Skip to content

Commit

Permalink
Add DRT detour constraints
Browse files Browse the repository at this point in the history
Based on the PR #2834
  • Loading branch information
luchengqi7 committed Dec 15, 2023
1 parent 47859fe commit 1b402e1
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.matsim.contrib.drt.optimizer.insertion;

import org.matsim.contrib.drt.passenger.DrtRequest;

/**
* This insertion cost calculator performs additional check on the maximum ride duration, on top of the original InsertionCostCalculator
* @author: Nico Kühnel (nkuehnel), Chengqi Lu (luchengqi7)
* */
public class MaxDetourInsertionCostCalculator implements InsertionCostCalculator {
private final InsertionCostCalculator delegate;

public MaxDetourInsertionCostCalculator(InsertionCostCalculator delegate) {
this.delegate = delegate;
}

@Override
public double calculate(DrtRequest drtRequest, InsertionGenerator.Insertion insertion, InsertionDetourTimeCalculator.DetourTimeInfo detourTimeInfo) {
if (violatesDetour(drtRequest, detourTimeInfo)) {
return INFEASIBLE_SOLUTION_COST;
}
return delegate.calculate(drtRequest, insertion, detourTimeInfo);
}

private boolean violatesDetour(DrtRequest drtRequest, InsertionDetourTimeCalculator.DetourTimeInfo detourTimeInfo) {
// Check if the max travel time constraint for the newly inserted request is violated
double rideDuration = detourTimeInfo.dropoffDetourInfo.arrivalTime - detourTimeInfo.pickupDetourInfo.departureTime;
return drtRequest.getMaxRideDuration() < rideDuration;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public static AcceptedDrtRequest createFromOriginalRequest(DrtRequest request) {
.earliestStartTime(request.getEarliestStartTime())
.latestStartTime(request.getLatestStartTime())
.latestArrivalTime(request.getLatestArrivalTime())
.maxRideDuration(request.getMaxRideDuration())
.build();
}

Expand All @@ -46,12 +47,14 @@ public static AcceptedDrtRequest createFromOriginalRequest(DrtRequest request) {
private final double earliestStartTime;
private final double latestStartTime;
private final double latestArrivalTime;
private final double maxRideDuration;

private AcceptedDrtRequest(Builder builder) {
request = builder.request;
earliestStartTime = builder.earliestStartTime;
latestStartTime = builder.latestStartTime;
latestArrivalTime = builder.latestArrivalTime;
maxRideDuration = builder.maxRideDuration;
}

public static Builder newBuilder() {
Expand All @@ -64,6 +67,7 @@ public static Builder newBuilder(AcceptedDrtRequest copy) {
builder.earliestStartTime = copy.getEarliestStartTime();
builder.latestStartTime = copy.getLatestStartTime();
builder.latestArrivalTime = copy.getLatestArrivalTime();
builder.maxRideDuration = copy.getMaxRideDuration();
return builder;
}

Expand All @@ -82,6 +86,9 @@ public double getLatestStartTime() {
public double getLatestArrivalTime() {
return latestArrivalTime;
}
public double getMaxRideDuration() {
return maxRideDuration;
}

public Id<Request> getId() {
return request.getId();
Expand Down Expand Up @@ -122,6 +129,7 @@ public static final class Builder {
private double earliestStartTime;
private double latestStartTime;
private double latestArrivalTime;
private double maxRideDuration;

private Builder() {
}
Expand All @@ -146,6 +154,11 @@ public Builder latestArrivalTime(double val) {
return this;
}

public Builder maxRideDuration(double val) {
this.maxRideDuration = val;
return this;
}

public AcceptedDrtRequest build() {
return new AcceptedDrtRequest(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class DrtRequest implements PassengerRequest {
private final double earliestStartTime;
private final double latestStartTime;
private final double latestArrivalTime;
private final double maxRideDuration;

private final List<Id<Person>> passengerIds = new ArrayList<>();
private final String mode;
Expand All @@ -52,6 +53,7 @@ private DrtRequest(Builder builder) {
earliestStartTime = builder.earliestStartTime;
latestStartTime = builder.latestStartTime;
latestArrivalTime = builder.latestArrivalTime;
maxRideDuration = builder.maxRideDuration;
passengerIds.addAll(builder.passengerIds);
mode = builder.mode;
fromLink = builder.fromLink;
Expand All @@ -69,6 +71,7 @@ public static Builder newBuilder(DrtRequest copy) {
builder.earliestStartTime = copy.getEarliestStartTime();
builder.latestStartTime = copy.getLatestStartTime();
builder.latestArrivalTime = copy.getLatestArrivalTime();
builder.maxRideDuration = copy.getMaxRideDuration();
builder.passengerIds = new ArrayList<>(copy.getPassengerIds());
builder.mode = copy.getMode();
builder.fromLink = copy.getFromLink();
Expand Down Expand Up @@ -100,6 +103,10 @@ public double getLatestArrivalTime() {
return latestArrivalTime;
}

public double getMaxRideDuration() {
return maxRideDuration;
}

@Override
public Link getFromLink() {
return fromLink;
Expand Down Expand Up @@ -133,6 +140,7 @@ public String toString() {
.add("earliestStartTime", earliestStartTime)
.add("latestStartTime", latestStartTime)
.add("latestArrivalTime", latestArrivalTime)
.add("maxRideDuration", maxRideDuration)
.add("passengerIds", passengerIds.stream().map(Object::toString).collect(Collectors.joining(",")))
.add("mode", mode)
.add("fromLink", fromLink)
Expand All @@ -146,6 +154,7 @@ public static final class Builder {
private double earliestStartTime;
private double latestStartTime;
private double latestArrivalTime;
private double maxRideDuration;
private List<Id<Person>> passengerIds = new ArrayList<>();
private String mode;
private Link fromLink;
Expand Down Expand Up @@ -179,6 +188,11 @@ public Builder latestArrivalTime(double val) {
return this;
}

public Builder maxRideDuration(double maxRideDuration) {
this.maxRideDuration = maxRideDuration;
return this;
}

public Builder passengerIds(List<Id<Person>> val) {
passengerIds = new ArrayList<>(val);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ public DrtRequest createRequest(Id<Request> id, List<Id<Person>> passengerIds, R
DrtRoute drtRoute = (DrtRoute)route;
double latestDepartureTime = departureTime + drtRoute.getMaxWaitTime();
double latestArrivalTime = departureTime + drtRoute.getTravelTime().seconds();
double maxRideDuration = drtRoute.getMaxRideTime();

eventsManager.processEvent(
new DrtRequestSubmittedEvent(submissionTime, mode, id, passengerIds, fromLink.getId(), toLink.getId(),
drtRoute.getDirectRideTime(), drtRoute.getDistance(), departureTime, latestDepartureTime, latestArrivalTime));
drtRoute.getDirectRideTime(), drtRoute.getDistance(), departureTime, latestDepartureTime, latestArrivalTime, maxRideDuration));

DrtRequest request = DrtRequest.newBuilder()
.id(id)
Expand All @@ -66,6 +67,7 @@ public DrtRequest createRequest(Id<Request> id, List<Id<Person>> passengerIds, R
.earliestStartTime(departureTime)
.latestStartTime(latestDepartureTime)
.latestArrivalTime(latestArrivalTime)
.maxRideDuration(maxRideDuration)
.submissionTime(submissionTime)
.build();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.matsim.contrib.drt.passenger;

import java.util.Optional;

public class MaxDetourOfferAcceptor implements DrtOfferAcceptor{
private final double promisedPickupTimeWindow;

public MaxDetourOfferAcceptor(double promisedPickupTimeWindow) {
this.promisedPickupTimeWindow = promisedPickupTimeWindow;
}

@Override
public Optional<AcceptedDrtRequest> acceptDrtOffer(DrtRequest request, double departureTime, double arrivalTime) {
double updatedPickupTimeWindow = Math.min(departureTime
+ promisedPickupTimeWindow, request.getLatestStartTime());
return Optional.of(AcceptedDrtRequest
.newBuilder()
.request(request)
.earliestStartTime(request.getEarliestStartTime())
.latestArrivalTime(Math.min(updatedPickupTimeWindow + request.getMaxRideDuration(), request.getLatestArrivalTime()))
.latestStartTime(updatedPickupTimeWindow).build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,26 @@ public class DrtRequestSubmittedEvent extends PassengerRequestSubmittedEvent {
public static final String ATTRIBUTE_EARLIEST_DEPARTURE_TIME = "earliestDepartureTime";
public static final String ATTRIBUTE_LATEST_PICKUP_TIME = "latestPickupTime";
public static final String ATTRIBUTE_LATEST_DROPOFF_TIME = "latestDropoffTime";
public static final String ATTRIBUTE_MAX_RIDE_DURATION = "maxRideDuration";

private final double unsharedRideTime;
private final double unsharedRideDistance;

private final double earliestDepartureTime;
private final double latestPickupTime;
private final double latestDropoffTime;
private final double maxRideDuration;

public DrtRequestSubmittedEvent(double time, String mode, Id<Request> requestId, List<Id<Person>> personIds,
Id<Link> fromLinkId, Id<Link> toLinkId, double unsharedRideTime, double unsharedRideDistance,
double earliestDepartureTime, double latestPickupTime, double latestDropoffTime) {
double earliestDepartureTime, double latestPickupTime, double latestDropoffTime, double maxRideDuration ) {
super(time, mode, requestId, personIds, fromLinkId, toLinkId);
this.unsharedRideTime = unsharedRideTime;
this.unsharedRideDistance = unsharedRideDistance;
this.earliestDepartureTime = earliestDepartureTime;
this.latestPickupTime = latestPickupTime;
this.latestDropoffTime = latestDropoffTime;
this.maxRideDuration = maxRideDuration;
}

@Override
Expand Down Expand Up @@ -90,6 +93,9 @@ public final double getLatestDropoffTime() {
return latestDropoffTime;
}

public double getMaxRideDuration() {
return maxRideDuration;
}
@Override
public Map<String, String> getAttributes() {
Map<String, String> attr = super.getAttributes();
Expand All @@ -98,6 +104,7 @@ public Map<String, String> getAttributes() {
attr.put(ATTRIBUTE_EARLIEST_DEPARTURE_TIME, earliestDepartureTime + "");
attr.put(ATTRIBUTE_LATEST_PICKUP_TIME, latestPickupTime + "");
attr.put(ATTRIBUTE_LATEST_DROPOFF_TIME, latestDropoffTime + "");
attr.put(ATTRIBUTE_MAX_RIDE_DURATION, maxRideDuration + "");
return attr;
}

Expand All @@ -118,7 +125,8 @@ public static DrtRequestSubmittedEvent convert(GenericEvent event) {
double earliestDepartureTime = Double.parseDouble(attributes.getOrDefault(ATTRIBUTE_EARLIEST_DEPARTURE_TIME, "NaN"));
double latestPickupTime = Double.parseDouble(attributes.getOrDefault(ATTRIBUTE_LATEST_PICKUP_TIME, "NaN"));
double latestDropoffTime = Double.parseDouble(attributes.getOrDefault(ATTRIBUTE_LATEST_DROPOFF_TIME, "NaN"));
double maxRideDuration = Double.parseDouble(attributes.getOrDefault(ATTRIBUTE_MAX_RIDE_DURATION, "NaN"));
return new DrtRequestSubmittedEvent(time, mode, requestId, personIds, fromLinkId, toLinkId, unsharedRideTime,
unsharedRideDistance, earliestDepartureTime, latestPickupTime, latestDropoffTime);
unsharedRideDistance, earliestDepartureTime, latestPickupTime, latestDropoffTime, maxRideDuration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ public double getMaxTravelTime() {
return getTravelTime().seconds(); // currently DrtRoute.travelTime is set to the max allowed travel time
}

public double getMaxRideTime() {
return routeDescription.getMaxRideTime();
}

public void setDirectRideTime(double directRideTime) {
this.routeDescription.setDirectRideTime(directRideTime);
}
Expand All @@ -86,6 +90,10 @@ public void setUnsharedPath(VrpPathWithTravelData unsharedPath) {
this.routeDescription.setUnsharedPath(links);
}

public void setMaxRideTime(double maxRideTime) {
this.routeDescription.setMaxRideTime(maxRideTime);
}


@Override
public String getRouteDescription() {
Expand Down Expand Up @@ -149,12 +157,18 @@ public static class RouteDescription {
private OptionalTime maxWaitTime = OptionalTime.undefined();
private OptionalTime directRideTime = OptionalTime.undefined();
private List<String> unsharedPath = new ArrayList<String>();
private OptionalTime maxRideTime = OptionalTime.undefined();

@JsonProperty("directRideTime")
public double getDirectRideTime() {
return directRideTime.isUndefined() ? OptionalTime.undefined().seconds() : directRideTime.seconds();
}

@JsonProperty("maxRideTime")
public double getMaxRideTime() {
return maxRideTime.seconds();
}

@JsonProperty("maxWaitTime")
public double getMaxWaitTime() {
return maxWaitTime.isUndefined() ? OptionalTime.undefined().seconds() : maxWaitTime.seconds();
Expand All @@ -169,13 +183,16 @@ public void setDirectRideTime(double directRideTime) {
this.directRideTime = OptionalTime.defined(directRideTime);
}

public void setMaxRideTime(double maxRideTime) {
this.maxRideTime = OptionalTime.defined(maxRideTime);
}

public void setMaxWaitTime(double maxWaitTime) {
this.maxWaitTime = OptionalTime.defined(maxWaitTime);
}

public void setUnsharedPath(List<String> unsharedPath) {
this.unsharedPath = unsharedPath;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,30 @@ static double getMaxTravelTime(DrtConfigGroup drtCfg, double unsharedRideTime) {
drtCfg.maxTravelTimeAlpha * unsharedRideTime + drtCfg.maxTravelTimeBeta);
}

/**
* Calculates the maximum ride time defined as: drtCfg.maxDetourAlpha * unsharedRideTime + drtCfg.maxDetourBeta
*
* @param drtCfg
* @param unsharedRideTime ride time of the direct (shortest-time) route
* @return maximum ride time
*/
static double getMaxRideTime(DrtConfigGroup drtCfg, double unsharedRideTime) {
return Math.min(unsharedRideTime + drtCfg.maxAbsoluteDetour, drtCfg.maxDetourAlpha * unsharedRideTime + drtCfg.maxDetourBeta);
}

public Route createRoute(double departureTime, Link accessActLink, Link egressActLink, Person person,
Attributes tripAttributes, RouteFactories routeFactories) {
VrpPathWithTravelData unsharedPath = VrpPaths.calcAndCreatePath(accessActLink, egressActLink, departureTime,
router, travelTime);
double unsharedRideTime = unsharedPath.getTravelTime();//includes first & last link
double maxTravelTime = getMaxTravelTime(drtCfg, unsharedRideTime);
double maxRideDuration = getMaxRideTime(drtCfg, unsharedRideTime);
double unsharedDistance = VrpPaths.calcDistance(unsharedPath);//includes last link

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,27 @@ public static DrtConfigGroup getSingleModeDrtConfig(Config config) {
@PositiveOrZero
public double maxAbsoluteDetour = Double.POSITIVE_INFINITY;// [s]

@Parameter
@Comment(
"Defines the maximum allowed absolute detour based on the unsharedRideTime. A linear combination similar to travel time constrain is used"
+ "This is the ratio part")
@DecimalMin("1.0")
public double maxDetourAlpha = Double.POSITIVE_INFINITY;

@Parameter
@Comment(
"Defines the maximum allowed absolute detour based on the unsharedRideTime. A linear combination similar to travel time constrain is used"
+ "This is the constant part")
@PositiveOrZero
public double maxDetourBeta = Double.POSITIVE_INFINITY;// [s]

@Parameter
@Comment(
"Defines the maximum delay allowed from the initial scheduled pick up time. Once a estimated pick up time is determined, the DRT optimizer"
+ "should try to keep this promise. By default, this limit is disabled. If enabled, a value between 120 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)."
Expand Down Expand Up @@ -250,7 +271,7 @@ private void initSingletonParameterSets() {
addDefinition(DrtRequestInsertionRetryParams.SET_NAME, DrtRequestInsertionRetryParams::new,
() -> drtRequestInsertionRetryParams,
params -> drtRequestInsertionRetryParams = (DrtRequestInsertionRetryParams)params);

//prebooking (optional)
addDefinition(PrebookingParams.SET_NAME, PrebookingParams::new,
() -> prebookingParams,
Expand Down
Loading

0 comments on commit 1b402e1

Please sign in to comment.