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

Add choice model 3.2.3

parent 6820556f
......@@ -62,6 +62,8 @@ public class SwissDiscreteModeChoiceModule extends AbstractDiscreteModeChoiceExt
return SwissUtilityParameters.buildLinearWithoutSociodemographics(true);
case "3.2.2":
return SwissUtilityParameters.buildLinearWithSociodemographics(true);
case "3.2.3":
return SwissUtilityParameters.buildNonLinear(true);
default:
throw new IllegalStateException();
}
......
......@@ -29,6 +29,10 @@ public class SwissUtilityEstimator extends BaseUtilityEstimator {
this.parameters = parameters;
}
private double interaction(double value, double reference, double lambda) {
return Math.pow(value / reference, lambda);
}
private double estimateSociodemographics(SwissUtilityParameters.SociodemographicsParameters socioParameters,
PersonVariables personVariables) {
double utility = 0.0;
......@@ -117,13 +121,30 @@ public class SwissUtilityEstimator extends BaseUtilityEstimator {
utility += parameters.pt.alpha;
utility += parameters.pt.betaAccessEgressTime * tripVariables.accessEgressTime_min;
utility += parameters.pt.betaTravelTime * tripVariables.inVehicleTime_min;
utility += parameters.pt.betaTravelTime
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.pt.lambdaTravelTimeDistance) //
* tripVariables.inVehicleTime_min;
utility += parameters.pt.betaWaitingTime * tripVariables.waitingTime_min;
utility += parameters.betaCost * tripVariables.travelCost_CHF;
utility += parameters.pt.betaLineSwitch * tripVariables.lineSwitches;
utility += parameters.betaCost
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.pt.lambdaCostDistance) //
* interaction(personVariables.income, parameters.referenceIncome_CHF, parameters.lambdaCostIncome) //
* tripVariables.travelCost_CHF;
utility += parameters.pt.betaLineSwitch
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.pt.lambdaLineSwitchesDistance)//
* tripVariables.lineSwitches;
utility += parameters.pt.betaHeadway
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.pt.lambdaHeadwayDistance)//
* tripVariables.headway_min;
utility += parameters.pt.betaHeadway * tripVariables.headway_min;
utility += parameters.pt.betaOccupancy * tripVariables.occupancy;
switch (tripVariables.mainMode) {
......@@ -162,6 +183,11 @@ public class SwissUtilityEstimator extends BaseUtilityEstimator {
throw new IllegalStateException();
}
utility += parameters.betaDelay
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.lambdaDelayDistance) //
* tripVariables.delay_min;
return utility;
}
......@@ -171,10 +197,22 @@ public class SwissUtilityEstimator extends BaseUtilityEstimator {
double utility = 0.0;
utility += parameters.car.alpha;
utility += parameters.car.betaTravelTime * tripVariables.travelTime_min;
utility += parameters.car.betaTravelTime //
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.car.lambdaTravelTimeDistance) //
* tripVariables.travelTime_min;
utility += parameters.car.betaParkingSearchTime * tripVariables.parkingSearchTime_min;
utility += parameters.betaCost * tripVariables.travelCost_CHF;
utility += parameters.car.betaParkingCost * tripVariables.parkingCost_CHF;
utility += parameters.betaCost //
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.car.lambdaCostDistance) //
* interaction(personVariables.income, parameters.referenceIncome_CHF, parameters.lambdaCostIncome) //
* tripVariables.travelCost_CHF;
utility += parameters.car.betaParkingCost
* interaction(personVariables.income, parameters.referenceIncome_CHF, parameters.lambdaCostIncome) //
* tripVariables.parkingCost_CHF;
if (personVariables.carAlwaysAvailable) {
utility += parameters.car.betaAlwaysAvailable;
......@@ -184,7 +222,12 @@ public class SwissUtilityEstimator extends BaseUtilityEstimator {
utility += estimatePurpose(parameters.car.purpose, trip);
utility += estimateRegion(parameters.car.region, personVariables);
utility += estimateMunicipalityType(parameters.car.municipalityType, personVariables);
utility += parameters.betaDelay
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.lambdaDelayDistance) //
* tripVariables.delay_min;
return utility;
}
......@@ -194,7 +237,10 @@ public class SwissUtilityEstimator extends BaseUtilityEstimator {
double utility = 0.0;
utility += parameters.walk.alpha;
utility += parameters.walk.betaTravelTime * tripVariables.travelTime_min;
utility += parameters.walk.betaTravelTime
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.walk.lambdaTravelTimeDistance) //
* tripVariables.travelTime_min;
utility += estimateSociodemographics(parameters.walk.sociodemographics, personVariables);
utility += estimatePurpose(parameters.walk.purpose, trip);
......@@ -210,7 +256,10 @@ public class SwissUtilityEstimator extends BaseUtilityEstimator {
double utility = 0.0;
utility += parameters.bike.alpha;
utility += parameters.bike.betaTravelTime * tripVariables.travelTime_min;
utility += parameters.bike.betaTravelTime
* interaction(tripVariables.travelDistance_km, parameters.referenceDistance_km,
parameters.bike.lambdaTravelTimeDistance) //
* tripVariables.travelTime_min;
utility += estimateSociodemographics(parameters.bike.sociodemographics, personVariables);
utility += estimatePurpose(parameters.bike.purpose, trip);
......
......@@ -13,17 +13,24 @@ package ch.ethz.matsim.projects.astra_2018_002.mode_choice;
*
* Ommitted choice dimensions:
* <ul>
* <li>Delay probability</li>
* <li>Delay [min]</li>
* <li>Road toll [CHF]</li>
* <li>Delay probability + Intreaction</li>
* <li>Road toll [CHF] + Interacton</li>
* </ul>
*/
public class SwissUtilityParameters {
private SwissUtilityParameters() {
}
// Constants
public double referenceDistance_km = 20.0;
public double referenceIncome_CHF = 7000.0;
// I) General
public double betaCost = 0.0;
public double betaDelay = 0.0;
public double lambdaDelayDistance = 0.0;
public double lambdaCostIncome = 0.0;
public class SociodemographicsParameters {
public double betaMale = 0.0;
......@@ -62,6 +69,8 @@ public class SwissUtilityParameters {
public PurposeParameters purpose = new PurposeParameters();
public RegionParameters region = new RegionParameters();
public MunicipalityTypeParameters municipalityType = new MunicipalityTypeParameters();
public double lambdaTravelTimeDistance = 0.0;
}
public WalkParameters walk = new WalkParameters();
......@@ -75,6 +84,8 @@ public class SwissUtilityParameters {
public PurposeParameters purpose = new PurposeParameters();
public RegionParameters region = new RegionParameters();
public MunicipalityTypeParameters municipalityType = new MunicipalityTypeParameters();
public double lambdaTravelTimeDistance = 0.0;
}
public BikeParameters bike = new BikeParameters();
......@@ -92,6 +103,9 @@ public class SwissUtilityParameters {
public PurposeParameters purpose = new PurposeParameters();
public RegionParameters region = new RegionParameters();
public MunicipalityTypeParameters municipalityType = new MunicipalityTypeParameters();
public double lambdaTravelTimeDistance = 0.0;
public double lambdaCostDistance = 0.0;
}
public CarParameters car = new CarParameters();
......@@ -119,6 +133,11 @@ public class SwissUtilityParameters {
public double betaSubscriptionHalbtax = 0.0;
public double betaSubscriptionRegional = 0.0;
public double betaSubscriptionGA = 0.0;
public double lambdaTravelTimeDistance = 0.0;
public double lambdaLineSwitchesDistance = 0.0;
public double lambdaHeadwayDistance = 0.0;
public double lambdaCostDistance = 0.0;
}
public PtParameters pt = new PtParameters();
......@@ -132,6 +151,10 @@ public class SwissUtilityParameters {
// General
parameters.betaCost = -0.164;
if (useRouteChoice) {
parameters.betaDelay = -0.033;
}
// Walk
parameters.walk.alpha = 0.791;
parameters.walk.betaTravelTime = -0.085;
......@@ -173,6 +196,10 @@ public class SwissUtilityParameters {
// General
parameters.betaCost = -0.107;
if (useRouteChoice) {
parameters.betaDelay = -0.062;
}
// Walk
parameters.walk.alpha = 0.791;
parameters.walk.betaTravelTime = -0.079;
......@@ -261,4 +288,119 @@ public class SwissUtilityParameters {
return parameters;
}
/**
* Chapter 3.2.3: Modell with non-linear utility function
*/
static public SwissUtilityParameters buildNonLinear(boolean useRouteChoice) {
SwissUtilityParameters parameters = new SwissUtilityParameters();
// General
parameters.betaCost = -0.172;
parameters.lambdaCostIncome = -0.208;
if (useRouteChoice) {
parameters.betaDelay = -0.09;
parameters.lambdaDelayDistance = -0.406;
}
// Walk
parameters.walk.alpha = 0.001;
parameters.walk.betaTravelTime = -0.048;
parameters.walk.lambdaTravelTimeDistance = -0.360;
parameters.walk.sociodemographics.betaMale = -0.059;
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.purpose.betaWork = -0.085;
parameters.walk.purpose.betaEducation = 0.573;
parameters.walk.purpose.betaShop = -0.327;
parameters.walk.purpose.betaErrand = -1.210;
parameters.walk.region.betaRegion1 = 0.333;
parameters.walk.region.betaRegion3 = -0.238;
parameters.walk.municipalityType.betaSubUrban = -0.157;
parameters.walk.municipalityType.betaRural = -0.017;
// Bike
parameters.bike.alpha = -2.750;
parameters.bike.betaTravelTime = -0.052;
parameters.bike.lambdaTravelTimeDistance = -0.367;
parameters.bike.sociodemographics.betaMale = 0.399;
parameters.bike.sociodemographics.betaAge = 0.623;
parameters.bike.sociodemographics.betaAgeSquared = -0.078;
parameters.bike.sociodemographics.betaIncome = 0.192;
parameters.bike.sociodemographics.betaIncomeSquared = -0.008;
parameters.bike.purpose.betaWork = 0.383;
parameters.bike.purpose.betaEducation = 0.869;
parameters.bike.purpose.betaShop = -0.806;
parameters.bike.purpose.betaErrand = -0.726;
parameters.bike.region.betaRegion1 = 0.601;
parameters.bike.region.betaRegion3 = 0.618;
parameters.bike.municipalityType.betaSubUrban = -0.263;
parameters.bike.municipalityType.betaRural = -0.205;
// Car
parameters.car.alpha = 0.0;
parameters.car.betaTravelTime = -0.047;
parameters.car.betaParkingSearchTime = -0.070;
parameters.car.betaParkingCost = -0.160;
parameters.car.lambdaTravelTimeDistance = -0.305;
parameters.car.lambdaCostDistance = -0.686;
parameters.car.betaAlwaysAvailable = 0.832;
// PT
parameters.pt.alpha = -0.761;
parameters.pt.betaTravelTime = -0.035;
parameters.pt.betaAccessEgressTime = -0.039;
parameters.pt.betaWaitingTime = -0.020;
parameters.pt.betaLineSwitch = -0.215;
parameters.pt.betaHeadway = -0.009;
parameters.pt.lambdaTravelTimeDistance = -0.362;
parameters.pt.lambdaLineSwitchesDistance = -0.285;
parameters.pt.lambdaHeadwayDistance = -0.583;
parameters.pt.lambdaCostDistance = -0.480;
parameters.pt.betaOccupancy = -0.038;
if (useRouteChoice) {
parameters.pt.betaMainTransportModeRail = 0.0;
parameters.pt.betaMainTransportModeTram = -0.200;
parameters.pt.betaMainTransportModeBus = -0.212;
}
parameters.pt.betaSubscriptionHalbtax = 0.315;
parameters.pt.betaSubscriptionRegional = 1.480;
parameters.pt.betaSubscriptionGA = 1.610;
parameters.pt.sociodemographics.betaMale = -0.059;
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.purpose.betaWork = 0.315;
parameters.pt.purpose.betaEducation = 0.896;
parameters.pt.purpose.betaShop = -0.403;
parameters.pt.purpose.betaErrand = -0.307;
parameters.pt.region.betaRegion1 = 0.390;
parameters.pt.region.betaRegion3 = 0.083;
parameters.pt.municipalityType.betaSubUrban = -0.208;
parameters.pt.municipalityType.betaRural = -0.247;
return parameters;
}
}
......@@ -8,6 +8,7 @@ import org.matsim.api.core.v01.population.Leg;
import org.matsim.api.core.v01.population.Person;
import org.matsim.api.core.v01.population.PlanElement;
import org.matsim.core.router.TripRouter;
import org.matsim.core.utils.misc.Time;
import org.matsim.facilities.ActivityFacilities;
import org.matsim.pt.transitSchedule.api.TransitSchedule;
......@@ -129,9 +130,15 @@ public abstract class BaseUtilityEstimator extends AbstractTripRouterEstimator {
boolean isFirstWaitingTime = true;
double inVehicleDistance_km = 0.0;
double totalTravelTime = 0.0;
double totalTravelDistance = 0.0;
for (PlanElement element : elements) {
if (element instanceof Leg) {
Leg leg = (Leg) element;
totalTravelDistance += leg.getRoute().getDistance();
totalTravelTime += leg.getTravelTime();
switch (leg.getMode()) {
case TransportMode.access_walk:
......@@ -166,6 +173,9 @@ public abstract class BaseUtilityEstimator extends AbstractTripRouterEstimator {
tripVariables.lineSwitches = Math.max(0, numberOfVehicularTrips - 1);
tripVariables.travelCost_CHF = costModel.calculatePtTravelCost(personVariables, inVehicleDistance_km);
tripVariables.delay_min = calculateDelay(trip, totalTravelTime) / 60.0;
tripVariables.travelDistance_km = totalTravelDistance / 1000.0;
return estimatePtTrip(trip, personVariables, tripVariables);
}
......@@ -189,6 +199,9 @@ public abstract class BaseUtilityEstimator extends AbstractTripRouterEstimator {
tripVariables.parkingSearchTime_min = 0.0;
tripVariables.parkingCost_CHF = 0.0;
tripVariables.delay_min = calculateDelay(trip, leg.getTravelTime()) / 60.0;
tripVariables.travelDistance_km = travelDistance_km;
return estimateCarTrip(trip, personVariables, tripVariables);
}
......@@ -201,6 +214,8 @@ public abstract class BaseUtilityEstimator extends AbstractTripRouterEstimator {
Leg leg = (Leg) elements.get(0);
tripVariables.travelTime_min = leg.getTravelTime() / 60.0;
tripVariables.travelDistance_km = leg.getRoute().getDistance() / 1000.0;
return estimateWalkTrip(trip, personVariables, tripVariables);
}
......@@ -213,6 +228,22 @@ public abstract class BaseUtilityEstimator extends AbstractTripRouterEstimator {
Leg leg = (Leg) elements.get(0);
tripVariables.travelTime_min = leg.getTravelTime() / 60.0;
tripVariables.travelDistance_km = leg.getRoute().getDistance() / 1000.0;
return estimateBikeTrip(trip, personVariables, tripVariables);
}
private double calculateDelay(DiscreteModeChoiceTrip trip, double travelTime) {
if (!Time.isUndefinedTime(trip.getOriginActivity().getEndTime())) {
double arrivalTime = trip.getOriginActivity().getEndTime() + travelTime;
if (!Time.isUndefinedTime(trip.getOriginActivity().getStartTime())) {
return Math.max(0.0, arrivalTime - trip.getDestinationActivity().getStartTime());
}
return 0.0;
} else {
throw new IllegalStateException();
}
}
}
......@@ -2,4 +2,5 @@ package ch.ethz.matsim.projects.astra_2018_002.mode_choice.base;
public class TripVariablesBike {
public double travelTime_min = 0.0;
public double travelDistance_km = 0.0;
}
......@@ -6,4 +6,7 @@ public class TripVariablesCar {
public double parkingSearchTime_min = 0.0;
public double parkingCost_CHF = 0.0;
public double delay_min = 0.0;
public double travelDistance_km = 0.0;
}
......@@ -16,4 +16,7 @@ public class TripVariablesPt {
}
public MainMode mainMode = MainMode.Bus;
public double delay_min = 0.0;
public double travelDistance_km = 0.0;
}
......@@ -2,4 +2,5 @@ package ch.ethz.matsim.projects.astra_2018_002.mode_choice.base;
public class TripVariablesWalk {
public double travelTime_min = 0.0;
public double travelDistance_km = 0.0;
}
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