Skip to content

Commit

Permalink
Merge branch 'master' into PrebookingStopActivity-performance
Browse files Browse the repository at this point in the history
  • Loading branch information
sebhoerl authored Jun 8, 2024
2 parents db7d822 + 6b5cf77 commit ba184f3
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ private void writeIterationVehicleStats(String summarizeVehicles, String vehOcc,
try (var bw = getAppendingBufferedWriter("drt_detailed_distanceStats", ".csv")) {
if (!vheaderWritten) {
vheaderWritten = true;
bw.write("runId;iteration");
bw.write("runId" + delimiter + "iteration");
for (int i = 0; i <= maxcap; i++) {
bw.write(delimiter + i + " pax distance_m");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,15 @@ class LinearPenaltyFunctionWithCap implements PenaltyFunction {

private final double penaltyPerCar;
private final double maxPenalty;
private final double areaFactor;

public LinearPenaltyFunctionWithCap(double gridSize, double penaltyPerCar, double maxPenalty) {
public LinearPenaltyFunctionWithCap(double penaltyPerCar, double maxPenalty) {
this.penaltyPerCar = penaltyPerCar;
this.maxPenalty = maxPenalty;
this.areaFactor = gridSize * gridSize / 2500.;
}

@Override
public double calculatePenalty(int numberOfCars) {
return Math.max(Math.min(numberOfCars * penaltyPerCar / areaFactor, maxPenalty), 0);
return Math.max(Math.min(numberOfCars * penaltyPerCar, maxPenalty), 0);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
*/
public /*deliberately non-final*/ class ParkingProxyModule extends AbstractModule {

private final static int GRIDSIZE = 500;
private final Scenario scenario;

public ParkingProxyModule(Scenario scenario) {
Expand All @@ -60,57 +61,38 @@ public void install() {
initialLoad,
parkingConfig.getTimeBinSize(),
qsimEndTime,
parkingConfig.getGridSize()
GRIDSIZE
);
PenaltyFunction penaltyFunction = new LinearPenaltyFunctionWithCap(parkingConfig.getGridSize(), parkingConfig.getDelayPerCar(), parkingConfig.getMaxDelay());
PenaltyFunction penaltyFunction = new LinearPenaltyFunctionWithCap(parkingConfig.getDelayPerCar(), parkingConfig.getMaxDelay());
//PenaltyFunction penaltyFunction = new ExponentialPenaltyFunctionWithCap(10, parkingConfig.getGridSize(), parkingConfig.getMaxDelay(), 360);

switch(parkingConfig.getCalculationMethod()) {
case none:
ParkingVehiclesCountEventHandler parkingHandler = new ParkingVehiclesCountEventHandler(carCounter, scenario.getNetwork(), parkingConfig.getScenarioScaleFactor());
super.addEventHandlerBinding().toInstance(parkingHandler);

CarEgressWalkObserver walkObserver;
switch (parkingConfig.getIter0Method()) {
case hourPenalty:
walkObserver = new CarEgressWalkObserver(parkingHandler, penaltyFunction, PenaltyCalculator.getDummyHourCalculator());
break;
case noPenalty:
walkObserver = new CarEgressWalkObserver(parkingHandler, penaltyFunction, PenaltyCalculator.getDummyZeroCalculator());
break;
case events:
ParkingVehiclesCountEventHandler parkingHandler = new ParkingVehiclesCountEventHandler(carCounter, scenario.getNetwork(), parkingConfig.getScenarioScaleFactor());
super.addEventHandlerBinding().toInstance(parkingHandler);

CarEgressWalkObserver walkObserver;
switch (parkingConfig.getIter0Method()) {
case hourPenalty:
walkObserver = new CarEgressWalkObserver(parkingHandler, penaltyFunction, PenaltyCalculator.getDummyHourCalculator());
break;
case noPenalty:
walkObserver = new CarEgressWalkObserver(parkingHandler, penaltyFunction, PenaltyCalculator.getDummyZeroCalculator());
break;
case takeFromAttributes:
// CarEgressWalkChanger will handle this, we don't want to also change egress walks. Note that if it is observeOnly, the first iteration will put out zeros.
walkObserver = new CarEgressWalkObserver(parkingHandler, penaltyFunction, PenaltyCalculator.getDummyZeroCalculator());
break;
case estimateFromPlans:
ParkingCounterByPlans plansCounter = new ParkingCounterByPlans(carCounter, parkingConfig.getScenarioScaleFactor());
plansCounter.calculateByPopulation(scenario.getPopulation(), scenario.getNetwork());
walkObserver = new CarEgressWalkObserver(parkingHandler, penaltyFunction, plansCounter.generatePenaltyCalculator());
break;
default:
throw new RuntimeException("Unknown iter0 mode");
}
if (parkingConfig.getObserveOnly()) {
super.addControlerListenerBinding().toInstance(walkObserver);
} else {
super.addControlerListenerBinding().toInstance(new CarEgressWalkChanger(parkingHandler, penaltyFunction, walkObserver, parkingConfig.getIter0Method()));
}
case takeFromAttributes:
// CarEgressWalkChanger will handle this, we don't want to also change egress walks. Note that if it is observeOnly, the first iteration will put out zeros.
walkObserver = new CarEgressWalkObserver(parkingHandler, penaltyFunction, PenaltyCalculator.getDummyZeroCalculator());
break;
case estimateFromPlans:
ParkingCounterByPlans plansCounter = new ParkingCounterByPlans(carCounter, parkingConfig.getScenarioScaleFactor());
plansCounter.calculateByPopulation(scenario.getPopulation(), scenario.getNetwork());
walkObserver = new CarEgressWalkObserver(parkingHandler, penaltyFunction, plansCounter.generatePenaltyCalculator());
break;
case plans:
throw new RuntimeException("Mode \"plans\" is not working yet. Use \"events\" instead.");
/*
ParkingCounterByPlans planCounter = new ParkingCounterByPlans(carCounter, parkingConfig.getScenarioScaleFactor());
super.addControlerListenerBinding().toInstance(planCounter);
if (parkingConfig.getObserveOnly()) {
super.addControlerListenerBinding().toInstance(new CarEgressWalkObserver(planCounter, penaltyFunction));
} else {
super.addControlerListenerBinding().toInstance(new CarEgressWalkChanger(planCounter, penaltyFunction));
}
break;*/
default:
throw new RuntimeException("Unsupported calculation method " + parkingConfig.getCalculationMethod());
throw new RuntimeException("Unknown iter0 mode");
}
if (parkingConfig.getObserveOnly()) {
super.addControlerListenerBinding().toInstance(walkObserver);
} else {
super.addControlerListenerBinding().toInstance(new CarEgressWalkChanger(parkingHandler, penaltyFunction, walkObserver, parkingConfig.getIter0Method()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,23 @@

public class ParkingProxyConfigGroup extends ReflectiveConfigGroup {

public static enum CalculationMethod {none, events, plans};
public static enum Iter0Method {noPenalty, hourPenalty, takeFromAttributes, estimateFromPlans}

public static final String GROUP_NAME = "parkingProxy";
public static final String METHOD = "method";
public static final String ITER0 = "iter0";
public static final String OBSERVE_ONLY = "observeOnly";
public static final String DELAY_PER_CAR = "delayPerCar";
public static final String MAX_DELAY = "maxDelay";
public static final String SCALE_FACTOR = "scenarioScaleFactor";
public static final String TIME_BIN_SIZE = "timeBinSize";
public static final String GRID_SIZE = "gridSize";
public static final String CARS_PER_1000_PERSONS = "carsPer1000Persons";

private CalculationMethod method = CalculationMethod.events;
private Iter0Method iter0Method = Iter0Method.hourPenalty;
private boolean observeOnly = false;
private double delayPerCar = 2.5;
private double maxDelay = 900;
private int scenarioScaleFactor = 100;
private int timeBinSize = 900;
private int gridSize = 500;
private int carsPer1000Persons = 500;

public ParkingProxyConfigGroup() {
Expand All @@ -58,22 +53,12 @@ public Map<String, String> getComments() {
comments.put(SCALE_FACTOR, "The inverse of the scenario perentage, i.e. the number with which to multiply the"
+ " number of agents to get the real life population, e.g. 4 in a 25% scenario. Needs to be an Intger,"
+ " so in case of weird percentages (e.g. 1/3) please round.");
comments.put(DELAY_PER_CAR, "in seconds. Note that this should be scaled MANUALLY with the gridsize!");
comments.put(MAX_DELAY, "in seconds. Note that this should be scaled MANUALLY with the gridsize!");
comments.put(DELAY_PER_CAR, "in seconds");
comments.put(MAX_DELAY, "in seconds");
comments.put(TIME_BIN_SIZE, "in seconds");
comments.put(GRID_SIZE, "in CRS units, usually meters");
return comments;
}

@StringGetter(METHOD)
public CalculationMethod getCalculationMethod() {
return this.method;
}
@StringSetter(METHOD)
public void setCalculationMethod(CalculationMethod method) {
this.method = method;
}

@StringGetter(ITER0)
public Iter0Method getIter0Method() {
return this.iter0Method;
Expand Down Expand Up @@ -110,15 +95,6 @@ public void setMaxDelay(double maxDelay) {
this.maxDelay = maxDelay;
}

@StringGetter(GRID_SIZE)
public int getGridSize() {
return gridSize;
}
@StringSetter(GRID_SIZE)
public void setGridSize(int gridSize) {
this.gridSize = gridSize;
}

@StringGetter(TIME_BIN_SIZE)
public int getTimeBinSize() {
return timeBinSize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
package ch.sbb.matsim.config;

import com.google.common.base.Verify;

import ch.sbb.matsim.routing.pt.raptor.RaptorStaticConfig.RaptorTransferCalculation;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
Expand Down Expand Up @@ -61,6 +64,8 @@ public class SwissRailRaptorConfigGroup extends ReflectiveConfigGroup {
private static final String PARAM_TRANSFER_WALK_MARGIN_DESC = "time deducted from transfer walk leg during transfers between pt legs in order to avoid missing a vehicle by a few seconds due to delays.";
private static final String PARAM_INTERMODAL_LEG_ONLYHANDLING = "intermodalLegOnlyHandling";
private static final String PARAM_INTERMODAL_LEG_ONLYHANDLING_DESC = "Define how routes containing only intermodal legs are handled: Useful options: alllow, avoid, forbid";
private static final String PARAM_TRANSFER_CALCULATION = "transferCalculation";
private static final String PARAM_TRANFER_CALCULATION_DESC = "Defines whether all potential transfers are precomputed at the beginning of the simulation (Initial) or whether they are constructed on-demand (Cached). The former incurs potentially long up-front caclulations, but quicker routing. The latter avoids any initial computation, but may require longer routing time.";

private boolean useRangeQuery = false;
private boolean useIntermodality = false;
Expand All @@ -74,6 +79,7 @@ public class SwissRailRaptorConfigGroup extends ReflectiveConfigGroup {
private double transferPenaltyHourlyCost = 0;
private double transferWalkMargin = 5;
private IntermodalLegOnlyHandling intermodalLegOnlyHandling = IntermodalLegOnlyHandling.forbid;
private RaptorTransferCalculation transferCalculation = RaptorTransferCalculation.Initial;

private ScoringParameters scoringParameters = ScoringParameters.Default;

Expand Down Expand Up @@ -128,9 +134,19 @@ public void setIntermodalLegOnlyHandling(IntermodalLegOnlyHandling intermodalLeg
public String getIntermodalLegOnlyHandlingString() {
return intermodalLegOnlyHandling.toString();
}

public IntermodalLegOnlyHandling getIntermodalLegOnlyHandling() {
return intermodalLegOnlyHandling;
}

@StringSetter(PARAM_TRANSFER_CALCULATION)
public void setTransferCalculation(RaptorTransferCalculation transferCalculation) {
this.transferCalculation = transferCalculation;
}

@StringGetter(PARAM_TRANSFER_CALCULATION)
public RaptorTransferCalculation getTransferCalculation() {
return transferCalculation;
}

@StringGetter(PARAM_USE_RANGE_QUERY)
Expand Down Expand Up @@ -707,6 +723,7 @@ public Map<String, String> getComments() {
comments.put(PARAM_USE_CAPACITY_CONSTRAINTS, PARAM_USE_CAPACITY_CONSTRAINTS_DESC);
comments.put(PARAM_TRANSFER_WALK_MARGIN, PARAM_TRANSFER_WALK_MARGIN_DESC);
comments.put(PARAM_INTERMODAL_ACCESS_EGRESS_MODE_SELECTION,PARAM_INTERMODAL_ACCESS_EGRESS_MODE_SELECTION_DESC);
comments.put(PARAM_TRANSFER_CALCULATION, PARAM_TRANFER_CALCULATION_DESC);
return comments;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,22 @@ public enum RaptorOptimization {
* (see {@link SwissRailRaptor#calcTree(TransitStopFacility, double, RaptorParameters, Person)} ).
*/
OneToAllRouting }

public enum RaptorTransferCalculation {
/**
* Use this option if you want the algorithm to calculate all possible transfers
* up-front, which will allow for rapid lookup during routing, but may come with
* significant simulation startup time.
*/
Initial,

/**
* Use this option if you want the algorithm to calculate transfers on demand,
* which avoids any simulation start-up time but may increase the routing time
* itself.
*/
Cached
}


/**
Expand All @@ -71,6 +87,7 @@ public enum RaptorOptimization {
private boolean useCapacityConstraints = false;

private RaptorOptimization optimization = RaptorOptimization.OneToOneRouting;
private RaptorTransferCalculation transferCalculation = RaptorTransferCalculation.Initial;

private SwissRailRaptorConfigGroup.IntermodalLegOnlyHandling intermodalLegOnlyHandling = SwissRailRaptorConfigGroup.IntermodalLegOnlyHandling.forbid;

Expand Down Expand Up @@ -167,4 +184,12 @@ public SwissRailRaptorConfigGroup.IntermodalLegOnlyHandling getIntermodalLegOnly
public void setIntermodalLegOnlyHandling(SwissRailRaptorConfigGroup.IntermodalLegOnlyHandling intermodalLegOnlyHandling) {
this.intermodalLegOnlyHandling = intermodalLegOnlyHandling;
}

public RaptorTransferCalculation getTransferCalculation() {
return this.transferCalculation;
}

public void setTransferCalculation(RaptorTransferCalculation transferCalculation) {
this.transferCalculation = transferCalculation;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public static RaptorStaticConfig createStaticConfig(Config config) {
staticConfig.setTransferWalkMargin(srrConfig.getTransferWalkMargin());
staticConfig.setIntermodalLegOnlyHandling(srrConfig.getIntermodalLegOnlyHandling());
staticConfig.setMinimalTransferTime(config.transitRouter().getAdditionalTransferTime());
staticConfig.setTransferCalculation(srrConfig.getTransferCalculation());

staticConfig.setUseModeMappingForPassengers(srrConfig.isUseModeMappingForPassengers());
if (srrConfig.isUseModeMappingForPassengers()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -752,10 +752,17 @@ private void handleTransfers(boolean strict, RaptorParameters raptorParams) {
continue;
}
RRouteStop fromRouteStop = fromPE.toRouteStop; // this is the route stop we arrive with least cost at stop
int firstTransferIndex = fromRouteStop.indexFirstTransfer;
int lastTransferIndex = firstTransferIndex + fromRouteStop.countTransfers;

// obtain on-demand transfers if applicable (will return null if transfers are calculated initially)
RTransfer[] transfers = this.data.calculateTransfers(fromRouteStop);

int firstTransferIndex = transfers == null ? fromRouteStop.indexFirstTransfer : 0;
int lastTransferIndex = transfers == null ? firstTransferIndex + fromRouteStop.countTransfers : transfers.length;
transfers = transfers == null ? this.data.transfers : transfers;

for (int transferIndex = firstTransferIndex; transferIndex < lastTransferIndex; transferIndex++) {
RTransfer transfer = this.data.transfers[transferIndex];
RTransfer transfer = transfers[transferIndex];

int toRouteStopIndex = transfer.toRouteStop;
transferProvider.reset(transfer);
int newArrivalTime = arrivalTime + transfer.transferTime;
Expand Down
Loading

0 comments on commit ba184f3

Please sign in to comment.