To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

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

WIP: Simplify mode choice

parent 5ed894bc
......@@ -289,7 +289,7 @@ public abstract class BaseUtilityEstimator extends AbstractTripRouterEstimator {
tripVariables.destinationHomeDistance_km = CoordUtils.calcEuclideanDistance(personVariables.homeLocation,
trip.getDestinationActivity().getCoord()) * 1e-3;
tripVariables.travelCost_CHF = costModel.calculatePtTravelCost(personVariables, tripVariables);
tripVariables.travelCost_CHF = costModel.calculatePublicTransportTravelCost(personVariables, tripVariables);
return estimatePtTrip(trip, personVariables, tripVariables);
}
......
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.cost;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.base.PersonVariables;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.base.TripVariablesPt;
import java.util.EnumSet;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.person_variables.PersonVariables.Subscription;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.pricing.SharedAVTravelCost;
public class CostModel {
......@@ -25,26 +26,26 @@ public class CostModel {
return shared.getTravelCost(distance_km, isPooled);
}
public double calculatePtTravelCost(PersonVariables personVariables, TripVariablesPt tripVariables) {
public double calculatePublicTransportTravelCost(EnumSet<Subscription> subscriptions, double inVehicleDistance_km,
double originHomeDistance_km, double destinationHomeDistance_km) {
/*
* TODO: Later on, we should have a more complex cost model here.
*/
if (personVariables.hasGeneralSubscription) {
if (subscriptions.contains(Subscription.GA)) {
return 0.0;
}
if (personVariables.hasRegionalSubscription) {
if (tripVariables.originHomeDistance_km <= parameters.ptRegionalRadius_km
&& tripVariables.destinationHomeDistance_km <= parameters.ptRegionalRadius_km) {
if (subscriptions.contains(Subscription.VERBUND)) {
if (originHomeDistance_km <= parameters.ptRegionalRadius_km
&& destinationHomeDistance_km <= parameters.ptRegionalRadius_km) {
return 0.0;
}
}
double fullCost = Math.max(parameters.ptCostMinimum_CHF,
parameters.ptCostPerKm_CHF * tripVariables.inVehicleDistance_km);
double fullCost = Math.max(parameters.ptCostMinimum_CHF, parameters.ptCostPerKm_CHF * inVehicleDistance_km);
if (personVariables.hasHalbtaxSubscription) {
if (subscriptions.contains(Subscription.HALBTAX)) {
return fullCost * 0.5;
} else {
return fullCost;
......
......@@ -2,6 +2,7 @@ package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation;
import java.util.List;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.population.Person;
import org.matsim.api.core.v01.population.PlanElement;
import org.matsim.core.router.TripRouter;
......@@ -10,14 +11,65 @@ import org.matsim.facilities.ActivityFacilities;
import ch.ethz.matsim.discrete_mode_choice.components.estimators.AbstractTripRouterEstimator;
import ch.ethz.matsim.discrete_mode_choice.model.DiscreteModeChoiceTrip;
import ch.ethz.matsim.discrete_mode_choice.model.trip_based.candidates.TripCandidate;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.bike.BikeTripVariables;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.bike.BikeTripVariablesCalculator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.car.CarTripVariables;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.car.CarTripVariablesCalculator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.private_av.PrivateAvTripVariables;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.private_av.PrivateAvTripVariablesCalculator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.pt.PublicTransportTripVariables;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.pt.PublicTransportTripVariablesCalculator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.shared_av.SharedAvTripVariables;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.shared_av.SharedAvTripVariablesCalculator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.walk.WalkTripVariables;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.walk.WalkTripVariablesCalculator;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.SharedAVModule;
public class SwitzerlandEstimator extends AbstractTripRouterEstimator {
private CarTripVariablesCalculator carTripVariablesCalculator;
private PublicTransportTripVariablesCalculator publicTransportTripVariablesCalculator;
private WalkTripVariablesCalculator walkTripVariablesCalculator;
private BikeTripVariablesCalculator bikeTripVariablesCalculator;
private PrivateAvTripVariablesCalculator privateAvTripVariablesCalculator;
private SharedAvTripVariablesCalculator taxiAvTripVariablesCalculator;
private SharedAvTripVariablesCalculator pooledAvTripVariablesCalculator;
public SwitzerlandEstimator(TripRouter tripRouter, ActivityFacilities facilities) {
super(tripRouter, facilities);
}
protected double estimateTrip(Person person, String mode, DiscreteModeChoiceTrip trip,
List<TripCandidate> previousTrips, List<? extends PlanElement> routedTrip) {
return 0.0;
List<TripCandidate> previousTrips, List<? extends PlanElement> elements) {
double utility = 0.0;
switch (mode) {
case TransportMode.walk: {
WalkTripVariables tripVariables = walkTripVariablesCalculator.calculate(trip, elements);
}
case TransportMode.bike: {
BikeTripVariables tripVariables = bikeTripVariablesCalculator.calculate(trip, elements);
}
case TransportMode.pt: {
PublicTransportTripVariables tripVariables = publicTransportTripVariablesCalculator.calculate(trip,
elements);
}
case TransportMode.car: {
CarTripVariables tripVariables = carTripVariablesCalculator.calculate(trip, elements);
}
case "prav3":
case "prav4":
case "prav5": {
PrivateAvTripVariables tripVariables = privateAvTripVariablesCalculator.calculate(trip, elements);
}
case SharedAVModule.AV_TAXI: {
SharedAvTripVariables tripVariables = taxiAvTripVariablesCalculator.calculate(trip, elements);
}
case SharedAVModule.AV_POOL: {
SharedAvTripVariables tripVariables = pooledAvTripVariablesCalculator.calculate(trip, elements);
}
}
return utility;
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.person_variables;
import java.util.EnumSet;
import org.matsim.api.core.v01.Coord;
public class PersonVariables {
public final int age_a;
public final double income_CHF;
public final boolean isMale;
public final Coord homeLocation;
public enum CarAvailability {
NEVER, SOMETIMES, ALWAYS
}
public final CarAvailability carAvailability;
public enum MunicipalityType {
URBAN, SUBURBAN, RURAL, UNKNOWN
}
public final MunicipalityType municipalityType;
public enum SurveyRegion {
REGION_1, REGION_2, REGION_3, UNKNOWN
}
public final SurveyRegion surveyRegion;
public enum Subscription {
HALBTAX, GA, VERBUND
}
public final EnumSet<Subscription> subscriptions;
public PersonVariables(int age_a, double income_CHF, boolean isMale, Coord homeLocation,
CarAvailability carAvailability, MunicipalityType municipalityType, SurveyRegion surveyRegion,
EnumSet<Subscription> subscriptions) {
this.age_a = age_a;
this.income_CHF = income_CHF;
this.isMale = isMale;
this.homeLocation = homeLocation;
this.carAvailability = carAvailability;
this.municipalityType = municipalityType;
this.surveyRegion = surveyRegion;
this.subscriptions = subscriptions;
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.person_variables;
import java.util.EnumSet;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.population.Activity;
import org.matsim.api.core.v01.population.Person;
import org.matsim.api.core.v01.population.PlanElement;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.person_variables.PersonVariables.CarAvailability;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.person_variables.PersonVariables.MunicipalityType;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.person_variables.PersonVariables.Subscription;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.person_variables.PersonVariables.SurveyRegion;
public class PersonVariablesCalculator {
public PersonVariables calculatePersonVariables(Person person) {
int age_a = (Integer) person.getAttributes().getAttribute("age");
double income_CHF = (Double) person.getAttributes().getAttribute("householdIncome");
boolean isMale = ((String) person.getAttributes().getAttribute("sex")).equals("m");
CarAvailability carAvailability = CarAvailability.NEVER;
switch ((String) person.getAttributes().getAttribute("carAvail")) {
case "always":
carAvailability = CarAvailability.ALWAYS;
break;
case "sometimes":
carAvailability = CarAvailability.SOMETIMES;
break;
}
SurveyRegion surveyRegion = SurveyRegion.UNKNOWN;
switch ((Integer) person.getAttributes().getAttribute("spRegion")) {
case 1:
surveyRegion = SurveyRegion.REGION_1;
break;
case 2:
surveyRegion = SurveyRegion.REGION_2;
break;
case 3:
surveyRegion = SurveyRegion.REGION_3;
break;
}
MunicipalityType municipalityType = MunicipalityType.UNKNOWN;
switch ((String) person.getAttributes().getAttribute("municipalityType")) {
case "rural":
municipalityType = MunicipalityType.RURAL;
break;
case "suburban":
municipalityType = MunicipalityType.SUBURBAN;
break;
case "urban":
municipalityType = MunicipalityType.URBAN;
break;
default:
}
EnumSet<Subscription> subscriptions = EnumSet.noneOf(Subscription.class);
if ((Boolean) person.getAttributes().getAttribute("ptHasGA")) {
subscriptions.add(Subscription.GA);
}
if ((Boolean) person.getAttributes().getAttribute("ptHasHalbtax")) {
subscriptions.add(Subscription.HALBTAX);
}
if ((Boolean) person.getAttributes().getAttribute("ptHasVerbund")) {
subscriptions.add(Subscription.VERBUND);
}
Coord homeLocation = getHomeLocation(person);
return new PersonVariables(age_a, income_CHF, isMale, homeLocation, carAvailability, municipalityType,
surveyRegion, subscriptions);
}
private Coord getHomeLocation(Person person) {
Double homeX = (Double) person.getAttributes().getAttribute("home_x");
Double homeY = (Double) person.getAttributes().getAttribute("home_y");
if (homeX == null || homeY == null) {
homeX = 0.0;
homeY = 0.0;
for (PlanElement element : person.getSelectedPlan().getPlanElements()) {
if (element instanceof Activity) {
Activity activity = (Activity) element;
if (activity.getType().equals("home")) {
homeX = activity.getCoord().getX();
homeY = activity.getCoord().getY();
}
}
}
person.getAttributes().putAttribute("home_x", homeX);
person.getAttributes().putAttribute("home_y", homeY);
}
return new Coord(homeX, homeY);
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.variables;
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables;
import org.matsim.core.utils.misc.Time;
......
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.variables.bike;
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.bike;
public class BikeTripVariables {
public final double travelTime_min;
......
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.variables.bike;
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.bike;
import java.util.List;
......@@ -6,7 +6,7 @@ import org.matsim.api.core.v01.population.Leg;
import org.matsim.api.core.v01.population.PlanElement;
import ch.ethz.matsim.discrete_mode_choice.model.DiscreteModeChoiceTrip;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.variables.TripVariablesUtils;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.TripVariablesUtils;
public class BikeTripVariablesCalculator {
public BikeTripVariables calculate(DiscreteModeChoiceTrip trip, List<? extends PlanElement> elements) {
......
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.variables.car;
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.car;
public class CarTripVariables {
public final double travelDistance_km;
......
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.variables.car;
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.car;
import java.util.List;
......@@ -6,30 +6,34 @@ import org.matsim.api.core.v01.population.Leg;
import org.matsim.api.core.v01.population.PlanElement;
import ch.ethz.matsim.discrete_mode_choice.model.DiscreteModeChoiceTrip;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.parameters.CarParameters;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.variables.TripVariablesUtils;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.cost.CostModel;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.TripVariablesUtils;
public class CarTripVariablesCalculator {
private final CarParameters carParameters;
public CarTripVariablesCalculator(CarParameters carParameters) {
this.carParameters = carParameters;
private final CostModel costModel;
public CarTripVariablesCalculator(CostModel costModel) {
this.costModel = costModel;
}
public CarTripVariables calculate(DiscreteModeChoiceTrip trip, List<? extends PlanElement> elements) {
if (elements.size() > 1) {
throw new IllegalStateException();
}
Leg leg = (Leg) elements.get(0);
double travelDistance_km = leg.getRoute().getDistance() * 1e-3;
double travelTime_min = leg.getTravelTime() / 60.0;
double parkingSearchTime_min = carParameters.parkingSearchPenalty_min;
double parkingSearchTime_min = 0.0; // TODO
double travelCost_CHF = costModel.calculateCarTravelCost(travelDistance_km);
double parkingCost_CHF = 0.0; // TODO
double delay_min = TripVariablesUtils.calculateDelay_min(trip, travelTime_min);
return new CarTripVariables(travelDistance_km, travelCost_CHF, parkingCost_CHF, travelTime_min, parkingSearchTime_min, delay_min);
return new CarTripVariables(travelDistance_km, travelCost_CHF, parkingCost_CHF, travelTime_min,
parkingSearchTime_min, delay_min);
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.variables.general;
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.general;
public class GeneralTripVariables {
public final double crowflyDistance_km;
......
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.variables.general;
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.general;
import org.matsim.core.utils.geometry.CoordUtils;
......
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.private_av;
public class PrivateAvTripVariables {
public final double travelDistance_km;
public final double travelCost_CHF;
public final double parkingCost_CHF;
public final double travelTime_min;
public final double delay_min;
public PrivateAvTripVariables(double travelDistance_km, double travelCost_CHF, double parkingCost_CHF,
double travelTime_min, double delay_min) {
this.travelDistance_km = travelDistance_km;
this.travelCost_CHF = travelCost_CHF;
this.parkingCost_CHF = parkingCost_CHF;
this.travelTime_min = travelTime_min;
this.delay_min = delay_min;
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.private_av;
import java.util.List;
import org.matsim.api.core.v01.population.Leg;
import org.matsim.api.core.v01.population.PlanElement;
import ch.ethz.matsim.discrete_mode_choice.model.DiscreteModeChoiceTrip;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.cost.CostModel;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.TripVariablesUtils;
public class PrivateAvTripVariablesCalculator {
private final CostModel costModel;
public PrivateAvTripVariablesCalculator(CostModel costModel) {
this.costModel = costModel;
}
public PrivateAvTripVariables calculate(DiscreteModeChoiceTrip trip, List<? extends PlanElement> elements) {
if (elements.size() > 1) {
throw new IllegalStateException();
}
Leg leg = (Leg) elements.get(0);
double travelDistance_km = leg.getRoute().getDistance() * 1e-3;
double travelTime_min = leg.getTravelTime() / 60.0;
double travelCost_CHF = costModel.calculatePrivateAvTravelCost(travelDistance_km);
double parkingCost_CHF = 0.0; // TODO
double delay_min = TripVariablesUtils.calculateDelay_min(trip, travelTime_min);
return new PrivateAvTripVariables(travelDistance_km, travelCost_CHF, parkingCost_CHF, travelTime_min,
delay_min);
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.pt;
public class PublicTransportTripVariables {
public final double accessEgressWalkTime_min;
public final double accessEgressWalkDistance_km;
public final double transferWalkTime_min;
public final double transferWalkDistance_km;
public final double inVehicleTime_min;
public final double inVehicleDistance_km;
public final double railTime_min;
public final double initialWaitingTime_min;
public final double waitingTime_min;
public final int lineSwitches;
public final double travelCost_CHF;
public final double headway_min;
public final double occupancy;
public enum MainMode {
Rail, Tram, Bus
}
public final MainMode mainMode;
public final double delay_min;
public PublicTransportTripVariables(double accessEgressWalkTime_min, double accessEgressWalkDistance_km,
double transferWalkTime_min, double transferWalkDistance_km, double inVehicleTime_min,
double inVehicleDistance_km, double railTime_min, double initialWaitingTime_min, double waitingTime_min,
int lineSwitches, double travelCost_CHF, double headway_min, double occupancy, MainMode mainMode,
double delay_min) {
this.accessEgressWalkTime_min = accessEgressWalkTime_min;
this.accessEgressWalkDistance_km = accessEgressWalkDistance_km;
this.transferWalkTime_min = transferWalkTime_min;
this.transferWalkDistance_km = transferWalkDistance_km;
this.inVehicleTime_min = inVehicleTime_min;
this.inVehicleDistance_km = inVehicleDistance_km;
this.railTime_min = railTime_min;
this.waitingTime_min = waitingTime_min;
this.lineSwitches = lineSwitches;
this.travelCost_CHF = travelCost_CHF;
this.headway_min = headway_min;
this.occupancy = occupancy;
this.mainMode = mainMode;
this.delay_min = delay_min;
this.initialWaitingTime_min = initialWaitingTime_min;
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.pt;
import java.util.List;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.population.Leg;
import org.matsim.api.core.v01.population.PlanElement;
import org.matsim.core.utils.geometry.CoordUtils;
import org.matsim.pt.transitSchedule.api.TransitSchedule;
import ch.ethz.matsim.baseline_scenario.transit.routing.EnrichedTransitRoute;
import ch.ethz.matsim.discrete_mode_choice.model.DiscreteModeChoiceTrip;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.cost.CostModel;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.person_variables.PersonVariables;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.TripVariablesUtils;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.estimation.trip_variables.pt.PublicTransportTripVariables.MainMode;
public class PublicTransportTripVariablesCalculator {
private final CostModel costModel;
private final TransitSchedule transitSchedule;
public PublicTransportTripVariablesCalculator(CostModel costModel, TransitSchedule transitSchedule) {
this.transitSchedule = transitSchedule;
this.costModel = costModel;
}
private MainMode getTransportMode(EnrichedTransitRoute route) {
String mainMode = transitSchedule.getTransitLines().get(route.getTransitLineId()).getRoutes()