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

add basil model + fix income

parent b2a0946b
......@@ -14,12 +14,13 @@ import ch.ethz.matsim.baseline_scenario.transit.routing.DefaultEnrichedTransitRo
import ch.ethz.matsim.baseline_scenario.transit.routing.DefaultEnrichedTransitRouteFactory;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.SwissDiscreteModeChoiceModule;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.SwissModeChoiceUtilities;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.SwissUtilityParameters.UtilitySet;
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", "model") //
.requireOptions("config-path", "model", "use-route-choice", "use-only-significant") //
.build();
// Load config
......@@ -45,7 +46,12 @@ public class RunASTRA2018002 {
Controler controler = new Controler(scenario);
controler.addOverridingModule(new SwissRailRaptorModule());
controler.addOverridingModule(new BaselineTransitModule());
controler.addOverridingModule(new SwissDiscreteModeChoiceModule(cmd.getOptionStrict("model")));
UtilitySet utilitySet = Enum.valueOf(UtilitySet.class, cmd.getOptionStrict("model"));
boolean useRouteChoice = cmd.getOption("use-route-choice").map(Boolean::parseBoolean).orElse(true);
boolean useOnlySignificant = cmd.getOption("use-only-significant").map(Boolean::parseBoolean).orElse(false);
controler
.addOverridingModule(new SwissDiscreteModeChoiceModule(utilitySet, useRouteChoice, useOnlySignificant));
// Run
controler.run();
......
......@@ -25,16 +25,21 @@ import ch.ethz.matsim.discrete_mode_choice.modules.SelectorModule;
import ch.ethz.matsim.discrete_mode_choice.modules.TourFinderModule;
import ch.ethz.matsim.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup;
import ch.ethz.matsim.discrete_mode_choice.modules.config.VehicleTourConstraintConfigGroup.HomeType;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.SwissUtilityParameters.UtilitySet;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.cost.CostModel;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.cost.CostParameters;
public class SwissDiscreteModeChoiceModule extends AbstractDiscreteModeChoiceExtension {
public static final String SWISS_ESTIMATOR_NAME = "Swiss";
private final String model;
private final UtilitySet utilitySet;
private final boolean useRouteChoice;
private final boolean onlySignificant;
public SwissDiscreteModeChoiceModule(String model) {
this.model = model;
public SwissDiscreteModeChoiceModule(UtilitySet utilitySet, boolean useRouteChoice, boolean onlySignificant) {
this.utilitySet = utilitySet;
this.useRouteChoice = useRouteChoice;
this.onlySignificant = onlySignificant;
}
@Override
......@@ -57,16 +62,7 @@ public class SwissDiscreteModeChoiceModule extends AbstractDiscreteModeChoiceExt
* TODO: We can make this configurable in a better way.
*/
switch (model) {
case "3.2.1":
return SwissUtilityParameters.buildLinearWithoutSociodemographics(true);
case "3.2.2":
return SwissUtilityParameters.buildLinearWithSociodemographics(true);
case "3.2.3":
return SwissUtilityParameters.buildNonLinear(true);
default:
throw new IllegalStateException();
}
return SwissUtilityParameters.build(utilitySet, useRouteChoice, onlySignificant);
}
@Provides
......
......@@ -39,8 +39,8 @@ public class SwissUtilityEstimator extends BaseUtilityEstimator {
utility += socioParameters.betaAge * personVariables.age;
utility += socioParameters.betaAgeSquared * Math.pow(personVariables.age, 2.0);
utility += socioParameters.betaIncome * personVariables.income;
utility += socioParameters.betaIncomeSquared * Math.pow(personVariables.income, 2.0);
utility += socioParameters.betaIncome * personVariables.income_1000CHF;
utility += socioParameters.betaIncomeSquared * Math.pow(personVariables.income_1000CHF, 2.0);
if (personVariables.isMale) {
utility += socioParameters.betaMale;
......@@ -132,7 +132,8 @@ public class SwissUtilityEstimator extends BaseUtilityEstimator {
utility += parameters.betaCost
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.pt.lambdaCostDistance) //
* interaction(personVariables.income, parameters.referenceIncome_CHF, parameters.lambdaCostIncome) //
* interaction(personVariables.income_1000CHF, parameters.referenceIncome_1000CHF,
parameters.lambdaCostIncome) //
* tripVariables.travelCost_CHF;
utility += parameters.pt.betaLineSwitch
......@@ -207,11 +208,13 @@ public class SwissUtilityEstimator extends BaseUtilityEstimator {
utility += parameters.betaCost //
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.car.lambdaCostDistance) //
* interaction(personVariables.income, parameters.referenceIncome_CHF, parameters.lambdaCostIncome) //
* interaction(personVariables.income_1000CHF, parameters.referenceIncome_1000CHF,
parameters.lambdaCostIncome) //
* tripVariables.travelCost_CHF;
utility += parameters.car.betaParkingCost
* interaction(personVariables.income, parameters.referenceIncome_CHF, parameters.lambdaCostIncome) //
* interaction(personVariables.income_1000CHF, parameters.referenceIncome_1000CHF,
parameters.lambdaCostIncome) //
* tripVariables.parkingCost_CHF;
if (personVariables.carAlwaysAvailable) {
......
......@@ -23,7 +23,7 @@ public class SwissUtilityParameters {
// Constants
public double referenceDistance_km = 20.0;
public double referenceIncome_CHF = 7000.0;
public double referenceIncome_1000CHF = 7.0;
// I) General
public double betaCost = 0.0;
......@@ -145,14 +145,16 @@ public class SwissUtilityParameters {
/**
* Chapter 3.2.1: Modell with linear utility function WITHOUT sociodemographics
*/
static public SwissUtilityParameters buildLinearWithoutSociodemographics(boolean useRouteChoice) {
static private SwissUtilityParameters buildLinearWithoutSociodemographics(boolean useRouteChoice,
boolean onlySignificant) {
SwissUtilityParameters parameters = new SwissUtilityParameters();
double s = onlySignificant ? 0.0 : 1.0;
// General
parameters.betaCost = -0.164;
if (useRouteChoice) {
parameters.betaDelay = -0.033;
parameters.betaDelay = -0.033 * s;
}
// Walk
......@@ -190,8 +192,10 @@ public class SwissUtilityParameters {
/**
* Chapter 3.2.2: Modell with linear utility function WITH sociodemographics
*/
static public SwissUtilityParameters buildLinearWithSociodemographics(boolean useRouteChoice) {
static private SwissUtilityParameters buildLinearWithSociodemographics(boolean useRouteChoice,
boolean onlySignificant) {
SwissUtilityParameters parameters = new SwissUtilityParameters();
double s = onlySignificant ? 0.0 : 1.0;
// General
parameters.betaCost = -0.107;
......@@ -204,11 +208,11 @@ public class SwissUtilityParameters {
parameters.walk.alpha = 0.879;
parameters.walk.betaTravelTime = -0.079;
parameters.walk.sociodemographics.betaMale = -0.052;
parameters.walk.sociodemographics.betaMale = -0.052 * s;
parameters.walk.sociodemographics.betaAge = 0.430;
parameters.walk.sociodemographics.betaAgeSquared = -0.044;
parameters.walk.sociodemographics.betaIncome = -0.015;
parameters.walk.sociodemographics.betaIncomeSquared = -0.002;
parameters.walk.sociodemographics.betaIncome = -0.015 * s;
parameters.walk.sociodemographics.betaIncomeSquared = -0.002 * s;
parameters.walk.purpose.betaWork = -0.112;
parameters.walk.purpose.betaEducation = 0.677;
......@@ -219,7 +223,7 @@ public class SwissUtilityParameters {
parameters.walk.region.betaRegion3 = -0.246;
parameters.walk.municipalityType.betaSubUrban = -0.190;
parameters.walk.municipalityType.betaRural = -0.044;
parameters.walk.municipalityType.betaRural = -0.044 * s;
// Bike
parameters.bike.alpha = -1.510;
......@@ -269,11 +273,11 @@ public class SwissUtilityParameters {
parameters.pt.betaSubscriptionRegional = 1.580;
parameters.pt.betaSubscriptionGA = 1.790;
parameters.pt.sociodemographics.betaMale = -0.052;
parameters.pt.sociodemographics.betaAge = 0.111;
parameters.pt.sociodemographics.betaAgeSquared = -0.007;
parameters.pt.sociodemographics.betaIncome = -0.027;
parameters.pt.sociodemographics.betaIncomeSquared = 0.000;
parameters.pt.sociodemographics.betaMale = -0.052 * s;
parameters.pt.sociodemographics.betaAge = 0.111 * s;
parameters.pt.sociodemographics.betaAgeSquared = -0.007 * s;
parameters.pt.sociodemographics.betaIncome = -0.027 * s;
parameters.pt.sociodemographics.betaIncomeSquared = 0.000 * s;
parameters.pt.purpose.betaWork = 0.321;
parameters.pt.purpose.betaEducation = 0.891;
......@@ -281,7 +285,7 @@ public class SwissUtilityParameters {
parameters.pt.purpose.betaErrand = -0.357;
parameters.pt.region.betaRegion1 = 0.378;
parameters.pt.region.betaRegion3 = 0.060;
parameters.pt.region.betaRegion3 = 0.060 * s;
parameters.pt.municipalityType.betaSubUrban = -0.191;
parameters.pt.municipalityType.betaRural = -0.242;
......@@ -292,8 +296,9 @@ public class SwissUtilityParameters {
/**
* Chapter 3.2.3: Modell with non-linear utility function
*/
static public SwissUtilityParameters buildNonLinear(boolean useRouteChoice) {
static private SwissUtilityParameters buildNonLinear(boolean useRouteChoice, boolean onlySignificant) {
SwissUtilityParameters parameters = new SwissUtilityParameters();
double s = onlySignificant ? 0.0 : 1.0;
// General
parameters.betaCost = -0.172;
......@@ -305,15 +310,15 @@ public class SwissUtilityParameters {
}
// Walk
parameters.walk.alpha = 0.001;
parameters.walk.alpha = 0.001 * s;
parameters.walk.betaTravelTime = -0.048;
parameters.walk.lambdaTravelTimeDistance = -0.360;
parameters.walk.sociodemographics.betaMale = -0.059;
parameters.walk.sociodemographics.betaMale = -0.059 * s;
parameters.walk.sociodemographics.betaAge = 0.411;
parameters.walk.sociodemographics.betaAgeSquared = -0.044;
parameters.walk.sociodemographics.betaIncome = 0.030;
parameters.walk.sociodemographics.betaIncomeSquared = -0.003;
parameters.walk.sociodemographics.betaIncome = 0.030 * s;
parameters.walk.sociodemographics.betaIncomeSquared = -0.003 * s;
parameters.walk.purpose.betaWork = -0.085;
parameters.walk.purpose.betaEducation = 0.573;
......@@ -324,7 +329,7 @@ public class SwissUtilityParameters {
parameters.walk.region.betaRegion3 = -0.238;
parameters.walk.municipalityType.betaSubUrban = -0.157;
parameters.walk.municipalityType.betaRural = -0.017;
parameters.walk.municipalityType.betaRural = -0.017 * s;
// Bike
parameters.bike.alpha = -2.750;
......@@ -384,11 +389,11 @@ public class SwissUtilityParameters {
parameters.pt.betaSubscriptionRegional = 1.480;
parameters.pt.betaSubscriptionGA = 1.610;
parameters.pt.sociodemographics.betaMale = -0.059;
parameters.pt.sociodemographics.betaMale = -0.059 * s;
parameters.pt.sociodemographics.betaAge = 0.132;
parameters.pt.sociodemographics.betaAgeSquared = -0.010;
parameters.pt.sociodemographics.betaIncome = -0.034;
parameters.pt.sociodemographics.betaIncomeSquared = 0.001;
parameters.pt.sociodemographics.betaAgeSquared = -0.010 * s;
parameters.pt.sociodemographics.betaIncome = -0.034 * s;
parameters.pt.sociodemographics.betaIncomeSquared = 0.001 * s;
parameters.pt.purpose.betaWork = 0.315;
parameters.pt.purpose.betaEducation = 0.896;
......@@ -403,4 +408,139 @@ public class SwissUtilityParameters {
return parameters;
}
/**
* Appendix A5: Table 32
*/
static private SwissUtilityParameters buildAppendix(boolean useRouteChoice, boolean onlySignificant) {
SwissUtilityParameters parameters = new SwissUtilityParameters();
double s = onlySignificant ? 0.0 : 1.0;
// General
parameters.betaCost = -0.182;
parameters.lambdaCostIncome = -0.254;
if (useRouteChoice) {
parameters.betaDelay = -0.072;
parameters.lambdaDelayDistance = -0.257;
}
// Walk
parameters.walk.alpha = 0.140 * s;
parameters.walk.betaTravelTime = -0.054;
parameters.walk.lambdaTravelTimeDistance = -0.350;
parameters.walk.sociodemographics.betaMale = -0.0 * s;
parameters.walk.sociodemographics.betaAge = 0.433 * s;
parameters.walk.sociodemographics.betaAgeSquared = -0.047 * s;
parameters.walk.sociodemographics.betaIncome = 0.056 * s;
parameters.walk.sociodemographics.betaIncomeSquared = -0.004 * s;
parameters.walk.purpose.betaWork = -0.088 * s;
parameters.walk.purpose.betaEducation = 0.655 * s;
parameters.walk.purpose.betaShop = -0.355 * s;
parameters.walk.purpose.betaErrand = -1.281;
parameters.walk.region.betaRegion1 = 0.403;
parameters.walk.region.betaRegion3 = -0.239 * s;
parameters.walk.municipalityType.betaSubUrban = -0.170 * s;
parameters.walk.municipalityType.betaRural = -0.003 * s;
// Bike
parameters.bike.alpha = -2.517;
parameters.bike.betaTravelTime = -0.059;
parameters.bike.lambdaTravelTimeDistance = -0.456;
parameters.bike.sociodemographics.betaMale = 0.434;
parameters.bike.sociodemographics.betaAge = 0.645;
parameters.bike.sociodemographics.betaAgeSquared = -0.080;
parameters.bike.sociodemographics.betaIncome = 0.218;
parameters.bike.sociodemographics.betaIncomeSquared = -0.009;
parameters.bike.purpose.betaWork = 0.405;
parameters.bike.purpose.betaEducation = 0.953;
parameters.bike.purpose.betaShop = -0.859;
parameters.bike.purpose.betaErrand = -0.795;
parameters.bike.region.betaRegion1 = 0.663;
parameters.bike.region.betaRegion3 = 0.667;
parameters.bike.municipalityType.betaSubUrban = -0.266 * s;
parameters.bike.municipalityType.betaRural = -0.201 * s;
// Car
parameters.car.alpha = 0.0;
parameters.car.betaTravelTime = -0.05;
parameters.car.betaParkingSearchTime = -0.067;
parameters.car.betaParkingCost = -0.176;
parameters.car.lambdaTravelTimeDistance = -0.302;
parameters.car.lambdaCostDistance = -0.675;
parameters.car.betaAlwaysAvailable = 0.890;
// PT
parameters.pt.alpha = -1.023;
parameters.pt.betaTravelTime = -0.035;
parameters.pt.betaAccessEgressTime = -0.042;
parameters.pt.betaWaitingTime = -0.034;
parameters.pt.betaLineSwitch = -0.179;
parameters.pt.betaHeadway = -0.009;
parameters.pt.lambdaTravelTimeDistance = -0.316;
parameters.pt.lambdaLineSwitchesDistance = -0.467;
parameters.pt.lambdaHeadwayDistance = -0.668;
parameters.pt.lambdaCostDistance = -0.433;
parameters.pt.betaOccupancy = -0.039;
if (useRouteChoice) {
parameters.pt.betaMainTransportModeRail = 0.0;
parameters.pt.betaMainTransportModeTram = -0.240;
parameters.pt.betaMainTransportModeBus = -0.233;
}
parameters.pt.betaSubscriptionHalbtax = 0.360;
parameters.pt.betaSubscriptionRegional = 1.571;
parameters.pt.betaSubscriptionGA = 1.712;
parameters.pt.sociodemographics.betaMale = -0.047 * s;
parameters.pt.sociodemographics.betaAge = 0.137 * s;
parameters.pt.sociodemographics.betaAgeSquared = -0.010 * s;
parameters.pt.sociodemographics.betaIncome = -0.026 * s;
parameters.pt.sociodemographics.betaIncomeSquared = 0.005 * s;
parameters.pt.purpose.betaWork = 0.326;
parameters.pt.purpose.betaEducation = 0.911;
parameters.pt.purpose.betaShop = -0.408;
parameters.pt.purpose.betaErrand = -0.347 * s;
parameters.pt.region.betaRegion1 = 0.415;
parameters.pt.region.betaRegion3 = 0.107 * s;
parameters.pt.municipalityType.betaSubUrban = -0.178;
parameters.pt.municipalityType.betaRural = -0.213;
return parameters;
}
public enum UtilitySet {
CHAPTER_3_2_1, CHAPTER_3_2_2, CHAPTER_3_2_3, APPENDIX_A5
}
static public SwissUtilityParameters build(UtilitySet set, boolean useRouteChoice, boolean onlySignificant) {
switch (set) {
case CHAPTER_3_2_1:
return buildLinearWithoutSociodemographics(useRouteChoice, onlySignificant);
case CHAPTER_3_2_2:
return buildLinearWithSociodemographics(useRouteChoice, onlySignificant);
case CHAPTER_3_2_3:
return buildNonLinear(useRouteChoice, onlySignificant);
case APPENDIX_A5:
return buildAppendix(useRouteChoice, onlySignificant);
default:
throw new IllegalStateException();
}
}
}
......@@ -43,7 +43,7 @@ public abstract class BaseUtilityEstimator extends AbstractTripRouterEstimator {
PersonVariables personVariables = new PersonVariables();
personVariables.age = (Integer) person.getAttributes().getAttribute("age");
personVariables.income = (Double) person.getAttributes().getAttribute("householdIncome");
personVariables.income_1000CHF = (Double) person.getAttributes().getAttribute("householdIncome") * 1e-3;
personVariables.isMale = ((String) person.getAttributes().getAttribute("sex")).equals("m");
personVariables.carAlwaysAvailable = ((String) person.getAttributes().getAttribute("carAvail"))
.equals("always");
......
......@@ -2,7 +2,7 @@ package ch.ethz.matsim.projects.astra_2018_002.mode_choice.base;
public class PersonVariables {
public int age = 0;
public double income = 0.0;
public double income_1000CHF = 0.0;
public boolean isMale = false;
public boolean carAlwaysAvailable = false;
......
......@@ -20,13 +20,13 @@ public class CostModel {
switch (personVariables.ptSubscription) {
case GA:
return 0.0;
return parameters.ptCostPerKmGA * distance_km;
case Halbtax:
return 0.5 * parameters.ptCostPerKm * distance_km;
return parameters.ptCostPerKmHalfFare * distance_km;
case None:
return parameters.ptCostPerKm * distance_km;
case Regional:
return 0.5 * parameters.ptCostPerKm * distance_km;
return parameters.ptCostPerKmRegional * distance_km;
default:
throw new IllegalStateException();
}
......
......@@ -2,5 +2,9 @@ package ch.ethz.matsim.projects.astra_2018_002.mode_choice.cost;
public class CostParameters {
public double carCostPerKm = 0.17;
public double ptCostPerKm = 0.25;
public double ptCostPerKmHalfFare = 0.25 * 0.5;
public double ptCostPerKmGA = 0.0;
public double ptCostPerKmRegional = 0.25 * 0.5;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment