Skip to content

Commit

Permalink
factor out drt optimization constraint params from drt config group a…
Browse files Browse the repository at this point in the history
…s preparatory work for service differentiation
  • Loading branch information
nkuehnel committed May 3, 2024
1 parent ef7e434 commit 6766668
Show file tree
Hide file tree
Showing 22 changed files with 196 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ private static void loadConfigGroups(Config config) {
MultiModeDrtConfigGroup multiModeDrtConfigGroup = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class);

DrtConfigGroup drtCfg = new DrtConfigGroup();
drtCfg.maxWaitTime = 2 * 3600;
drtCfg.maxTravelTimeAlpha = 5;
drtCfg.maxTravelTimeBeta = 15 * 60;
drtCfg.getDrtOptimizationConstraintsParam().maxWaitTime = 2 * 3600;
drtCfg.getDrtOptimizationConstraintsParam().maxTravelTimeAlpha = 5;
drtCfg.getDrtOptimizationConstraintsParam().maxTravelTimeBeta = 15 * 60;
drtCfg.stopDuration = 60;
drtCfg.vehiclesFile = "jointDemand_vehicles.xml";
multiModeDrtConfigGroup.addParameterSet(drtCfg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public EmptyVehicleChargingScheduler get() {
bindModal(VehicleEntry.EntryFactory.class).toProvider(
EDrtVehicleDataEntryFactory.EDrtVehicleDataEntryFactoryProvider.class).asEagerSingleton();

bindModal(CostCalculationStrategy.class).to(drtCfg.rejectRequestIfMaxWaitOrTravelTimeViolated ?
bindModal(CostCalculationStrategy.class).to(drtCfg.getDrtOptimizationConstraintsParam().rejectRequestIfMaxWaitOrTravelTimeViolated ?
CostCalculationStrategy.RejectSoftConstraintViolations.class :
CostCalculationStrategy.DiscourageSoftConstraintViolations.class).asEagerSingleton();

Expand Down Expand Up @@ -179,7 +179,7 @@ public EmptyVehicleRelocator get() {
getter.getModal(StopTimeCalculator.class), scheduleWaitBeforeDrive)))
.asEagerSingleton();

bindModal(DefaultOfferAcceptor.class).toProvider(modalProvider(getter -> new DefaultOfferAcceptor(drtCfg.maxAllowedPickupDelay)));
bindModal(DefaultOfferAcceptor.class).toProvider(modalProvider(getter -> new DefaultOfferAcceptor(drtCfg.getDrtOptimizationConstraintsParam().maxAllowedPickupDelay)));
bindModal(DrtOfferAcceptor.class).to(modalKey(DefaultOfferAcceptor.class));

bindModal(ScheduleTimingUpdater.class).toProvider(modalProvider(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public PessimisticDrtEstimator(DrtConfigGroup drtConfig) {
public Estimate estimate(DrtRoute route, OptionalTime departureTime) {
// If not estimates are present, use travel time alpha as detour
// beta is not used, because estimates are supposed to be minimums and not worst cases
double travelTime = Math.min(route.getDirectRideTime() + drtConfig.maxAbsoluteDetour,
route.getDirectRideTime() * drtConfig.maxTravelTimeAlpha);
double travelTime = Math.min(route.getDirectRideTime() + drtConfig.getDrtOptimizationConstraintsParam().maxAbsoluteDetour,
route.getDirectRideTime() * drtConfig.getDrtOptimizationConstraintsParam().maxTravelTimeAlpha);

double fare = 0;
if (drtConfig.getDrtFareParams().isPresent()) {
Expand All @@ -34,7 +34,7 @@ public Estimate estimate(DrtRoute route, OptionalTime departureTime) {
}

// for distance, also use the max travel time alpha
return new Estimate(route.getDistance() * drtConfig.maxTravelTimeAlpha, travelTime, drtConfig.maxWaitTime, fare, 0);
return new Estimate(route.getDistance() * drtConfig.getDrtOptimizationConstraintsParam().maxTravelTimeAlpha, travelTime, drtConfig.getDrtOptimizationConstraintsParam().maxWaitTime, fare, 0);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ void test() {

DrtConfigGroup drtConfigGroup = drtWithShiftsConfigGroup;
drtConfigGroup.mode = TransportMode.drt;
drtConfigGroup.maxTravelTimeAlpha = 1.5;
drtConfigGroup.maxTravelTimeBeta = 10. * 60.;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxTravelTimeAlpha = 1.5;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxTravelTimeBeta = 10. * 60.;
drtConfigGroup.stopDuration = 30.;
drtConfigGroup.maxWaitTime = 600.;
drtConfigGroup.rejectRequestIfMaxWaitOrTravelTimeViolated = true;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxWaitTime = 600.;
drtConfigGroup.getDrtOptimizationConstraintsParam().rejectRequestIfMaxWaitOrTravelTimeViolated = true;
drtConfigGroup.useModeFilteredSubnetwork = false;
drtConfigGroup.vehiclesFile = fleetFile;
drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.door2door;
drtConfigGroup.plotDetailedCustomerStats = true;
drtConfigGroup.maxWalkDistance = 1000.;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxWalkDistance = 1000.;
drtConfigGroup.idleVehiclesReturnToDepots = false;

drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,16 @@ void test() {

DrtConfigGroup drtConfigGroup = drtWithShiftsConfigGroup;
drtConfigGroup.mode = TransportMode.drt;
drtConfigGroup.maxTravelTimeAlpha = 1.5;
drtConfigGroup.maxTravelTimeBeta = 10. * 60.;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxTravelTimeAlpha = 1.5;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxTravelTimeBeta = 10. * 60.;
drtConfigGroup.stopDuration = 30.;
drtConfigGroup.maxWaitTime = 600.;
drtConfigGroup.rejectRequestIfMaxWaitOrTravelTimeViolated = true;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxWaitTime = 600.;
drtConfigGroup.getDrtOptimizationConstraintsParam().rejectRequestIfMaxWaitOrTravelTimeViolated = true;
drtConfigGroup.useModeFilteredSubnetwork = false;
drtConfigGroup.vehiclesFile = fleetFile;
drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.door2door;
drtConfigGroup.plotDetailedCustomerStats = true;
drtConfigGroup.maxWalkDistance = 1000.;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxWalkDistance = 1000.;
drtConfigGroup.idleVehiclesReturnToDepots = false;

drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,16 @@ void test() {

DrtConfigGroup drtConfigGroup = drtWithShiftsConfigGroup;
drtConfigGroup.mode = TransportMode.drt;
drtConfigGroup.maxTravelTimeAlpha = 1.5;
drtConfigGroup.maxTravelTimeBeta = 10. * 60.;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxTravelTimeAlpha = 1.5;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxTravelTimeBeta = 10. * 60.;
drtConfigGroup.stopDuration = 30.;
drtConfigGroup.maxWaitTime = 600.;
drtConfigGroup.rejectRequestIfMaxWaitOrTravelTimeViolated = true;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxWaitTime = 600.;
drtConfigGroup.getDrtOptimizationConstraintsParam().rejectRequestIfMaxWaitOrTravelTimeViolated = true;
drtConfigGroup.useModeFilteredSubnetwork = false;
drtConfigGroup.vehiclesFile = fleetFile;
drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.door2door;
drtConfigGroup.plotDetailedCustomerStats = true;
drtConfigGroup.maxWalkDistance = 1000.;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxWalkDistance = 1000.;
drtConfigGroup.idleVehiclesReturnToDepots = false;

drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ void test() {

DrtConfigGroup drtConfigGroup = drtWithShiftsConfigGroup;
drtConfigGroup.mode = TransportMode.drt;
drtConfigGroup.maxTravelTimeAlpha = 1.5;
drtConfigGroup.maxTravelTimeBeta = 10. * 60.;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxTravelTimeAlpha = 1.5;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxTravelTimeBeta = 10. * 60.;
drtConfigGroup.stopDuration = 30.;
drtConfigGroup.maxWaitTime = 600.;
drtConfigGroup.rejectRequestIfMaxWaitOrTravelTimeViolated = true;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxWaitTime = 600.;
drtConfigGroup.getDrtOptimizationConstraintsParam().rejectRequestIfMaxWaitOrTravelTimeViolated = true;
drtConfigGroup.useModeFilteredSubnetwork = false;
drtConfigGroup.vehiclesFile = fleetFile;
drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.door2door;
drtConfigGroup.plotDetailedCustomerStats = true;
drtConfigGroup.maxWalkDistance = 1000.;
drtConfigGroup.getDrtOptimizationConstraintsParam().maxWalkDistance = 1000.;
drtConfigGroup.idleVehiclesReturnToDepots = false;

drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ private void writeAndPlotWaitTimeEstimateComparison(Collection<EventSequence> pe

if (createChart) {
final JFreeChart chart2 = DensityScatterPlots.createPlot("Wait times", "Actual wait time [s]", "Initially planned wait time [s]",
times, Pair.of(0., drtCfg.maxWaitTime));
times, Pair.of(0., drtCfg.getDrtOptimizationConstraintsParam().maxWaitTime));
// xAxis.setLowerBound(0);
// yAxis.setLowerBound(0);
ChartUtils.writeChartAsPNG(new FileOutputStream(plotFileName), chart2, 1500, 1500);
Expand Down Expand Up @@ -664,11 +664,11 @@ private static void analyseDetours(Network network, List<DrtLeg> legs, Map<Id<Re
ChartSaveUtils.saveAsPNG(chart, fileName + "_distancePlot", 1500, 1500);

final JFreeChart chart2 = DensityScatterPlots.createPlot("Travel Times", "travel time [s]", "unshared ride time [s]", travelTimes,
Pair.of(drtCfg.maxTravelTimeAlpha, drtCfg.maxTravelTimeBeta));
Pair.of(drtCfg.getDrtOptimizationConstraintsParam().maxTravelTimeAlpha, drtCfg.getDrtOptimizationConstraintsParam().maxTravelTimeBeta));
ChartSaveUtils.saveAsPNG(chart2, fileName + "_travelTimePlot", 1500, 1500);

final JFreeChart chart3 = DensityScatterPlots.createPlot("Ride Times", "ride time [s]", "unshared ride time [s]", rideTimes,
Pair.of(drtCfg.maxTravelTimeAlpha, drtCfg.maxTravelTimeBeta));
Pair.of(drtCfg.getDrtOptimizationConstraintsParam().maxTravelTimeAlpha, drtCfg.getDrtOptimizationConstraintsParam().maxTravelTimeBeta));
ChartSaveUtils.saveAsPNG(chart3, fileName + "_rideTimePlot", 1500, 1500);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ protected void configureQSim() {

bindModal(VehicleEntry.EntryFactory.class).toInstance(new VehicleDataEntryFactoryImpl());

bindModal(CostCalculationStrategy.class).to(drtCfg.rejectRequestIfMaxWaitOrTravelTimeViolated ?
bindModal(CostCalculationStrategy.class).to(drtCfg.getDrtOptimizationConstraintsParam().rejectRequestIfMaxWaitOrTravelTimeViolated ?
CostCalculationStrategy.RejectSoftConstraintViolations.class :
CostCalculationStrategy.DiscourageSoftConstraintViolations.class).asEagerSingleton();

Expand Down Expand Up @@ -148,7 +148,7 @@ public EmptyVehicleRelocator get() {
getter.getModal(StopTimeCalculator.class), scheduleWaitBeforeDrive)))
.asEagerSingleton();

bindModal(DefaultOfferAcceptor.class).toProvider(modalProvider(getter -> new DefaultOfferAcceptor(drtCfg.maxAllowedPickupDelay)));
bindModal(DefaultOfferAcceptor.class).toProvider(modalProvider(getter -> new DefaultOfferAcceptor(drtCfg.getDrtOptimizationConstraintsParam().maxAllowedPickupDelay)));
bindModal(DrtOfferAcceptor.class).to(modalKey(DefaultOfferAcceptor.class));

bindModal(ScheduleTimingUpdater.class).toProvider(modalProvider(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public DrtRouteCreator(DrtConfigGroup drtCfg, Network modalNetwork,
* @return maximum travel time
*/
static double getMaxTravelTime(DrtConfigGroup drtCfg, double unsharedRideTime) {
return drtCfg.maxTravelTimeAlpha * unsharedRideTime + drtCfg.maxTravelTimeBeta;
return drtCfg.getDrtOptimizationConstraintsParam().maxTravelTimeAlpha * unsharedRideTime + drtCfg.getDrtOptimizationConstraintsParam().maxTravelTimeBeta;
}

/**
Expand All @@ -72,7 +72,7 @@ static double getMaxTravelTime(DrtConfigGroup drtCfg, double unsharedRideTime) {
* @return maximum ride time
*/
static double getMaxRideTime(DrtConfigGroup drtCfg, double unsharedRideTime) {
return Math.min(unsharedRideTime + drtCfg.maxAbsoluteDetour, drtCfg.maxDetourAlpha * unsharedRideTime + drtCfg.maxDetourBeta);
return Math.min(unsharedRideTime + drtCfg.getDrtOptimizationConstraintsParam().maxAbsoluteDetour, drtCfg.getDrtOptimizationConstraintsParam().maxDetourAlpha * unsharedRideTime + drtCfg.getDrtOptimizationConstraintsParam().maxDetourBeta);
}

public Route createRoute(double departureTime, Link accessActLink, Link egressActLink, Person person,
Expand All @@ -89,7 +89,7 @@ public Route createRoute(double departureTime, Link accessActLink, Link egressAc
route.setTravelTime(maxTravelTime);
route.setMaxRideTime(maxRideDuration);
route.setDirectRideTime(unsharedRideTime);
route.setMaxWaitTime(drtCfg.maxWaitTime);
route.setMaxWaitTime(drtCfg.getDrtOptimizationConstraintsParam().maxWaitTime);

if (this.drtCfg.storeUnsharedPath) {
route.setUnsharedPath(unsharedPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,9 @@
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;

import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;

public class DrtConfigGroup extends ReflectiveConfigGroupWithConfigurableParameterSets implements Modal {
private static final Logger log = LogManager.getLogger(DrtConfigGroup.class);
Expand All @@ -68,6 +66,9 @@ public static DrtConfigGroup getSingleModeDrtConfig(Config config) {
return drtConfigGroups.iterator().next();
}

@NotNull
private DrtOptimizationConstraintsParams drtOptimizationConstraintsParams;

@Parameter
@Comment("Mode which will be handled by PassengerEngine and VrpOptimizer (passengers'/customers' perspective)")
@NotBlank
Expand All @@ -86,66 +87,6 @@ public static DrtConfigGroup getSingleModeDrtConfig(Config config) {
@Positive
public double stopDuration = Double.NaN;// seconds

@Parameter
@Comment("Max wait time for the bus to come (optimisation constraint).")
@PositiveOrZero
public double maxWaitTime = Double.NaN;// seconds

@Parameter
@Comment("Defines the slope of the maxTravelTime estimation function (optimisation constraint), i.e. "
+ "min(unsharedRideTime + maxAbsoluteDetour, maxTravelTimeAlpha * unsharedRideTime + maxTravelTimeBeta). "
+ "Alpha should not be smaller than 1.")
@DecimalMin("1.0")
public double maxTravelTimeAlpha = Double.NaN;// [-]

@Parameter
@Comment("Defines the shift of the maxTravelTime estimation function (optimisation constraint), i.e. "
+ "min(unsharedRideTime + maxAbsoluteDetour, maxTravelTimeAlpha * unsharedRideTime + maxTravelTimeBeta). "
+ "Beta should not be smaller than 0.")
@PositiveOrZero
public double maxTravelTimeBeta = Double.NaN;// [s]

@Parameter
@Comment(
"Defines the maximum allowed absolute detour in seconds. Note that the detour is computed from the latest promised pickup time. " +
"To enable the max detour constraint, maxAllowedPickupDelay has to be specified. maxAbsoluteDetour should not be smaller than 0, "
+ "and should be higher than the offset maxDetourBeta. By default, this limit is disabled (i.e. set to Inf)")
@PositiveOrZero
public double maxAbsoluteDetour = Double.POSITIVE_INFINITY;// [s]

@Parameter
@Comment(
"Defines the maximum allowed absolute detour based on the unsharedRideTime. Note that the detour is computed from the latest promised "
+ "pickup time. To enable the max detour constraint, maxAllowedPickupDelay has to be specified. A linear combination similar to travel "
+ "time constrain is used. This is the ratio part. By default, this limit is disabled (i.e. set to Inf, together with maxDetourBeta).")
@DecimalMin("1.0")
public double maxDetourAlpha = Double.POSITIVE_INFINITY;

@Parameter
@Comment(
"Defines the maximum allowed absolute detour based on the unsharedRideTime. Note that the detour is computed from the latest promised "
+ "pickup time. To enable the max detour constraint, maxAllowedPickupDelay has to be specified. A linear combination similar to travel "
+ "time constrain is used. This is the constant part. By default, this limit is disabled (i.e. set to Inf, together with maxDetourAlpha).")
@PositiveOrZero
public double maxDetourBeta = Double.POSITIVE_INFINITY;// [s]

@Parameter
@Comment(
"Defines the maximum delay allowed from the initial scheduled pick up time. Once the initial pickup time is offered, the latest promised"
+ "pickup time is calculated based on initial scheduled pickup time + maxAllowedPickupDelay. "
+ "By default, this limit is disabled. If enabled, a value between 0 and 240 is a good choice.")
@PositiveOrZero
public double maxAllowedPickupDelay = Double.POSITIVE_INFINITY;// [s]

@Parameter
@Comment("If true, the max travel and wait times of a submitted request"
+ " are considered hard constraints (the request gets rejected if one of the constraints is violated)."
+ " If false, the max travel and wait times are considered soft constraints (insertion of a request that"
+ " violates one of the constraints is allowed, but its cost is increased by additional penalty to make"
+ " it relatively less attractive). Penalisation of insertions can be customised by injecting a customised"
+ " InsertionCostCalculator.PenaltyCalculator")
public boolean rejectRequestIfMaxWaitOrTravelTimeViolated = true;

@Parameter
@Comment("If true, the startLink is changed to last link in the current schedule, so the taxi starts the next "
+ "day at the link where it stopped operating the day before. False by default.")
Expand Down Expand Up @@ -173,14 +114,6 @@ public enum OperationalScheme {
@NotNull
public OperationalScheme operationalScheme = OperationalScheme.door2door;

//TODO consider renaming maxWalkDistance to max access/egress distance (or even have 2 separate params)
@Parameter
@Comment(
"Maximum beeline distance (in meters) to next stop location in stopbased system for access/egress walk leg to/from drt."
+ " If no stop can be found within this maximum distance will return null (in most cases caught by fallback routing module).")
@PositiveOrZero // used only for stopbased DRT scheme
public double maxWalkDistance = Double.MAX_VALUE;// [m];

@Parameter
@Comment("An XML file specifying the vehicle fleet."
+ " The file format according to dvrp_vehicles_v1.dtd"
Expand Down Expand Up @@ -243,6 +176,10 @@ public DrtConfigGroup() {
}

private void initSingletonParameterSets() {
//drt optimization constraints
addDefinition(DrtOptimizationConstraintsParams.SET_NAME, DrtOptimizationConstraintsParams::new,
() -> drtOptimizationConstraintsParams, params -> drtOptimizationConstraintsParams = (DrtOptimizationConstraintsParams) params);

//rebalancing (optional)
addDefinition(RebalancingParams.SET_NAME, RebalancingParams::new, () -> rebalancingParams,
params -> rebalancingParams = (RebalancingParams)params);
Expand Down Expand Up @@ -295,7 +232,7 @@ protected void checkConsistency(Config config) {
+ "attempting to travel without vehicles being available.");
}

Verify.verify(maxWaitTime >= stopDuration, "maxWaitTime must not be smaller than stopDuration");
Verify.verify(drtOptimizationConstraintsParams.maxWaitTime >= stopDuration, "maxWaitTime must not be smaller than stopDuration");

Verify.verify(operationalScheme != OperationalScheme.stopbased || transitStopFile != null,
"transitStopFile must not be null when operationalScheme is " + OperationalScheme.stopbased);
Expand Down Expand Up @@ -323,19 +260,20 @@ protected void checkConsistency(Config config) {
if (useModeFilteredSubnetwork) {
DvrpModeRoutingNetworkModule.checkUseModeFilteredSubnetworkAllowed(config, mode);
}

if ((maxDetourAlpha != Double.POSITIVE_INFINITY && maxDetourBeta != Double.POSITIVE_INFINITY) || maxAbsoluteDetour != Double.POSITIVE_INFINITY) {
Verify.verify(maxAllowedPickupDelay != Double.POSITIVE_INFINITY, "Detour constraints are activated, " +
"maxAllowedPickupDelay must be specified! A value between 0 and 240 seconds can be a good choice for maxAllowedPickupDelay.");
}

}

@Override
public String getMode() {
return mode;
}

public DrtOptimizationConstraintsParams getDrtOptimizationConstraintsParam() {
if (drtOptimizationConstraintsParams == null) {
addParameterSet(new DrtOptimizationConstraintsParams());
}
return drtOptimizationConstraintsParams;
}

public DrtInsertionSearchParams getDrtInsertionSearchParams() {
return drtInsertionSearchParams;
}
Expand Down
Loading

0 comments on commit 6766668

Please sign in to comment.