Skip to content

Commit

Permalink
"migrant"-Subpopulation bicycle usage (currently not working)
Browse files Browse the repository at this point in the history
  • Loading branch information
Aleksander1234519 committed Jun 26, 2024
1 parent c008d79 commit d6f5957
Show file tree
Hide file tree
Showing 4 changed files with 302 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public HomeMultipleLocationFilter(ShpOptions analysisAreaShapeFile, String input
* @param p Person to check
* @param key Will search in all polygons, that have this {@code key} value in the {@code columnToMap} attribute.
*/
public boolean checkIfPersonInPolygon(Person p, String key){ // TODO Replace by efficient solution
public boolean checkIfPersonInPolygon(Person p, String key){
return personMapping.get(key).contains(p.getId());
}

Expand Down
77 changes: 77 additions & 0 deletions src/main/java/org/matsim/prepare/MigrantBicycleChoiceHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.matsim.prepare;

import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.events.PersonDepartureEvent;
import org.matsim.api.core.v01.events.PersonMoneyEvent;
import org.matsim.api.core.v01.events.PersonScoreEvent;
import org.matsim.api.core.v01.events.handler.PersonDepartureEventHandler;
import org.matsim.api.core.v01.population.Population;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.controler.events.AfterMobsimEvent;
import org.matsim.core.controler.events.ReplanningEvent;
import org.matsim.core.controler.listener.AfterMobsimListener;
import org.matsim.core.controler.listener.ReplanningListener;
import org.matsim.core.events.EventsUtils;
import org.matsim.core.gbl.MatsimRandom;
import org.matsim.core.population.PopulationUtils;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

public class MigrantBicycleChoiceHandler implements PersonDepartureEventHandler, AfterMobsimListener {
private List<PersonScoreEvent> migrantDepartures;
private Population population;

public MigrantBicycleChoiceHandler(Population population) {
migrantDepartures = new LinkedList<>();
this.population = population;
}

public MigrantBicycleChoiceHandler(String populationPath) {
migrantDepartures = new LinkedList<>();
this.population = PopulationUtils.readPopulation(populationPath);
}

@Override
public void handleEvent(PersonDepartureEvent personDepartureEvent) {
// Do not do anything, if this Person is not a migrant
if( !population.getPersons().get(personDepartureEvent.getPersonId()).getAttributes().getAsMap().containsKey("subpopulation")
|| !population.getPersons().get(personDepartureEvent.getPersonId()).getAttributes().getAttribute("subpopulation").equals("migrant") ){
return;
}

// Add to departures of migrants
Random rand = MatsimRandom.getRandom();
if(personDepartureEvent.getLegMode().equals("bicycle") && rand.nextInt(1000) < 1000) new PersonMoneyEvent(personDepartureEvent.getTime(), personDepartureEvent.getPersonId(), 1000); //TODO what is kind?; set rand-value to 400
// TODO TransportMode.bike
}


@Override
public void notifyAfterMobsim(AfterMobsimEvent afterMobsimEvent) {
for(PersonScoreEvent e : migrantDepartures){
// TODO Check if this will actually influence the choice
// TODO Check what would be a useful value
// TODO Gibt es keine direktere Möglichkeit? Kann ich das Event nicht einfach irgendwie überschreiben?
afterMobsimEvent.getServices().getEvents().processEvent(e);
}
migrantDepartures.clear();
}

public static void main(String[] args) {
//MigrantBicycleChoiceHandler choiceHandler = new MigrantBicycleChoiceHandler();

}

// @Override
// public void notifyReplanning(ReplanningEvent replanningEvent) {
// /*for(PersonScoreEvent e : migrantDepartures){
// // TODO Check if this will actually influence the choice
// // TODO Check what would be a useful value
// // TODO Gibt es keine direktere Möglichkeit? Kann ich das Event nicht einfach irgendwie überschreiben?
// replanningEvent.getServices().getEvents().processEvent(e);
// }*/
// }
}
5 changes: 4 additions & 1 deletion src/main/java/org/matsim/prepare/MigrantMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ private void assignMigrantMapToPopulation(){
for(var e : migrantProbabilityMap.entrySet()){
double r = e.getValue();
boolean isMigrant = rand.nextInt(1000) < r*1000;
pop.getPersons().get(e.getKey()).getAttributes().putAttribute("isMigrant", isMigrant);
//pop.getPersons().get(e.getKey()).getAttributes().putAttribute("isMigrant", isMigrant);
pop.getPersons().get(e.getKey()).getAttributes().putAttribute("subpopulation", "migrant");
if (isMigrant) totalMigrants++;
//TODO DEBUG
if (isMigrant){
Expand Down Expand Up @@ -246,6 +247,8 @@ public static void main(String[] args) {
"Name",
"EPSG:25832"
);
PopulationUtils.writePopulation(detecter.getPopulation(), "output/gladbeck-v1.3-10pct.migrants-mapped.xml.gz");

System.out.println(detecter.getMigrantAmount());
System.out.println(detecter.district_amounts);
System.out.println(detecter.district_migrant_amounts);
Expand Down
220 changes: 220 additions & 0 deletions src/test/java/org/matsim/prepare/MigrantBicycleChoiceHandlerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package org.matsim.prepare;

import ch.sbb.matsim.routing.pt.raptor.RaptorIntermodalAccessEgress;
import ch.sbb.matsim.routing.pt.raptor.SwissRailRaptorModule;
import com.google.inject.Singleton;
import com.google.inject.multibindings.Multibinder;
import org.junit.Test;
import org.matsim.analysis.ModeChoiceCoverageControlerListener;
import org.matsim.analysis.linkpaxvolumes.LinkPaxVolumesAnalysisModule;
import org.matsim.analysis.personMoney.PersonMoneyEventsAnalysisModule;
import org.matsim.analysis.pt.stop2stop.PtStop2StopAnalysisModule;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.population.Person;
import org.matsim.api.core.v01.population.Population;
import org.matsim.api.core.v01.population.PopulationFactory;
import org.matsim.contrib.bicycle.BicycleConfigGroup;
import org.matsim.contrib.bicycle.Bicycles;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.config.groups.StrategyConfigGroup;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.controler.Controler;
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.events.EventsUtils;
import org.matsim.core.population.PopulationUtils;
import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule;
import org.matsim.core.router.AnalysisMainModeIdentifier;
import org.matsim.core.router.MultimodalLinkChooser;
import org.matsim.core.scenario.ScenarioUtils;
import org.matsim.core.scoring.functions.ScoringParametersForPerson;
import org.matsim.examples.ExamplesUtils;
import org.matsim.extensions.pt.fare.intermodalTripFareCompensator.IntermodalTripFareCompensatorsModule;
import org.matsim.extensions.pt.routing.EnhancedRaptorIntermodalAccessEgress;
import org.matsim.extensions.pt.routing.ptRoutingModes.PtIntermodalRoutingModesModule;
import org.matsim.run.IntermodalPtAnalysisModeIdentifier;
import org.matsim.run.NearestLinkChooser;
import org.matsim.run.StrategyWeightFadeout;
import playground.vsp.scoring.IncomeDependentUtilityOfMoneyPersonScoringParameters;
import playground.vsp.simpleParkingCostHandler.ParkingCostConfigGroup;
import playground.vsp.simpleParkingCostHandler.ParkingCostModule;

public class MigrantBicycleChoiceHandlerTest {

String migrantPopulationPath = "gladbeck-v1.3-10pct.migrants-mapped.xml.gz"; // TODO Adjust path

private void prepareConfig(Config config){}

private void prepareScenario(Scenario scenario){}

private void prepareControler(Controler controler){}

@Test
public void testSubpopulationBiking() {
//TODO ... config.planCalcScore()

//Setup simulation test-run
// ==CONFIG==
Config config = ConfigUtils.loadConfig("scenarios/gladbeck-v1.0/input/gladbeck-v1.0-10pct.config.xml");

config.controler().setLastIteration(0);
config.controler().setOutputDirectory("output/MigrantBicycleTest");
config.global().setNumberOfThreads(1);
config.qsim().setNumberOfThreads(1);
config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists);
config.plans().setInputFile(migrantPopulationPath);
//additional contribs
//bike
BicycleConfigGroup bikeConfigGroup = (BicycleConfigGroup)ConfigUtils.addOrGetModule(config, BicycleConfigGroup.class);
bikeConfigGroup.setBicycleMode("bike");
//parking costs
ParkingCostConfigGroup parkingCostConfigGroup = (ParkingCostConfigGroup)ConfigUtils.addOrGetModule(config, ParkingCostConfigGroup.class);
parkingCostConfigGroup.setFirstHourParkingCostLinkAttributeName("oneHourPCost");
parkingCostConfigGroup.setExtraHourParkingCostLinkAttributeName("extraHourPCost");
parkingCostConfigGroup.setMaxDailyParkingCostLinkAttributeName("maxDailyPCost");
parkingCostConfigGroup.setMaxParkingDurationAttributeName("maxPTime");
parkingCostConfigGroup.setParkingPenaltyAttributeName("pFine");
parkingCostConfigGroup.setResidentialParkingFeeAttributeName("resPCosts");

// ==SCENARIO==
Scenario scenario = ScenarioUtils.loadScenario(config);

//Extract one test-person
Person migrant = null;
for(Person p : scenario.getPopulation().getPersons().values()){
if(p.getAttributes().getAttribute("subpopulation").equals("migrant")){
migrant = p;
break;
}
}
assert migrant != null;

scenario.getPopulation().getPersons().clear();
scenario.getPopulation().addPerson(migrant);

//==CONTROL(L)ER==
Controler controler = new Controler(scenario);

controler.addOverridingModule(new AbstractModule() {
@Override
public void install() {
bind(MultimodalLinkChooser.class).to(NearestLinkChooser.class);
}
});
controler.addOverridingModule(new SwissRailRaptorModule());
controler.addOverridingModule(new AbstractModule() {
public void install() {
this.bind(RaptorIntermodalAccessEgress.class).to(EnhancedRaptorIntermodalAccessEgress.class);
this.bind(AnalysisMainModeIdentifier.class).to(IntermodalPtAnalysisModeIdentifier.class);
}
});
controler.addOverridingModule(new PtIntermodalRoutingModesModule());
controler.addOverridingModule(new IntermodalTripFareCompensatorsModule());
controler.addOverridingModule(new LinkPaxVolumesAnalysisModule());
controler.addOverridingModule(new PtStop2StopAnalysisModule());
controler.addOverridingModule(new AbstractModule() {
public void install() {
this.bind(ScoringParametersForPerson.class).to(IncomeDependentUtilityOfMoneyPersonScoringParameters.class).in(Singleton.class);
}
});
controler.addOverridingModule(new AbstractModule() {
public void install() {
this.addTravelTimeBinding("ride").to(this.networkTravelTime());
this.addTravelDisutilityFactoryBinding("ride").to(this.carTravelDisutilityFactoryKey());
this.addTravelTimeBinding("bike").to(this.networkTravelTime());
this.addControlerListenerBinding().to(ModeChoiceCoverageControlerListener.class);
this.addControlerListenerBinding().to(StrategyWeightFadeout.class).in(Singleton.class);
Multibinder<StrategyWeightFadeout.Schedule> schedules = Multibinder.newSetBinder(this.binder(), StrategyWeightFadeout.Schedule.class);
schedules.addBinding().toInstance(new StrategyWeightFadeout.Schedule("SubtourModeChoice", "person", 0.75, 0.85));
schedules.addBinding().toInstance(new StrategyWeightFadeout.Schedule("ReRoute", "person", 0.78));
}
});
controler.addOverridingModule(new AbstractModule() {
public void install() {
this.install(new PersonMoneyEventsAnalysisModule());
}
});
controler.addOverridingModule(new ParkingCostModule());
Bicycles.addAsOverridingModule(controler);

//Setup Choice Handler
MigrantBicycleChoiceHandler choiceHandler = new MigrantBicycleChoiceHandler(scenario.getPopulation()); //TODO Make path universal
controler.addOverridingModule(new AbstractModule() {
@Override
public void install() {
addEventHandlerBinding().toInstance(choiceHandler);
}
});

//DEBUG{
System.out.println();
//config.getModules().values();
//}END

controler.run();
}

@Test
public void test2(){
String inputPath = String.valueOf(ExamplesUtils.getTestScenarioURL("equil-mixedTraffic"));
Config config = ConfigUtils.loadConfig(inputPath + "config-with-mode-vehicles.xml");
{
config.controler().setLastIteration(3);
config.controler().setOutputDirectory("output/MigrantBicycleTest/");
config.global().setNumberOfThreads(1);
config.qsim().setNumberOfThreads(1);
config.controler().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists);
//bike contrib
BicycleConfigGroup bikeConfigGroup = (BicycleConfigGroup)ConfigUtils.addOrGetModule(config, BicycleConfigGroup.class);
bikeConfigGroup.setBicycleMode("bike");
config.changeMode().setModes(new String[]{"car", "pt", "bicycle"});

//Set the replanning strategy for migrants: All migrants will fully reroute their plan
StrategyConfigGroup.StrategySettings migrantStrategySettings = new StrategyConfigGroup.StrategySettings(ConfigUtils.createAvailableStrategyId(config));
migrantStrategySettings.setStrategyName(DefaultPlanStrategiesModule.DefaultStrategy.ChangeTripMode);
migrantStrategySettings.setSubpopulation("migrant");
migrantStrategySettings.setWeight(1);
config.strategy().addStrategySettings(migrantStrategySettings);
}

Scenario scenario = ScenarioUtils.loadScenario(config);
//Person person = scenario.getPopulation().getPersons().get(Id.createPersonId("10"));
//scenario.getPopulation().getPersons().clear();
//scenario.getPopulation().addPerson(person);
Person migrant = scenario.getPopulation().getPersons().get(Id.createPersonId("1"));
migrant.getAttributes().putAttribute("subpopulation", "migrant");

Controler controler = new Controler(scenario);
{
controler.addOverridingModule(new AbstractModule() {
public void install() {
this.addTravelTimeBinding("ride").to(this.networkTravelTime());
this.addTravelDisutilityFactoryBinding("ride").to(this.carTravelDisutilityFactoryKey());
this.addTravelTimeBinding("bike").to(this.networkTravelTime());
this.addControlerListenerBinding().to(ModeChoiceCoverageControlerListener.class);
this.addControlerListenerBinding().to(StrategyWeightFadeout.class).in(Singleton.class);
Multibinder<StrategyWeightFadeout.Schedule> schedules = Multibinder.newSetBinder(this.binder(), StrategyWeightFadeout.Schedule.class);
schedules.addBinding().toInstance(new StrategyWeightFadeout.Schedule("SubtourModeChoice", "person", 0.75, 0.85));
schedules.addBinding().toInstance(new StrategyWeightFadeout.Schedule("ReRoute", "person", 0.78));
}
});
Bicycles.addAsOverridingModule(controler);
}

MigrantBicycleChoiceHandler choiceHandler = new MigrantBicycleChoiceHandler(scenario.getPopulation());

controler.addOverridingModule(new AbstractModule() {
@Override
public void install() {
addEventHandlerBinding().toInstance(choiceHandler);
addControlerListenerBinding().toInstance(choiceHandler);
}
});
controler.run();

//Migrant should now have bike as the best plan

System.out.println();
}
}

0 comments on commit d6f5957

Please sign in to comment.