Hi @Bhoumik_Shah,
Please kindly find below the code I implement the maxRouteDurationConstraint:
private static class maxRouteDurationConstraint implements HardActivityConstraint {
private final StateManager stateManager;
private final double maxRouteDuration;
private final VehicleRoutingTransportCosts routingCosts;
public maxRouteDurationConstraint(double maxRouteDuration, StateManager stateManager, VehicleRoutingTransportCosts routingCosts) {
this.maxRouteDuration = maxRouteDuration;
this.routingCosts = routingCosts;
this.stateManager = stateManager;
}
@Override
public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double depTimeAtPrevAct) {
Double oldDuration = iFacts.getRoute().getEnd().getArrTime() - iFacts.getRoute().getStart().getEndTime();
if (oldDuration > this.maxRouteDuration)
return ConstraintsStatus.NOT_FULFILLED_BREAK;
double tp_time_prevAct_newAct = this.routingCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct;
double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct);
double routeDurationIncrease;
if (nextAct instanceof End && !iFacts.getNewVehicle().isReturnToDepot()) {
routeDurationIncrease = newAct_endTime - depTimeAtPrevAct;
}
else {
double tp_time_newAct_nextAct = this.routingCosts.getTransportTime(newAct.getLocation(), nextAct.getLocation(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
double nextAct_arrTime = newAct_endTime + tp_time_newAct_nextAct;
double endTime_nextAct_new = CalculationUtils.getActivityEndTime(nextAct_arrTime, nextAct);
double arrTime_nextAct = depTimeAtPrevAct + this.routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle());
double endTime_nextAct_old = CalculationUtils.getActivityEndTime(arrTime_nextAct, nextAct);
double endTimeDelay_nextAct = Math.max(0.0D, endTime_nextAct_new - endTime_nextAct_old);
Double futureWaiting = this.stateManager.getActivityState(nextAct, iFacts.getRoute().getVehicle(), InternalStates.FUTURE_WAITING, Double.class);
if(futureWaiting == null) {
futureWaiting = Double.valueOf(0.0D);
}
routeDurationIncrease = Math.max(0, endTimeDelay_nextAct - futureWaiting);
}
Double newDuration = oldDuration + routeDurationIncrease;
if (newDuration > this.maxRouteDuration)
return ConstraintsStatus.NOT_FULFILLED;
else
return ConstraintsStatus.FULFILLED;
}
}
I tested it on a small test case and it worked fine.
Note that the way trip duration is defined in the code is different from what you said in an earlier comment, i.e., [quote=“Bhoumik_Shah, post:5, topic:758”]
Double oldDuration = context.getRoute().getEnd().getArrTime() - context.getRoute().getStart().getEndTime();
[/quote] is not the same as [quote=“Bhoumik_Shah, post:3, topic:758”]
startTimeofFirstActivity - EndTimeofLastActivity
[/quote] (well, this should be reversed, but you get the idea)
For the definition of trip duration as in the code, I think VehicleImpl/Builder/setLatestArrival should work - just define the vehicle latest arrival time = earliest start time + MaximumDuration.
Best regards,
He