Commit e8f5b955 authored by Sebastian Hörl's avatar Sebastian Hörl
Browse files

Initial commit

parents
.classpath
.settings
.project
dependency-reduced-pom.xml
target
latex/bare_jrnl.aux
latex/bare_jrnl.blg
latex/bare_jrnl.synctex.gz
latex/bare_jrnl.pdf
latex/bare_jrnl.log
latex/bare_jrnl.bbl
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.ethz.matsim.projects</groupId>
<artifactId>astra_2018_002</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>osgeo</id>
<name>Geotools repository</name>
<url>http://download.osgeo.org/webdav/geotools</url>
</repository>
<repository>
<id>matsim</id>
<url>http://dl.bintray.com/matsim/matsim</url>
</repository>
<repository>
<id>matsim-eth</id>
<url>http://dl.bintray.com/matsim-eth/matsim</url>
</repository>
<repository>
<id>bintray-schweizerischebundesbahnen-simba.mvn</id>
<name>bintray</name>
<url>https://schweizerischebundesbahnen.bintray.com/simba.mvn</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>ch.ethz.matsim</groupId>
<artifactId>ch_pt_utils</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>ch.ethz.matsim</groupId>
<artifactId>baseline_scenario</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>ch.ethz.matsim</groupId>
<artifactId>mode_choice</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>org.matsim</groupId>
<artifactId>matsim</artifactId>
<version>0.10.1</version>
</dependency>
<dependency>
<groupId>ch.sbb</groupId>
<artifactId>matsim-sbb-extensions</artifactId>
<version>0.10.2</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package ch.ethz.matsim.projects.astra_2018_002;
import java.io.File;
import org.matsim.api.core.v01.Scenario;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings;
import org.matsim.core.controler.Controler;
import org.matsim.core.scenario.ScenarioUtils;
import ch.ethz.matsim.baseline_scenario.config.CommandLine;
import ch.ethz.matsim.baseline_scenario.config.CommandLine.ConfigurationException;
import ch.ethz.matsim.baseline_scenario.transit.BaselineTransitModule;
import ch.ethz.matsim.baseline_scenario.transit.routing.DefaultEnrichedTransitRoute;
import ch.ethz.matsim.baseline_scenario.transit.routing.DefaultEnrichedTransitRouteFactory;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.ModeChoiceModule;
import ch.sbb.matsim.routing.pt.raptor.SwissRailRaptorModule;
public class RunASTRA2018002 {
static public void main(String[] args) throws ConfigurationException {
CommandLine cmd = new CommandLine.Builder(args) //
.requireOptions("config-path", "pt-pricing-path") //
.build();
// Load config
Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"));
config.controler().setLastIteration(10);
config.strategy().clearStrategySettings();
StrategySettings strategy = new StrategySettings();
strategy.setStrategyName("custom");
strategy.setWeight(0.2);
config.strategy().addStrategySettings(strategy);
strategy = new StrategySettings();
strategy.setStrategyName("SubtourModeChoice");
strategy.setWeight(0.0);
strategy.setDisableAfter(1);
config.strategy().addStrategySettings(strategy);
strategy = new StrategySettings();
strategy.setStrategyName("KeepLastSelected");
strategy.setWeight(0.8);
config.strategy().addStrategySettings(strategy);
// Load scenario
Scenario scenario = ScenarioUtils.createScenario(config);
scenario.getPopulation().getFactory().getRouteFactories().setRouteFactory(DefaultEnrichedTransitRoute.class,
new DefaultEnrichedTransitRouteFactory());
ScenarioUtils.loadScenario(scenario);
// Set up controller
Controler controler = new Controler(scenario);
controler.addOverridingModule(new SwissRailRaptorModule());
controler.addOverridingModule(new BaselineTransitModule());
File ptPricingPath = new File(cmd.getOptionStrict("pt-pricing-path"));
controler.addOverridingModule(new ModeChoiceModule(ptPricingPath));
// Run
controler.run();
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.matsim.api.core.v01.network.Network;
import org.matsim.core.config.groups.PlansCalcRouteConfigGroup;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.router.TripRouter;
import org.matsim.core.router.util.TravelTime;
import org.matsim.facilities.ActivityFacilities;
import org.matsim.pt.transitSchedule.api.TransitSchedule;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.operation.TransformException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import ch.ethz.matsim.baseline_scenario.config.CommandLine.ConfigurationException;
import ch.ethz.matsim.ch_pt_utils.costs.CostCalculator;
import ch.ethz.matsim.ch_pt_utils.costs.t603.SpatialT603;
import ch.ethz.matsim.ch_pt_utils.costs.t603.T603;
import ch.ethz.matsim.ch_pt_utils.costs.zonal.ZonalSystem;
import ch.ethz.matsim.mode_choice.constraints.CompositeTourConstraintFactory;
import ch.ethz.matsim.mode_choice.constraints.TourConstraintFromTripConstraint;
import ch.ethz.matsim.mode_choice.estimation.ModeAwareTripEstimator;
import ch.ethz.matsim.mode_choice.estimation.TourEstimatorFromTripEstimator;
import ch.ethz.matsim.mode_choice.estimation.TripEstimatorCache;
import ch.ethz.matsim.mode_choice.framework.ModeAvailability;
import ch.ethz.matsim.mode_choice.framework.ModeChoiceModel;
import ch.ethz.matsim.mode_choice.framework.ModeChoiceModel.FallbackBehaviour;
import ch.ethz.matsim.mode_choice.framework.tour_based.ActivityTourFinder;
import ch.ethz.matsim.mode_choice.framework.tour_based.TourBasedModel;
import ch.ethz.matsim.mode_choice.framework.tour_based.TourFinder;
import ch.ethz.matsim.mode_choice.framework.tour_based.constraints.TourConstraintFactory;
import ch.ethz.matsim.mode_choice.framework.tour_based.estimation.TourCandidate;
import ch.ethz.matsim.mode_choice.framework.tour_based.estimation.TourEstimator;
import ch.ethz.matsim.mode_choice.framework.trip_based.constraints.TripConstraintFactory;
import ch.ethz.matsim.mode_choice.framework.utilities.MultinomialSelector;
import ch.ethz.matsim.mode_choice.framework.utilities.UtilitySelectorFactory;
import ch.ethz.matsim.mode_choice.framework.utils.DefaultModeChainGenerator;
import ch.ethz.matsim.mode_choice.framework.utils.ModeChainGeneratorFactory;
import ch.ethz.matsim.mode_choice.mode_availability.LicenseAndOwnershipModeAvailability;
import ch.ethz.matsim.mode_choice.prediction.TeleportationPredictor;
import ch.ethz.matsim.mode_choice.replanning.ModeChoiceModelStrategy;
import ch.ethz.matsim.mode_choice.replanning.NonSelectedPlanSelector;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.constraints.AvoidOnlyWalkConstraint;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.constraints.VehicleTourConstraint;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.ModeChoiceParameters;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.car.CarEstimator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.car.CarPredictor;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.other.BikeEstimator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.other.WalkEstimator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.pt.PublicTransportEstimator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.pt.PublicTransportPredictor;
public class ModeChoiceModule extends AbstractModule {
private static final List<String> MODES = Arrays.asList("car", "pt", "bike", "walk");
private static final List<String> VEHICLE_MODES = Arrays.asList("car", "bike");
private static final List<String> CACHED_MODES = Arrays.asList("car", "pt", "bike", "walk");
private final File ptPricingPath;
public ModeChoiceModule(File ptPricingPath) {
this.ptPricingPath = ptPricingPath;
}
@Override
public void install() {
addPlanStrategyBinding("custom").toProvider(ModeChoiceModelStrategy.class);
bindPlanSelectorForRemoval().to(NonSelectedPlanSelector.class);
bind(ModeChoiceParameters.class).asEagerSingleton();
}
@Provides
public ModeChoiceModel provideModeChoiceModel(PlansCalcRouteConfigGroup routeConfig,
ModeChoiceParameters parameters, TripRouter router, ActivityFacilities facilities, Network network,
@Named("car") TravelTime carTravelTime, CostCalculator costCalculator, TransitSchedule schedule)
throws ConfigurationException {
// SET UP ESTIMATORS
// Walk estimator
double crowflyDistanceFactorWalk = routeConfig.getModeRoutingParams().get("walk").getBeelineDistanceFactor();
double speedWalk = routeConfig.getModeRoutingParams().get("walk").getTeleportedModeSpeed();
TeleportationPredictor teleportationPredictorWalk = new TeleportationPredictor(crowflyDistanceFactorWalk,
speedWalk);
WalkEstimator walkEstimator = new WalkEstimator(parameters, teleportationPredictorWalk);
// Bike estimator
double crowflyDistanceFactorBike = routeConfig.getModeRoutingParams().get("bike").getBeelineDistanceFactor();
double speedBike = routeConfig.getModeRoutingParams().get("bike").getTeleportedModeSpeed();
TeleportationPredictor teleportationPredictorBike = new TeleportationPredictor(crowflyDistanceFactorBike,
speedBike);
BikeEstimator bikeEstimator = new BikeEstimator(parameters, teleportationPredictorBike);
// Public transport estimator
PublicTransportPredictor publicTransportPredictor = new PublicTransportPredictor(router, facilities, network,
costCalculator, schedule);
PublicTransportEstimator publicTransportEstimator = new PublicTransportEstimator(parameters,
publicTransportPredictor);
// Car estimator
CarPredictor carPredictor = new CarPredictor(router, facilities, carTravelTime, network);
CarEstimator carEstimator = new CarEstimator(parameters, carPredictor);
// Create composite estimator
ModeAwareTripEstimator modeAwareEstimator = new ModeAwareTripEstimator();
modeAwareEstimator.addEstimator("walk", walkEstimator);
modeAwareEstimator.addEstimator("bike", bikeEstimator);
modeAwareEstimator.addEstimator("pt", publicTransportEstimator);
modeAwareEstimator.addEstimator("car", carEstimator);
TripEstimatorCache estimator = new TripEstimatorCache(modeAwareEstimator, CACHED_MODES);
// Set up tour estimator
TourEstimator tourEstimator = new TourEstimatorFromTripEstimator(estimator);
// SET UP CONSTRAINTS
// Trip constraints
TripConstraintFactory avoidOnlyWalkConstraintFactory = new AvoidOnlyWalkConstraint.Factory();
// Tour constraints
TourConstraintFactory vehicleContinuityConstraintFactory = new VehicleTourConstraint.Factory(VEHICLE_MODES);
// Combine constraints
CompositeTourConstraintFactory constraintFactory = new CompositeTourConstraintFactory();
constraintFactory.addFactory(new TourConstraintFromTripConstraint.Factory(avoidOnlyWalkConstraintFactory));
constraintFactory.addFactory(vehicleContinuityConstraintFactory);
// SET UP MODEL
ModeAvailability modeAvailability = new LicenseAndOwnershipModeAvailability(MODES);
ModeChainGeneratorFactory modeChainGeneratorFactory = new DefaultModeChainGenerator.Factory();
TourFinder tourFinder = new ActivityTourFinder("home");
UtilitySelectorFactory<TourCandidate> tourSelectorFactory = new MultinomialSelector.Factory<>(700.0);
ModeChoiceModel model = new TourBasedModel(tourEstimator, modeAvailability, constraintFactory, tourFinder,
tourSelectorFactory, modeChainGeneratorFactory, FallbackBehaviour.EXCEPTION);
return model;
}
@Singleton
@Provides
public CostCalculator provideCostCalculator() throws JsonParseException, JsonMappingException, IOException,
MismatchedDimensionException, NoSuchAuthorityCodeException, FactoryException, TransformException {
File t603File = new File(ptPricingPath, "t603.json");
File hafasPath = new File(ptPricingPath, "hafas");
File zonesPath = new File(ptPricingPath, "zones/Tarifzonen NPVM LV95_area.SHP");
T603 t603 = T603.read(t603File);
SpatialT603 spatialT603 = SpatialT603.read(hafasPath, t603);
ZonalSystem zonalPricing = ZonalSystem.read(zonesPath);
return new CostCalculator(t603, spatialT603, zonalPricing);
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.constraints;
import java.util.Collection;
import java.util.List;
import ch.ethz.matsim.mode_choice.constraints.AbstractTripConstraint;
import ch.ethz.matsim.mode_choice.estimation.TripCandidateWithPrediction;
import ch.ethz.matsim.mode_choice.framework.ModeChoiceTrip;
import ch.ethz.matsim.mode_choice.framework.trip_based.constraints.TripConstraint;
import ch.ethz.matsim.mode_choice.framework.trip_based.constraints.TripConstraintFactory;
import ch.ethz.matsim.mode_choice.framework.trip_based.estimation.TripCandidate;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.pt.PublicTransportPrediction;
public class AvoidOnlyWalkConstraint extends AbstractTripConstraint {
@Override
public boolean validateAfterEstimation(ModeChoiceTrip trip, TripCandidate candidate,
List<TripCandidate> previousCandidates) {
if (candidate.getMode().equals("pt")) {
PublicTransportPrediction prediction = (PublicTransportPrediction) ((TripCandidateWithPrediction) candidate)
.getPrediction();
return !prediction.isOnlyWalk;
}
return true;
}
static public class Factory implements TripConstraintFactory {
@Override
public TripConstraint createConstraint(List<ModeChoiceTrip> trips, Collection<String> availableModes) {
return new AvoidOnlyWalkConstraint();
}
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.constraints;
import java.util.Collection;
import java.util.List;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.core.router.TripStructureUtils.Trip;
import ch.ethz.matsim.mode_choice.framework.ModeChoiceTrip;
import ch.ethz.matsim.mode_choice.framework.tour_based.constraints.TourConstraint;
import ch.ethz.matsim.mode_choice.framework.tour_based.constraints.TourConstraintFactory;
import ch.ethz.matsim.mode_choice.framework.tour_based.estimation.TourCandidate;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.utils.VehicleLocationUtils;
public class VehicleTourConstraint implements TourConstraint {
final private Collection<String> constrainedModes;
final private List<ModeChoiceTrip> trips;
final private Id<Link> homeLinkId;
public VehicleTourConstraint(Id<Link> homeLinkId, Collection<String> constrainedModes, List<ModeChoiceTrip> trips) {
this.homeLinkId = homeLinkId;
this.trips = trips;
this.constrainedModes = constrainedModes;
}
@Override
public boolean validateBeforeEstimation(List<String> modes, List<List<String>> previousModes) {
for (String testMode : constrainedModes) {
int firstModeIndex = modes.indexOf(testMode);
int lastModeIndex = modes.lastIndexOf(testMode);
if (firstModeIndex > -1) { // The test mode is used at least once
Trip firstTripInformation = trips.get(firstModeIndex).getTripInformation();
Trip lastTripInformation = trips.get(lastModeIndex).getTripInformation();
Id<Link> firstDepartureLinkId = VehicleLocationUtils.getOriginLinkId(firstTripInformation);
Id<Link> lastArrivalLinkId = VehicleLocationUtils.getDestinationLinkId(lastTripInformation);
if (!firstDepartureLinkId.equals(homeLinkId)) {
// The first trip with this mode does not start at home
return false;
}
if (!lastArrivalLinkId.equals(homeLinkId)) {
// The last trip with this mode does not end at home
return false;
}
Id<Link> currentLinkId = VehicleLocationUtils.getDestinationLinkId(firstTripInformation);
for (int i = firstModeIndex + 1; i <= lastModeIndex; i++) {
if (modes.get(i).equals(testMode)) {
Trip tripInformation = trips.get(i).getTripInformation();
if (!currentLinkId.equals(VehicleLocationUtils.getOriginLinkId(tripInformation))) {
// Departure at one link, but car is at another link
return false;
}
currentLinkId = VehicleLocationUtils.getDestinationLinkId(tripInformation);
}
}
}
}
return true;
}
@Override
public boolean validateAfterEstimation(TourCandidate candidate, List<TourCandidate> previousCandidates) {
return true;
}
public static class Factory implements TourConstraintFactory {
final private Collection<String> constrainedModes;
public Factory(Collection<String> constrainedModes) {
this.constrainedModes = constrainedModes;
}
@Override
public TourConstraint createConstraint(List<ModeChoiceTrip> trips, Collection<String> availableModes) {
Id<Link> homeLinkId = VehicleLocationUtils.getHomeLinkId(trips);
return new VehicleTourConstraint(homeLinkId, constrainedModes, trips);
}
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation;
public class ModeChoiceParameters {
// Constants
public double shortDistance = 200.0;
public double shortDistancePenalty = -100.0;
// Cost
public double betaCostBase = -0.126;
public double averageDistance_km = 40.0;
public double lambdaDistanceCost = -0.4;
public double betaCost(double distance_km) {
distance_km = Math.max(distance_km, 0.001);
return betaCostBase * Math.pow(distance_km / averageDistance_km, lambdaDistanceCost);
}
// Walk
public double alphaWalk = 0.63;
public double betaTravelTimeWalk_min = -0.141;
// Bike
public double alphaBike = -0.1;
public double betaTravelTimeBike_min = -0.0805;
public double betaAgeBike_yr = -0.0496;
// Car
public double alphaCar = 0.827;
public double betaTravelTimeCar_min = -0.0667;
public double distanceCostCar_km = 0.27;
public double parkingSearchTimeCar_min = 6.0;
public double accessEgressWalkTimeCar_min = 5.0;
// Public Transport
public double alphaPublicTransport = 0.0;
public double betaNumberOfTransfersPublicTransport = -0.17;
public double betaInVehicleTimePublicTransport_min = -0.0192;
public double betaTransferTimePublicTransport_min = -0.0384;
public double betaAccessEgressTimePublicTransport_min = -0.0804;
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.car;
import java.util.List;
import org.matsim.api.core.v01.TransportMode;
import ch.ethz.matsim.mode_choice.estimation.ModalTripEstimator;
import ch.ethz.matsim.mode_choice.estimation.TripCandidateWithPrediction;
import ch.ethz.matsim.mode_choice.framework.ModeChoiceTrip;
import ch.ethz.matsim.mode_choice.framework.trip_based.estimation.TripCandidate;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.ModeChoiceParameters;
public class CarEstimator implements ModalTripEstimator {
final private CarPredictor predictor;
final private ModeChoiceParameters parameters;
public CarEstimator(ModeChoiceParameters parameters, CarPredictor predictor) {
this.predictor = predictor;
this.parameters = parameters;
}
@Override
public TripCandidate estimateTrip(ModeChoiceTrip trip, List<TripCandidate> preceedingTrips) {
CarPrediction prediction = predictor.predict(trip);
double travelTime_min = prediction.travelTime / 60.0;
double distance_km = prediction.distance * 1e-3;
double cost = parameters.distanceCostCar_km * distance_km;
double betaCost = parameters.betaCost(distance_km);
double utility = 0.0;
utility += parameters.alphaCar;
utility += parameters.betaTravelTimeCar_min * travelTime_min;
utility += parameters.betaTravelTimeCar_min * parameters.parkingSearchTimeCar_min;
utility += parameters.betaTravelTimeWalk_min * parameters.accessEgressWalkTimeCar_min;
utility += betaCost * cost;
if (prediction.crowflyDistance < parameters.shortDistance) {
utility += parameters.shortDistancePenalty;
}
return new TripCandidateWithPrediction(utility, TransportMode.car, prediction);
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.car;
public class CarPrediction {
final public double distance;
final public double travelTime;
final public double crowflyDistance;
public CarPrediction(double distance, double travelTime, double crowflyDistance) {
this.distance = distance;
this.travelTime = travelTime;
this.crowflyDistance = crowflyDistance;
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.car;