1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00
This commit is contained in:
James La 2019-09-26 02:16:33 +00:00 committed by GitHub
commit b79b0284f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -62,88 +62,94 @@ public class MaxTimeInVehicleConstraint implements HardActivityConstraint {
@Override
public ConstraintsStatus fulfilled(final JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
boolean newActIsPickup = newAct instanceof PickupActivity;
boolean newActIsDelivery = newAct instanceof DeliveryActivity;
try {
boolean newActIsPickup = newAct instanceof PickupActivity;
boolean newActIsDelivery = newAct instanceof DeliveryActivity;
/*
1. check whether insertion of new shipment satisfies own max-in-vehicle-constraint
2. check whether insertion of new shipment satisfies all other max-in-vehicle-constraints
*/
//************ 1. check whether insertion of new shipment satisfies own max-in-vehicle-constraint
double newActArrival = prevActDepTime + transportTime.getTransportTime(prevAct.getLocation(),newAct.getLocation(),prevActDepTime,iFacts.getNewDriver(),iFacts.getNewVehicle());
double newActStart = Math.max(newActArrival, newAct.getTheoreticalEarliestOperationStartTime());
double newActDeparture = newActStart + activityCosts.getActivityDuration(newAct, newActArrival, iFacts.getNewDriver(), iFacts.getNewVehicle());
double nextActArrival = newActDeparture + transportTime.getTransportTime(newAct.getLocation(),nextAct.getLocation(),newActDeparture,iFacts.getNewDriver(),iFacts.getNewVehicle());
double nextActStart = Math.max(nextActArrival,nextAct.getTheoreticalEarliestOperationStartTime());
if(newAct instanceof DeliveryActivity){
double pickupEnd;
if(iFacts.getAssociatedActivities().size() == 1){
pickupEnd = iFacts.getNewDepTime();
}
else {
pickupEnd = iFacts.getRelatedActivityContext().getEndTime();
}
double timeInVehicle = newActStart - pickupEnd;
double maxTimeInVehicle = ((TourActivity.JobActivity)newAct).getJob().getMaxTimeInVehicle();
if(timeInVehicle > maxTimeInVehicle) return ConstraintsStatus.NOT_FULFILLED;
/*
1. check whether insertion of new shipment satisfies own max-in-vehicle-constraint
2. check whether insertion of new shipment satisfies all other max-in-vehicle-constraints
*/
//************ 1. check whether insertion of new shipment satisfies own max-in-vehicle-constraint
double newActArrival = prevActDepTime + transportTime.getTransportTime(prevAct.getLocation(),newAct.getLocation(),prevActDepTime,iFacts.getNewDriver(),iFacts.getNewVehicle());
double newActStart = Math.max(newActArrival, newAct.getTheoreticalEarliestOperationStartTime());
double newActDeparture = newActStart + activityCosts.getActivityDuration(newAct, newActArrival, iFacts.getNewDriver(), iFacts.getNewVehicle());
double nextActArrival = newActDeparture + transportTime.getTransportTime(newAct.getLocation(),nextAct.getLocation(),newActDeparture,iFacts.getNewDriver(),iFacts.getNewVehicle());
double nextActStart = Math.max(nextActArrival,nextAct.getTheoreticalEarliestOperationStartTime());
if(newAct instanceof DeliveryActivity){
double pickupEnd;
if(iFacts.getAssociatedActivities().size() == 1){
pickupEnd = iFacts.getNewDepTime();
}
else {
pickupEnd = iFacts.getRelatedActivityContext().getEndTime();
}
double timeInVehicle = newActStart - pickupEnd;
double maxTimeInVehicle = ((TourActivity.JobActivity)newAct).getJob().getMaxTimeInVehicle();
if(timeInVehicle > maxTimeInVehicle) return ConstraintsStatus.NOT_FULFILLED;
}
else if(newActIsPickup){
if(iFacts.getAssociatedActivities().size() == 1){
double maxTimeInVehicle = ((TourActivity.JobActivity)newAct).getJob().getMaxTimeInVehicle();
//ToDo - estimate in vehicle time of pickups here - This seems to trickier than I thought
double nextActDeparture = nextActStart + activityCosts.getActivityDuration(nextAct, nextActArrival, iFacts.getNewDriver(), iFacts.getNewVehicle());
}
else if(newActIsPickup){
if(iFacts.getAssociatedActivities().size() == 1){
double maxTimeInVehicle = ((TourActivity.JobActivity)newAct).getJob().getMaxTimeInVehicle();
//ToDo - estimate in vehicle time of pickups here - This seems to trickier than I thought
double nextActDeparture = nextActStart + activityCosts.getActivityDuration(nextAct, nextActArrival, iFacts.getNewDriver(), iFacts.getNewVehicle());
// if(!nextAct instanceof End)
double timeToEnd = 0; //newAct.end + tt(newAct,nextAct) + t@nextAct + t_to_end
if(timeToEnd > maxTimeInVehicle) return ConstraintsStatus.NOT_FULFILLED;
}
}
double timeToEnd = 0; //newAct.end + tt(newAct,nextAct) + t@nextAct + t_to_end
if(timeToEnd > maxTimeInVehicle) return ConstraintsStatus.NOT_FULFILLED;
}
}
//************ 2. check whether insertion of new shipment satisfies all other max-in-vehicle-constraints
//************ 2. check whether insertion of new shipment satisfies all other max-in-vehicle-constraints
double minSlack = Double.MAX_VALUE;
if (!(nextAct instanceof End)) {
minSlack = stateManager.getActivityState(nextAct, iFacts.getNewVehicle(), minSlackId, Double.class);
}
double directArrTimeNextAct = prevActDepTime + transportTime.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
double directNextActStart = Math.max(directArrTimeNextAct, nextAct.getTheoreticalEarliestOperationStartTime());
double additionalTimeOfNewAct = (nextActStart - prevActDepTime) - (directNextActStart - prevActDepTime);
if (additionalTimeOfNewAct > minSlack) {
if (newActIsPickup) return ConstraintsStatus.NOT_FULFILLED;
else return ConstraintsStatus.NOT_FULFILLED;
}
if (newActIsDelivery) {
Map<Job, Double> openJobsAtNext;
if (nextAct instanceof End)
openJobsAtNext = stateManager.getRouteState(iFacts.getRoute(), iFacts.getNewVehicle(), openJobsId, Map.class);
else openJobsAtNext = stateManager.getActivityState(nextAct, iFacts.getNewVehicle(), openJobsId, Map.class);
if (openJobsAtNext == null) openJobsAtNext = Collections.emptyMap();
for (Job openJob : openJobsAtNext.keySet()) {
double slack = openJobsAtNext.get(openJob);
double additionalTimeOfNewJob = additionalTimeOfNewAct;
if (openJob instanceof Shipment) {
Map<Job, Double> openJobsAtNextOfPickup = Collections.emptyMap();
TourActivity nextAfterPickup;
if (iFacts.getAssociatedActivities().size() == 1 && !iFacts.getRoute().isEmpty())
nextAfterPickup = iFacts.getRoute().getActivities().get(0);
else
nextAfterPickup = iFacts.getRoute().getActivities().get(iFacts.getRelatedActivityContext().getInsertionIndex());
if (nextAfterPickup != null)
openJobsAtNextOfPickup = stateManager.getActivityState(nextAfterPickup, iFacts.getNewVehicle(), openJobsId, Map.class);
if (openJobsAtNextOfPickup.containsKey(openJob)) {
TourActivity pickupAct = iFacts.getAssociatedActivities().get(0);
double pickupActArrTime = iFacts.getRelatedActivityContext().getArrivalTime();
double pickupActEndTime = startOf(pickupAct, pickupActArrTime) + activityCosts.getActivityDuration(pickupAct, pickupActArrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
double nextAfterPickupArr = pickupActEndTime + transportTime.getTransportTime(pickupAct.getLocation(), nextAfterPickup.getLocation(), pickupActArrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
additionalTimeOfNewJob += startOf(nextAfterPickup, nextAfterPickupArr) - startOf(nextAfterPickup, nextAfterPickup.getArrTime());
}
}
if (additionalTimeOfNewJob > slack) {
return ConstraintsStatus.NOT_FULFILLED;
}
}
}
return ConstraintsStatus.FULFILLED;
double minSlack = Double.MAX_VALUE;
if (!(nextAct instanceof End)) {
minSlack = stateManager.getActivityState(nextAct, iFacts.getNewVehicle(), minSlackId, Double.class);
}
double directArrTimeNextAct = prevActDepTime + transportTime.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
double directNextActStart = Math.max(directArrTimeNextAct, nextAct.getTheoreticalEarliestOperationStartTime());
double additionalTimeOfNewAct = (nextActStart - prevActDepTime) - (directNextActStart - prevActDepTime);
if (additionalTimeOfNewAct > minSlack) {
if (newActIsPickup) return ConstraintsStatus.NOT_FULFILLED;
else return ConstraintsStatus.NOT_FULFILLED;
}
if (newActIsDelivery) {
Map<Job, Double> openJobsAtNext;
if (nextAct instanceof End)
openJobsAtNext = stateManager.getRouteState(iFacts.getRoute(), iFacts.getNewVehicle(), openJobsId, Map.class);
else openJobsAtNext = stateManager.getActivityState(nextAct, iFacts.getNewVehicle(), openJobsId, Map.class);
if (openJobsAtNext == null) openJobsAtNext = Collections.emptyMap();
for (Job openJob : openJobsAtNext.keySet()) {
double slack = openJobsAtNext.get(openJob);
double additionalTimeOfNewJob = additionalTimeOfNewAct;
if (openJob instanceof Shipment) {
Map<Job, Double> openJobsAtNextOfPickup = Collections.emptyMap();
TourActivity nextAfterPickup;
if (iFacts.getAssociatedActivities().size() == 1 && !iFacts.getRoute().isEmpty())
nextAfterPickup = iFacts.getRoute().getActivities().get(0);
else
nextAfterPickup = iFacts.getRoute().getActivities().get(iFacts.getRelatedActivityContext().getInsertionIndex());
if (nextAfterPickup != null)
openJobsAtNextOfPickup = stateManager.getActivityState(nextAfterPickup, iFacts.getNewVehicle(), openJobsId, Map.class);
if (openJobsAtNextOfPickup.containsKey(openJob)) {
TourActivity pickupAct = iFacts.getAssociatedActivities().get(0);
double pickupActArrTime = iFacts.getRelatedActivityContext().getArrivalTime();
double pickupActEndTime = startOf(pickupAct, pickupActArrTime) + activityCosts.getActivityDuration(pickupAct, pickupActArrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
double nextAfterPickupArr = pickupActEndTime + transportTime.getTransportTime(pickupAct.getLocation(), nextAfterPickup.getLocation(), pickupActArrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
additionalTimeOfNewJob += startOf(nextAfterPickup, nextAfterPickupArr) - startOf(nextAfterPickup, nextAfterPickup.getArrTime());
}
}
if (additionalTimeOfNewJob > slack) {
return ConstraintsStatus.NOT_FULFILLED;
}
}
}
return ConstraintsStatus.FULFILLED;
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
return ConstraintsStatus.NOT_FULFILLED;
}
}
private double startOf(TourActivity act, double arrTime) {