Skip to content

Commit

Permalink
Merge branch 'master' into preplannedOptimizer
Browse files Browse the repository at this point in the history
  • Loading branch information
nkuehnel authored Sep 15, 2024
2 parents fbfe1e8 + a60c794 commit afb0b48
Show file tree
Hide file tree
Showing 15 changed files with 223 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,22 @@ public void nextTask(DvrpVehicle vehicle) {
} else {
nonVisitedPreplannedStops.poll();//remove this stop from queue

var stopTask = taskFactory.createStopTask(vehicle, currentTime, currentTime + stopDuration, currentLink);
if (nextStop.pickup) {
var request = Preconditions.checkNotNull(openRequests.get(nextStop.preplannedRequest.key),
"Request (%s) has not been yet submitted", nextStop.preplannedRequest);
stopTask.addPickupRequest(AcceptedDrtRequest.createFromOriginalRequest(request));
if(nextStop.preplannedRequest.key.passengerIds.isEmpty() && nonVisitedPreplannedStops.isEmpty()) {
var stayTask = taskFactory.createStayTask(vehicle, currentTime, vehicle.getServiceEndTime(), currentLink);
schedule.addTask(stayTask);
} else {
var request = Preconditions.checkNotNull(openRequests.remove(nextStop.preplannedRequest.key),
"Request (%s) has not been yet submitted", nextStop.preplannedRequest);
stopTask.addDropoffRequest(AcceptedDrtRequest.createFromOriginalRequest(request));
var stopTask = taskFactory.createStopTask(vehicle, currentTime, currentTime + stopDuration, currentLink);
if (nextStop.pickup) {
var request = Preconditions.checkNotNull(openRequests.get(nextStop.preplannedRequest.key),
"Request (%s) has not been yet submitted", nextStop.preplannedRequest);
stopTask.addPickupRequest(AcceptedDrtRequest.createFromOriginalRequest(request));
} else {
var request = Preconditions.checkNotNull(openRequests.remove(nextStop.preplannedRequest.key),
"Request (%s) has not been yet submitted", nextStop.preplannedRequest);
stopTask.addDropoffRequest(AcceptedDrtRequest.createFromOriginalRequest(request));
}
schedule.addTask(stopTask);
}
schedule.addTask(stopTask);
}

// switch to the next task and update currentTasks
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.matsim.contrib.drt.optimizer.constraints;

/**
* @author Sebastian Hörl, IRT SystemX
*/
public record DrtRouteConstraints( //
double maxTravelTime, //
double maxRideTime, //
double maxWaitTime//
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public Optional<AcceptedDrtRequest> acceptDrtOffer(DrtRequest request, double de
.newBuilder()
.request(request)
.earliestStartTime(request.getEarliestStartTime())
.maxRideDuration(request.getMaxRideDuration())
.latestArrivalTime(Math.min(updatedLatestStartTime + request.getMaxRideDuration(), request.getLatestArrivalTime()))
.latestStartTime(updatedLatestStartTime).build());
.latestStartTime(updatedLatestStartTime)
.build());
}
}
Original file line number Diff line number Diff line change
@@ -1,45 +1,53 @@
package org.matsim.contrib.drt.routing;

import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.population.Person;
import org.matsim.contrib.drt.optimizer.constraints.ConstraintSetChooser;
import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet;
import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsSet;
import org.matsim.contrib.drt.optimizer.constraints.DrtRouteConstraints;
import org.matsim.contrib.drt.run.DrtConfigGroup;
import org.matsim.utils.objectattributes.attributable.Attributes;

/**
* @author nkuehnel / MOIA
*/
public class DefaultDrtRouteConstraintsCalculator implements DrtRouteConstraintsCalculator {

/**
* Calculates the maximum travel time defined as: drtCfg.getMaxTravelTimeAlpha() * unsharedRideTime + drtCfg.getMaxTravelTimeBeta()
*
* @param constraintsSet
* @param unsharedRideTime ride time of the direct (shortest-time) route
* @return maximum travel time
*/
@Override
public double getMaxTravelTime(DrtOptimizationConstraintsSet constraintsSet, double unsharedRideTime) {
if(constraintsSet instanceof DefaultDrtOptimizationConstraintsSet defaultSet) {
return defaultSet.maxTravelTimeAlpha * unsharedRideTime
+ defaultSet.maxTravelTimeBeta;
} else {
throw new IllegalArgumentException("Constraint set is not a default set");
}
}

/**
* Calculates the maximum ride time defined as: drtCfg.maxDetourAlpha * unsharedRideTime + drtCfg.maxDetourBeta
*
* @param constraintsSet
* @param unsharedRideTime ride time of the direct (shortest-time) route
* @return maximum ride time
*/
@Override
public double getMaxRideTime(DrtOptimizationConstraintsSet constraintsSet, double unsharedRideTime) {
if(constraintsSet instanceof DefaultDrtOptimizationConstraintsSet defaultSet) {
return Math.min(unsharedRideTime + defaultSet.maxAbsoluteDetour,
defaultSet.maxDetourAlpha * unsharedRideTime
+ defaultSet.maxDetourBeta);
} else {
throw new IllegalArgumentException("Constraint set is not a default set");
}
}
private final DrtConfigGroup drtCfg;
private final ConstraintSetChooser constraintSetChooser;

public DefaultDrtRouteConstraintsCalculator(DrtConfigGroup drtCfg, ConstraintSetChooser constraintSetChooser) {
this.drtCfg = drtCfg;
this.constraintSetChooser = constraintSetChooser;
}

/**
* Calculates the maximum travel time defined as: drtCfg.getMaxTravelTimeAlpha()
* unsharedRideTime + drtCfg.getMaxTravelTimeBeta()
*
* Calculates the maximum ride time defined as: drtCfg.maxDetourAlpha *
* unsharedRideTime + drtCfg.maxDetourBeta
*
* @return DrtRouteConstraints constraints
*/
@Override
public DrtRouteConstraints calculateRouteConstraints(double departureTime, Link accessActLink, Link egressActLink,
Person person, Attributes tripAttributes, double unsharedRideTime, double unsharedDistance) {
DrtOptimizationConstraintsSet constraintsSet = constraintSetChooser
.chooseConstraintSet(departureTime, accessActLink, egressActLink, person, tripAttributes).orElse(drtCfg
.addOrGetDrtOptimizationConstraintsParams().addOrGetDefaultDrtOptimizationConstraintsSet());

if (constraintsSet instanceof DefaultDrtOptimizationConstraintsSet defaultSet) {
double maxTravelTime = defaultSet.maxTravelTimeAlpha * unsharedRideTime + defaultSet.maxTravelTimeBeta;
double maxRideTime = Math.min(unsharedRideTime + defaultSet.maxAbsoluteDetour,
defaultSet.maxDetourAlpha * unsharedRideTime + defaultSet.maxDetourBeta);
double maxWaitTime = constraintsSet.maxWaitTime;

return new DrtRouteConstraints(maxTravelTime, maxRideTime, maxWaitTime);
} else {
throw new IllegalArgumentException("Constraint set is not a default set");
}

}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
package org.matsim.contrib.drt.routing;

import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsSet;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.population.Person;
import org.matsim.contrib.drt.optimizer.constraints.DrtRouteConstraints;
import org.matsim.utils.objectattributes.attributable.Attributes;

/**
* @author nkuehnel / MOIA
* @author Sebastian Hörl, IRT SystemX
*/
public interface DrtRouteConstraintsCalculator {

double getMaxTravelTime(DrtOptimizationConstraintsSet constraintsSet, double unsharedRideTime);
DrtRouteConstraints calculateRouteConstraints( //
double departureTime, //
Link accessActLink, //
Link egressActLink, //
Person person, //
Attributes tripAttributes, //
double unsharedRideTime, //
double unsharedDistance //
);

double getMaxRideTime(DrtOptimizationConstraintsSet constraintsSet, double unsharedRideTime);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.matsim.api.core.v01.population.Route;
import org.matsim.contrib.drt.optimizer.constraints.ConstraintSetChooser;
import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsSet;
import org.matsim.contrib.drt.optimizer.constraints.DrtRouteConstraints;
import org.matsim.contrib.drt.run.DrtConfigGroup;
import org.matsim.contrib.dvrp.path.VrpPathWithTravelData;
import org.matsim.contrib.dvrp.path.VrpPaths;
Expand All @@ -40,6 +41,7 @@
* @author jbischoff
* @author michalm (Michal Maciejewski)
* @author Kai Nagel
* @author Sebastian Hörl, IRT SystemX
*/
public class DrtRouteCreator implements DefaultMainLegRouter.RouteCreator {
private final DrtConfigGroup drtCfg;
Expand All @@ -48,16 +50,13 @@ public class DrtRouteCreator implements DefaultMainLegRouter.RouteCreator {

private final DrtRouteConstraintsCalculator routeConstraintsCalculator;

private final ConstraintSetChooser constraintSetChooser;

public DrtRouteCreator(DrtConfigGroup drtCfg, Network modalNetwork,
LeastCostPathCalculatorFactory leastCostPathCalculatorFactory, TravelTime travelTime,
TravelDisutilityFactory travelDisutilityFactory,
DrtRouteConstraintsCalculator routeConstraintsCalculator, ConstraintSetChooser constraintSetChooser) {
DrtRouteConstraintsCalculator routeConstraintsCalculator) {
this.drtCfg = drtCfg;
this.travelTime = travelTime;
this.routeConstraintsCalculator = routeConstraintsCalculator;
this.constraintSetChooser = constraintSetChooser;
router = leastCostPathCalculatorFactory.createPathCalculator(modalNetwork,
travelDisutilityFactory.createTravelDisutility(travelTime), travelTime);
}
Expand All @@ -71,18 +70,15 @@ public Route createRoute(double departureTime, Link accessActLink, Link egressAc
double unsharedRideTime = unsharedPath.getTravelTime();//includes first & last link
double unsharedDistance = VrpPaths.calcDistance(unsharedPath);//includes last link

DrtOptimizationConstraintsSet constraintsSet =
constraintSetChooser.chooseConstraintSet(departureTime, accessActLink, egressActLink, person, tripAttributes)
.orElse(drtCfg.addOrGetDrtOptimizationConstraintsParams().addOrGetDefaultDrtOptimizationConstraintsSet());
double maxTravelTime = routeConstraintsCalculator.getMaxTravelTime(constraintsSet, unsharedRideTime);
double maxRideDuration = routeConstraintsCalculator.getMaxRideTime(constraintsSet, unsharedRideTime);
DrtRouteConstraints constraints = routeConstraintsCalculator.calculateRouteConstraints(departureTime, accessActLink, egressActLink, person,
tripAttributes, unsharedRideTime, unsharedDistance);

DrtRoute route = routeFactories.createRoute(DrtRoute.class, accessActLink.getId(), egressActLink.getId());
route.setDistance(unsharedDistance);
route.setTravelTime(maxTravelTime);
route.setMaxRideTime(maxRideDuration);
route.setTravelTime(constraints.maxTravelTime());
route.setMaxRideTime(constraints.maxRideTime());
route.setDirectRideTime(unsharedRideTime);
route.setMaxWaitTime(constraintsSet.maxWaitTime);
route.setMaxWaitTime(constraints.maxWaitTime());

if (this.drtCfg.storeUnsharedPath) {
route.setUnsharedPath(unsharedPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ public void install() {
// yyyy possibly not used for door2door; try to move inside the corresponding switch statement below. kai, feb'24


bindModal(DrtRouteConstraintsCalculator.class).toProvider(modalProvider(getter -> new DefaultDrtRouteConstraintsCalculator())).in(Singleton.class);
bindModal(DrtRouteConstraintsCalculator.class).toProvider(modalProvider(getter -> new DefaultDrtRouteConstraintsCalculator(
drtCfg, getter.getModal(ConstraintSetChooser.class)))).in(Singleton.class);
DrtOptimizationConstraintsSet optimizationConstraintsSet = drtCfg.addOrGetDrtOptimizationConstraintsParams().addOrGetDefaultDrtOptimizationConstraintsSet();
bindModal(ConstraintSetChooser.class).toProvider(
() -> (departureTime, accessActLink, egressActLink, person, tripAttributes)
Expand Down Expand Up @@ -159,8 +160,7 @@ public DrtRouteCreator get() {
var travelTime = getModalInstance(TravelTime.class);
return new DrtRouteCreator(drtCfg, getModalInstance(Network.class), leastCostPathCalculatorFactory,
travelTime, getModalInstance(TravelDisutilityFactory.class),
getModalInstance(DrtRouteConstraintsCalculator.class),
getModalInstance(ConstraintSetChooser.class));
getModalInstance(DrtRouteConstraintsCalculator.class));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ void testCottbusClosestAccessEgressStopFinder() {
scenario.getNetwork(), QuadTrees.createQuadTree(drtStops.values()));
DrtRouteCreator drtRouteCreator = new DrtRouteCreator(drtCfg, scenario.getNetwork(),
new SpeedyDijkstraFactory(), new FreeSpeedTravelTime(), TimeAsTravelDisutility::new,
new DefaultDrtRouteConstraintsCalculator(),
(departureTime, accessActLink, egressActLink, person, tripAttributes) -> Optional.of(defaultConstraintsSet));
new DefaultDrtRouteConstraintsCalculator(drtCfg,
(departureTime, accessActLink, egressActLink, person, tripAttributes) -> Optional.of(defaultConstraintsSet)));
DefaultMainLegRouter mainRouter = new DefaultMainLegRouter(drtMode, scenario.getNetwork(),
scenario.getPopulation().getFactory(), drtRouteCreator);
DvrpRoutingModule dvrpRoutingModule = new DvrpRoutingModule(mainRouter, walkRouter, walkRouter, stopFinder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,20 @@

package org.matsim.contrib.dvrp.run;

import java.util.Set;

import javax.annotation.Nullable;

import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.PositiveOrZero;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.contrib.dynagent.run.DynQSimConfigConsistencyChecker;
import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets;
import org.matsim.contrib.dynagent.run.DynQSimConfigConsistencyChecker;
import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams;
import org.matsim.core.config.Config;

import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;
import javax.annotation.Nullable;
import java.util.Set;

public class DvrpConfigGroup extends ReflectiveConfigGroupWithConfigurableParameterSets {
private static final Logger log = LogManager.getLogger(DvrpConfigGroup.class);
Expand Down Expand Up @@ -68,13 +65,14 @@ public static DvrpConfigGroup get(Config config) {
@Parameter
@Comment("Used for OFFLINE estimation of travel times for VrpOptimizer"
+ " by means of the exponential moving average."
+ " The weighting decrease, alpha, must be in (0,1]."
+ " The weighting decrease, alpha, must be in [0,1]."
+ " We suggest small values of alpha, e.g. 0.05."
+ " The averaging starts from the initial travel time estimates. If not provided,"
+ " the free-speed TTs is used as the initial estimates")
@Positive
+ " the free-speed TTs is used as the initial estimates. If alpha is set to 0, the initial"
+ " travel times stay fixed.")
@PositiveOrZero
@DecimalMax("1.0")
public double travelTimeEstimationAlpha = 0.05; // [-], 1 ==> TTs from the last iteration only
public double travelTimeEstimationAlpha = 0.05; // [-], 1 ==> TTs from the last iteration only, 0 ==> initial TTs only

@Parameter
@Comment(""
Expand Down Expand Up @@ -146,6 +144,12 @@ protected void checkConsistency(Config config) {
if (!config.eventsManager().getSynchronizeOnSimSteps()) {
throw new RuntimeException("Synchronization on sim steps is required");
}
if(initialTravelTimesFile == null && travelTimeEstimationAlpha == 0.0) {
throw new RuntimeException("Initial travel times file is required if travel times should not be updated.");
}
if(travelTimeEstimationAlpha == 0.0 && travelTimeEstimationBeta > 0) {
throw new RuntimeException("Online estimation beta should be 0 if travel time should not be updated.");
}
}

public DvrpTravelTimeMatrixParams getTravelTimeMatrixParams() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public DvrpOfflineTravelTimeEstimator(TravelTime initialTT, TravelTime observedT
this.delimiter = delimiter;

alpha = travelTimeEstimationAlpha;
checkArgument(alpha > 0 && alpha <= 1, "travelTimeEstimationAlpha must be in (0,1]");
checkArgument(alpha >= 0 && alpha <= 1, "travelTimeEstimationAlpha must be in [0,1]");

linkTravelTimes = DvrpOfflineTravelTimes.convertToLinkTravelTimeMatrix(initialTT, network.getLinks().values(),
timeDiscretizer);
Expand All @@ -114,7 +114,9 @@ private int getIdx(double time) {

@Override
public void notifyMobsimBeforeCleanup(@SuppressWarnings("rawtypes") MobsimBeforeCleanupEvent e) {
updateTTs(observedTT, alpha);
if(alpha > 0) {
updateTTs(observedTT, alpha);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void install() {
addMobsimListenerBinding().to(DvrpOfflineTravelTimeEstimator.class);
addControlerListenerBinding().to(DvrpOfflineTravelTimeEstimator.class);

if (dvrpCfg.travelTimeEstimationBeta > 0) {// online estimation
if (dvrpCfg.travelTimeEstimationBeta > 0 && dvrpCfg.travelTimeEstimationAlpha > 0) {// online estimation
bind(DvrpOnlineTravelTimeEstimator.class).asEagerSingleton();
addMobsimListenerBinding().to(DvrpOnlineTravelTimeEstimator.class);
bind(DvrpTravelTimeEstimator.class).to(DvrpOnlineTravelTimeEstimator.class);
Expand Down
Loading

0 comments on commit afb0b48

Please sign in to comment.