1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

add multiple time windows

This commit is contained in:
oblonski 2015-05-25 23:35:58 +02:00
parent 4172478abd
commit 954f2588a4
2 changed files with 45 additions and 9 deletions

View file

@ -27,12 +27,15 @@ import jsprit.core.problem.misc.JobInsertionContext;
import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.solution.route.activity.End; import jsprit.core.problem.solution.route.activity.End;
import jsprit.core.problem.solution.route.activity.Start; import jsprit.core.problem.solution.route.activity.Start;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.solution.route.activity.TourActivity;
import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.util.CalculationUtils; import jsprit.core.util.CalculationUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.util.Collection;
/** /**
* Calculator that calculates the best insertion position for a {@link Service}. * Calculator that calculates the best insertion position for a {@link Service}.
* *
@ -108,6 +111,7 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
double bestCost = bestKnownCosts; double bestCost = bestKnownCosts;
additionalICostsAtRouteLevel += additionalAccessEgressCalculator.getCosts(insertionContext); additionalICostsAtRouteLevel += additionalAccessEgressCalculator.getCosts(insertionContext);
TimeWindow bestTimeWindow = null;
/* /*
generate new start and end for new vehicle generate new start and end for new vehicle
@ -121,17 +125,28 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
int actIndex = 0; int actIndex = 0;
boolean loopBroken = false; boolean loopBroken = false;
for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){ for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){
double actArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(),deliveryAct2Insert.getLocation(),prevActStartTime,newDriver,newVehicle);
Collection<TimeWindow> timeWindows = service.getTimeWindows(actArrTime);
boolean not_fulfilled_break = true;
for(TimeWindow timeWindow : timeWindows) {
deliveryAct2Insert.setTheoreticalEarliestStart(timeWindow.getStart());
deliveryAct2Insert.setTheoreticalLatestStart(timeWindow.getEnd());
ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
if(status.equals(ConstraintsStatus.FULFILLED)){ if (status.equals(ConstraintsStatus.FULFILLED)) {
//from job2insert induced costs at activity level //from job2insert induced costs at activity level
double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
double additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); double additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
if(additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts < bestCost){ if (additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts < bestCost) {
bestCost = additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts; bestCost = additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts;
insertionIndex = actIndex; insertionIndex = actIndex;
bestTimeWindow = timeWindow;
}
not_fulfilled_break = false;
} else if (status.equals(ConstraintsStatus.NOT_FULFILLED)) {
not_fulfilled_break = false;
} }
} }
else if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){ if(not_fulfilled_break){
loopBroken = true; loopBroken = true;
break; break;
} }
@ -141,6 +156,10 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
actIndex++; actIndex++;
} }
if(!loopBroken){ if(!loopBroken){
Collection<TimeWindow> timeWindows = service.getTimeWindows(actArrTime);
for(TimeWindow timeWindow : timeWindows) {
}
ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, end, prevActStartTime); ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, end, prevActStartTime);
if(status.equals(ConstraintsStatus.FULFILLED)){ if(status.equals(ConstraintsStatus.FULFILLED)){
double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, end, prevActStartTime); double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, end, prevActStartTime);

View file

@ -21,8 +21,11 @@ import jsprit.core.problem.Capacity;
import jsprit.core.problem.Location; import jsprit.core.problem.Location;
import jsprit.core.problem.Skills; import jsprit.core.problem.Skills;
import jsprit.core.problem.solution.route.activity.TimeWindow; import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.problem.solution.route.activity.TimeWindows;
import jsprit.core.util.Coordinate; import jsprit.core.util.Coordinate;
import java.util.Collection;
/** /**
* Service implementation of a job. * Service implementation of a job.
* *
@ -83,6 +86,8 @@ public class Service extends AbstractJob {
protected Location location; protected Location location;
protected TimeWindows timeWindows;
Builder(String id){ Builder(String id){
this.id = id; this.id = id;
} }
@ -111,6 +116,11 @@ public class Service extends AbstractJob {
return this; return this;
} }
public Builder setTimeWindows(TimeWindows timeWindows){
this.timeWindows = timeWindows;
return this;
}
/** /**
* Sets the serviceTime of this service. * Sets the serviceTime of this service.
* *
@ -198,6 +208,8 @@ public class Service extends AbstractJob {
private final Location location; private final Location location;
private final TimeWindows timeWindowManager;
Service(Builder builder){ Service(Builder builder){
id = builder.id; id = builder.id;
serviceTime = builder.serviceTime; serviceTime = builder.serviceTime;
@ -207,6 +219,11 @@ public class Service extends AbstractJob {
skills = builder.skills; skills = builder.skills;
name = builder.name; name = builder.name;
location = builder.location; location = builder.location;
timeWindowManager = builder.timeWindows;
}
public Collection<TimeWindow> getTimeWindows(double time){
return timeWindowManager.getTimeWindows(time);
} }
@Override @Override