Skip to content

Commit

Permalink
add LausitzPtFareModule for more detailled pt pricing
Browse files Browse the repository at this point in the history
  • Loading branch information
simei94 committed Jun 18, 2024
1 parent f3768f6 commit fdbc02c
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 3 deletions.
76 changes: 76 additions & 0 deletions src/main/java/org/matsim/run/LausitzPtFareModule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.matsim.run;

import org.matsim.api.core.v01.TransportMode;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.controler.AbstractModule;
import playground.vsp.pt.fare.DistanceBasedPtFareHandler;
import playground.vsp.pt.fare.DistanceBasedPtFareParams;
import playground.vsp.pt.fare.PtFareConfigGroup;
import playground.vsp.pt.fare.PtFareUpperBoundHandler;

/**
* Provides pt fare calculation for the lausitz model.
*/
public class LausitzPtFareModule extends AbstractModule {

// sources for price values:
// https://www.vbb.de/tickets/monatskarten/vbb-umweltkarte/
// for some example trips, which were used to calc (bahn.de) the below values see internal documentation

// single trip fare (<30km): mean(5.40,2.85)
static final double NORMAL_BASE_FARE = 4.125;
// shorter trips do not have a slope in this scenario
static final double NORMAL_TRIP_SLOPE = 0.000;
// agents always pay normalBaseFare minimum as there is no distance based cost for trips <30km
static final double MIN_FARE = NORMAL_BASE_FARE;
// for trips of +-30km there seems to be a somewhat higher pt price.
// the threshold is also chosen because Ruhland - Hoyerswerda falls just under the 30km mark.
// if the above connection were a longer = more expensive trip, it would increase the attractivity of the DRT service (policy case) immensly
static final int LONG_DISTANCE_THRESHOLD = 30000;
// single trip fare (>=30km): mean(20.30,30)
static final double LONG_BASE_FARE = 25.15;
// max. price: 46€ for 108km (longest rail distance in study area Eisenhüttenstadt <-> Bautzen) compared to mean price 25.15€ for 30km
// => slope for distance based cost: 0,2673076923€
static final double LONG_TRIP_SLOPE = 0.2673076923;

@Override
public void install() {
// Set the money related thing in the config (planCalcScore/scoring) file to 0.
getConfig().scoring().getModes().get(TransportMode.pt).setDailyMonetaryConstant(0);

// Initialize config group (and also write in the output config)
PtFareConfigGroup ptFareConfigGroup = ConfigUtils.addOrGetModule(this.getConfig(), PtFareConfigGroup.class);
DistanceBasedPtFareParams distanceBasedPtFareParams = ConfigUtils.addOrGetModule(this.getConfig(), DistanceBasedPtFareParams.class);

// Set parameters
ptFareConfigGroup.setApplyUpperBound(true);
// upper bound factor: relation of single trip compared to daily cost of monthly VBB ticket
// 5.12 / 4.125 = 1.24
ptFareConfigGroup.setUpperBoundFactor(1.24);

// Minimum fare (e.g. short trip or 1 zone ticket)
distanceBasedPtFareParams.setMinFare(MIN_FARE);
// Division between long trip and short trip (unit: m)
distanceBasedPtFareParams.setLongDistanceTripThreshold(LONG_DISTANCE_THRESHOLD);

// y = ax + b --> a value, for short trips
distanceBasedPtFareParams.setNormalTripSlope(NORMAL_TRIP_SLOPE);
// y = ax + b --> b value, for short trips
distanceBasedPtFareParams.setNormalTripIntercept(NORMAL_BASE_FARE);

// Base price is the daily ticket for long trips
// y = ax + b --> a value, for long trips
distanceBasedPtFareParams.setLongDistanceTripSlope(LONG_TRIP_SLOPE);
// y = ax + b --> b value, for long trips
distanceBasedPtFareParams.setLongDistanceTripIntercept(LONG_BASE_FARE);


// Add bindings
addEventHandlerBinding().toInstance(new DistanceBasedPtFareHandler(distanceBasedPtFareParams));
if (ptFareConfigGroup.getApplyUpperBound()) {
PtFareUpperBoundHandler ptFareUpperBoundHandler = new PtFareUpperBoundHandler(ptFareConfigGroup.getUpperBoundFactor());
addEventHandlerBinding().toInstance(ptFareUpperBoundHandler);
addControlerListenerBinding().toInstance(ptFareUpperBoundHandler);
}
}
}
9 changes: 6 additions & 3 deletions src/main/java/org/matsim/run/LausitzScenario.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,12 @@ public LausitzScenario(String configPath) {
super(configPath);
}

// TODO: change version variable to 1.1 and rather use this constructor than the follwoing
// public LausitzScenario() {
// super(String.format("input/v%s/lausitz-v%s-10pct.config.xml", VERSION, VERSION));
// }
public LausitzScenario() {
super(String.format("input/v%s/lausitz-v%s-25pct.config.xml", VERSION, VERSION));
super("input/v1.1/lausitz-v1.1-10pct.config.xml");
}

public static void main(String[] args) {
Expand Down Expand Up @@ -106,8 +110,6 @@ protected Config prepareConfig(Config config) {

// TODO: Config options

// TODO: recreate counts format with car and trucks

return config;
}

Expand Down Expand Up @@ -135,6 +137,7 @@ protected void prepareControler(Controler controler) {
controler.addOverridingModule(new AbstractModule() {
@Override
public void install() {
install(new LausitzPtFareModule());

bind(ScoringParametersForPerson.class).to(IncomeDependentUtilityOfMoneyPersonScoringParameters.class).asEagerSingleton();

Expand Down

0 comments on commit fdbc02c

Please sign in to comment.