Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DRT detour constraints (based on PR #2834) #2997

Merged
merged 15 commits into from
Jan 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,31 @@ public DefaultInsertionCostCalculator(CostCalculationStrategy costCalculationStr
*/
@Override
public double calculate(DrtRequest drtRequest, Insertion insertion, DetourTimeInfo detourTimeInfo) {
// check if the max riding time constraints is violated (with default config, the max ride duration
// is infinity)
if (violatesMaxRideDuration(drtRequest, detourTimeInfo)) {
return INFEASIBLE_SOLUTION_COST;
}

var vEntry = insertion.vehicleEntry;

// in case of prebooking, we may have intermediate stay times after pickup
// insertion that may reduce the effective pickup delay that remains that the
// dropoff insertion point
double effectiveDropoffTimeLoss = InsertionDetourTimeCalculator.calculateRemainingPickupTimeLossAtDropoff(
insertion, detourTimeInfo.pickupDetourInfo) + detourTimeInfo.dropoffDetourInfo.dropoffTimeLoss;

if (vEntry.getSlackTime(insertion.pickup.index) < detourTimeInfo.pickupDetourInfo.pickupTimeLoss
|| vEntry.getSlackTime(insertion.dropoff.index) < effectiveDropoffTimeLoss) {
return INFEASIBLE_SOLUTION_COST;
}

return costCalculationStrategy.calcCost(drtRequest, insertion, detourTimeInfo);
}

private boolean violatesMaxRideDuration(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
@@ -0,0 +1,33 @@
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)
*
* The function is now implemented in the DefaultInsertionCostCalculator
* */
@Deprecated
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 @@ -126,6 +133,7 @@ public static final class Builder {
private double earliestStartTime;
private double latestStartTime;
private double latestArrivalTime;
private double maxRideDuration;

private Builder() {
}
Expand All @@ -150,6 +158,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 maxAllowedPickupDelay;

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

@Override
public Optional<AcceptedDrtRequest> acceptDrtOffer(DrtRequest request, double departureTime, double arrivalTime) {
double updatedLatestStartTime = Math.min(departureTime
+ maxAllowedPickupDelay, request.getLatestStartTime());
return Optional.of(AcceptedDrtRequest
.newBuilder()
.request(request)
.earliestStartTime(request.getEarliestStartTime())
.latestArrivalTime(Math.min(updatedLatestStartTime + request.getMaxRideDuration(), request.getLatestArrivalTime()))
.latestStartTime(updatedLatestStartTime).build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

/**
* @author nkuehnel / MOIA
* The function is now realized by the MaxDetourOfferAcceptor -Chengqi (luchengqi7)
*/
@Deprecated
public final class PromisedPickupTimeWindowDrtOfferAcceptor implements DrtOfferAcceptor {
private final double promisedPickupTimeWindow;

Expand Down
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 @@ -61,8 +61,18 @@ public DrtRouteCreator(DrtConfigGroup drtCfg, Network modalNetwork,
* @return maximum travel time
*/
static double getMaxTravelTime(DrtConfigGroup drtCfg, double unsharedRideTime) {
return Math.min(unsharedRideTime + drtCfg.maxAbsoluteDetour,
drtCfg.maxTravelTimeAlpha * unsharedRideTime + drtCfg.maxTravelTimeBeta);
return 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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if we should use unsharedRideTime + drtCfg.maxAbsoluteDetour in both getMaxTravelTime() and getMaxRideTime().

Imposing this constraint on maxTravelTime implies it is also imposed on maxRideTime, because maxTravelTime >= maxRideTime.

}

public Route createRoute(double departureTime, Link accessActLink, Link egressActLink, Person person,
Expand All @@ -71,11 +81,13 @@ public Route createRoute(double departureTime, Link accessActLink, Link egressAc
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
Loading
Loading