-
Notifications
You must be signed in to change notification settings - Fork 452
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into dependabot/maven/org.apache.commons-common…
…s-compress-1.27.1
- Loading branch information
Showing
5 changed files
with
204 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
...rc/main/java/org/matsim/contribs/discrete_mode_choice/modules/UtilitiesWriterHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package org.matsim.contribs.discrete_mode_choice.modules; | ||
|
||
import com.google.inject.Inject; | ||
import org.matsim.api.core.v01.population.Population; | ||
import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup; | ||
import org.matsim.contribs.discrete_mode_choice.modules.utils.ExtractPlanUtilities; | ||
import org.matsim.core.config.groups.ControllerConfigGroup; | ||
import org.matsim.core.controler.OutputDirectoryHierarchy; | ||
import org.matsim.core.controler.events.IterationStartsEvent; | ||
import org.matsim.core.controler.events.ShutdownEvent; | ||
import org.matsim.core.controler.listener.IterationStartsListener; | ||
import org.matsim.core.controler.listener.ShutdownListener; | ||
|
||
import java.io.IOException; | ||
|
||
public class UtilitiesWriterHandler implements ShutdownListener, IterationStartsListener { | ||
private final OutputDirectoryHierarchy outputDirectoryHierarchy; | ||
private final ControllerConfigGroup controllerConfigGroup; | ||
private final Population population; | ||
private final DiscreteModeChoiceConfigGroup discreteModeChoiceConfigGroup; | ||
|
||
@Inject | ||
public UtilitiesWriterHandler(ControllerConfigGroup controllerConfigGroup, DiscreteModeChoiceConfigGroup discreteModeChoiceConfigGroup, Population population, OutputDirectoryHierarchy outputDirectoryHierarchy) { | ||
this.controllerConfigGroup = controllerConfigGroup; | ||
this.discreteModeChoiceConfigGroup = discreteModeChoiceConfigGroup; | ||
this.population = population; | ||
this.outputDirectoryHierarchy = outputDirectoryHierarchy; | ||
} | ||
|
||
@Override | ||
public void notifyShutdown(ShutdownEvent event) { | ||
String filePath = this.outputDirectoryHierarchy.getOutputFilename("dmc_utilities.csv"); | ||
try { | ||
ExtractPlanUtilities.writePlanUtilities(population, filePath); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public void notifyIterationStarts(IterationStartsEvent event) { | ||
if(event.getIteration() == controllerConfigGroup.getFirstIteration() || this.discreteModeChoiceConfigGroup.getWriteUtilitiesInterval() % event.getIteration() != 0) { | ||
return; | ||
} | ||
String filePath = this.outputDirectoryHierarchy.getIterationFilename(event.getIteration(), "dmc_utilities.csv"); | ||
try { | ||
ExtractPlanUtilities.writePlanUtilities(population, filePath); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
...ain/java/org/matsim/contribs/discrete_mode_choice/modules/utils/ExtractPlanUtilities.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package org.matsim.contribs.discrete_mode_choice.modules.utils; | ||
|
||
import org.matsim.api.core.v01.Scenario; | ||
import org.matsim.api.core.v01.population.Person; | ||
import org.matsim.api.core.v01.population.Plan; | ||
import org.matsim.api.core.v01.population.Population; | ||
import org.matsim.core.config.CommandLine; | ||
import org.matsim.core.config.Config; | ||
import org.matsim.core.config.ConfigUtils; | ||
import org.matsim.core.population.io.PopulationReader; | ||
import org.matsim.core.scenario.ScenarioUtils; | ||
|
||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
|
||
public class ExtractPlanUtilities { | ||
public static void writePlanUtilities(Population population, String filePath) throws IOException { | ||
FileWriter writer = new FileWriter(filePath); | ||
writer.write(String.join(CSV_SEPARATOR, CSV_HEADER)); | ||
writer.write("\n"); | ||
|
||
for(Person person: population.getPersons().values()) { | ||
double utility = Double.NaN; | ||
Plan plan = person.getSelectedPlan(); | ||
if(plan != null && plan.getAttributes().getAttribute("utility") != null) { | ||
utility = (double) plan.getAttributes().getAttribute("utility"); | ||
} | ||
writer.write(String.join(CSV_SEPARATOR, new String[]{ | ||
person.getId().toString(), | ||
String.valueOf(utility) | ||
})); | ||
writer.write("\n"); | ||
} | ||
writer.close(); | ||
} | ||
|
||
public static final String CMD_PLANS_PATH = "plans-path"; | ||
public static final String CMD_OUTPUT_PATH = "output-path"; | ||
public static final String CSV_SEPARATOR = ";"; | ||
public static final String[] CSV_HEADER = new String[]{"person_id", "utility"}; | ||
|
||
public static void main(String[] args) throws CommandLine.ConfigurationException, IOException { | ||
CommandLine commandLine = new CommandLine.Builder(args).requireOptions(CMD_PLANS_PATH, CMD_OUTPUT_PATH).build(); | ||
|
||
Config config = ConfigUtils.createConfig(); | ||
Scenario scenario = ScenarioUtils.createScenario(config); | ||
new PopulationReader(scenario).readFile(commandLine.getOptionStrict(CMD_PLANS_PATH)); | ||
|
||
writePlanUtilities(scenario.getPopulation(), commandLine.getOptionStrict(CMD_OUTPUT_PATH)); | ||
} | ||
} |
152 changes: 77 additions & 75 deletions
152
...java/org/matsim/contribs/discrete_mode_choice/replanning/DiscreteModeChoiceAlgorithm.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,75 +1,77 @@ | ||
package org.matsim.contribs.discrete_mode_choice.replanning; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Random; | ||
|
||
import org.matsim.api.core.v01.population.Leg; | ||
import org.matsim.api.core.v01.population.Plan; | ||
import org.matsim.api.core.v01.population.PlanElement; | ||
import org.matsim.api.core.v01.population.PopulationFactory; | ||
import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel; | ||
import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; | ||
import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel.NoFeasibleChoiceException; | ||
import org.matsim.contribs.discrete_mode_choice.model.trip_based.candidates.RoutedTripCandidate; | ||
import org.matsim.contribs.discrete_mode_choice.model.trip_based.candidates.TripCandidate; | ||
import org.matsim.core.population.algorithms.PlanAlgorithm; | ||
import org.matsim.core.router.TripRouter; | ||
|
||
/** | ||
* This replanning algorithm uses a predefined discrete mode choice model to | ||
* perform mode decisions for a given plan. | ||
* | ||
* @author sebhoerl | ||
*/ | ||
public class DiscreteModeChoiceAlgorithm implements PlanAlgorithm { | ||
private final Random random; | ||
private final DiscreteModeChoiceModel modeChoiceModel; | ||
private final TripListConverter tripListConverter; | ||
|
||
private final PopulationFactory populationFactory; | ||
|
||
public DiscreteModeChoiceAlgorithm(Random random, DiscreteModeChoiceModel modeChoiceModel, | ||
PopulationFactory populationFactory, TripListConverter tripListConverter) { | ||
this.random = random; | ||
this.modeChoiceModel = modeChoiceModel; | ||
this.populationFactory = populationFactory; | ||
this.tripListConverter = tripListConverter; | ||
} | ||
|
||
@Override | ||
/** | ||
* Performs mode choice on a plan. We assume that TripsToLegs has been called | ||
* before, hence the code is working diretly on legs. | ||
*/ | ||
public void run(Plan plan) { | ||
// I) First build a list of DiscreteModeChoiceTrips | ||
List<DiscreteModeChoiceTrip> trips = tripListConverter.convert(plan); | ||
|
||
// II) Run mode choice | ||
|
||
try { | ||
// Perform mode choice and retrieve candidates | ||
List<TripCandidate> chosenCandidates = modeChoiceModel.chooseModes(plan.getPerson(), trips, random); | ||
|
||
for (int i = 0; i < trips.size(); i++) { | ||
DiscreteModeChoiceTrip trip = trips.get(i); | ||
TripCandidate candidate = chosenCandidates.get(i); | ||
|
||
List<? extends PlanElement> insertElements; | ||
|
||
if (candidate instanceof RoutedTripCandidate) { | ||
RoutedTripCandidate routedCandidate = (RoutedTripCandidate) candidate; | ||
insertElements = routedCandidate.getRoutedPlanElements(); | ||
} else { | ||
Leg insertLeg = populationFactory.createLeg(candidate.getMode()); | ||
insertElements = Collections.singletonList(insertLeg); | ||
} | ||
|
||
TripRouter.insertTrip(plan, trip.getOriginActivity(), insertElements, trip.getDestinationActivity()); | ||
} | ||
} catch (NoFeasibleChoiceException e) { | ||
throw new IllegalStateException(e); | ||
} | ||
} | ||
} | ||
package org.matsim.contribs.discrete_mode_choice.replanning; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Random; | ||
|
||
import org.matsim.api.core.v01.population.Leg; | ||
import org.matsim.api.core.v01.population.Plan; | ||
import org.matsim.api.core.v01.population.PlanElement; | ||
import org.matsim.api.core.v01.population.PopulationFactory; | ||
import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel; | ||
import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; | ||
import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel.NoFeasibleChoiceException; | ||
import org.matsim.contribs.discrete_mode_choice.model.trip_based.candidates.RoutedTripCandidate; | ||
import org.matsim.contribs.discrete_mode_choice.model.trip_based.candidates.TripCandidate; | ||
import org.matsim.contribs.discrete_mode_choice.model.utilities.UtilityCandidate; | ||
import org.matsim.core.population.algorithms.PlanAlgorithm; | ||
import org.matsim.core.router.TripRouter; | ||
|
||
/** | ||
* This replanning algorithm uses a predefined discrete mode choice model to | ||
* perform mode decisions for a given plan. | ||
* | ||
* @author sebhoerl | ||
*/ | ||
public class DiscreteModeChoiceAlgorithm implements PlanAlgorithm { | ||
private final Random random; | ||
private final DiscreteModeChoiceModel modeChoiceModel; | ||
private final TripListConverter tripListConverter; | ||
|
||
private final PopulationFactory populationFactory; | ||
|
||
public DiscreteModeChoiceAlgorithm(Random random, DiscreteModeChoiceModel modeChoiceModel, | ||
PopulationFactory populationFactory, TripListConverter tripListConverter) { | ||
this.random = random; | ||
this.modeChoiceModel = modeChoiceModel; | ||
this.populationFactory = populationFactory; | ||
this.tripListConverter = tripListConverter; | ||
} | ||
|
||
@Override | ||
/** | ||
* Performs mode choice on a plan. We assume that TripsToLegs has been called | ||
* before, hence the code is working diretly on legs. | ||
*/ | ||
public void run(Plan plan) { | ||
// I) First build a list of DiscreteModeChoiceTrips | ||
List<DiscreteModeChoiceTrip> trips = tripListConverter.convert(plan); | ||
|
||
// II) Run mode choice | ||
|
||
try { | ||
// Perform mode choice and retrieve candidates | ||
List<TripCandidate> chosenCandidates = modeChoiceModel.chooseModes(plan.getPerson(), trips, random); | ||
|
||
for (int i = 0; i < trips.size(); i++) { | ||
DiscreteModeChoiceTrip trip = trips.get(i); | ||
TripCandidate candidate = chosenCandidates.get(i); | ||
|
||
List<? extends PlanElement> insertElements; | ||
|
||
if (candidate instanceof RoutedTripCandidate) { | ||
RoutedTripCandidate routedCandidate = (RoutedTripCandidate) candidate; | ||
insertElements = routedCandidate.getRoutedPlanElements(); | ||
} else { | ||
Leg insertLeg = populationFactory.createLeg(candidate.getMode()); | ||
insertElements = Collections.singletonList(insertLeg); | ||
} | ||
|
||
TripRouter.insertTrip(plan, trip.getOriginActivity(), insertElements, trip.getDestinationActivity()); | ||
} | ||
plan.getAttributes().putAttribute("utility", chosenCandidates.stream().mapToDouble(UtilityCandidate::getUtility).sum()); | ||
} catch (NoFeasibleChoiceException e) { | ||
throw new IllegalStateException(e); | ||
} | ||
} | ||
} |