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:
parent
4172478abd
commit
954f2588a4
2 changed files with 45 additions and 9 deletions
|
|
@ -27,12 +27,15 @@ import jsprit.core.problem.misc.JobInsertionContext;
|
|||
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||
import jsprit.core.problem.solution.route.activity.End;
|
||||
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.vehicle.Vehicle;
|
||||
import jsprit.core.util.CalculationUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Calculator that calculates the best insertion position for a {@link Service}.
|
||||
*
|
||||
|
|
@ -108,6 +111,7 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
|
|||
|
||||
double bestCost = bestKnownCosts;
|
||||
additionalICostsAtRouteLevel += additionalAccessEgressCalculator.getCosts(insertionContext);
|
||||
TimeWindow bestTimeWindow = null;
|
||||
|
||||
/*
|
||||
generate new start and end for new vehicle
|
||||
|
|
@ -121,17 +125,28 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
|
|||
int actIndex = 0;
|
||||
boolean loopBroken = false;
|
||||
for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){
|
||||
ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
|
||||
if(status.equals(ConstraintsStatus.FULFILLED)){
|
||||
//from job2insert induced costs at activity level
|
||||
double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
|
||||
double additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
|
||||
if(additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts < bestCost){
|
||||
bestCost = additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts;
|
||||
insertionIndex = actIndex;
|
||||
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);
|
||||
if (status.equals(ConstraintsStatus.FULFILLED)) {
|
||||
//from job2insert induced costs at activity level
|
||||
double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
|
||||
double additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
|
||||
if (additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts < bestCost) {
|
||||
bestCost = additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
|
@ -141,6 +156,10 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
|
|||
actIndex++;
|
||||
}
|
||||
if(!loopBroken){
|
||||
Collection<TimeWindow> timeWindows = service.getTimeWindows(actArrTime);
|
||||
for(TimeWindow timeWindow : timeWindows) {
|
||||
|
||||
}
|
||||
ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, end, prevActStartTime);
|
||||
if(status.equals(ConstraintsStatus.FULFILLED)){
|
||||
double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, end, prevActStartTime);
|
||||
|
|
|
|||
|
|
@ -21,8 +21,11 @@ import jsprit.core.problem.Capacity;
|
|||
import jsprit.core.problem.Location;
|
||||
import jsprit.core.problem.Skills;
|
||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||
import jsprit.core.problem.solution.route.activity.TimeWindows;
|
||||
import jsprit.core.util.Coordinate;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Service implementation of a job.
|
||||
*
|
||||
|
|
@ -83,6 +86,8 @@ public class Service extends AbstractJob {
|
|||
|
||||
protected Location location;
|
||||
|
||||
protected TimeWindows timeWindows;
|
||||
|
||||
Builder(String id){
|
||||
this.id = id;
|
||||
}
|
||||
|
|
@ -111,6 +116,11 @@ public class Service extends AbstractJob {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setTimeWindows(TimeWindows timeWindows){
|
||||
this.timeWindows = timeWindows;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the serviceTime of this service.
|
||||
*
|
||||
|
|
@ -198,6 +208,8 @@ public class Service extends AbstractJob {
|
|||
|
||||
private final Location location;
|
||||
|
||||
private final TimeWindows timeWindowManager;
|
||||
|
||||
Service(Builder builder){
|
||||
id = builder.id;
|
||||
serviceTime = builder.serviceTime;
|
||||
|
|
@ -207,6 +219,11 @@ public class Service extends AbstractJob {
|
|||
skills = builder.skills;
|
||||
name = builder.name;
|
||||
location = builder.location;
|
||||
timeWindowManager = builder.timeWindows;
|
||||
}
|
||||
|
||||
public Collection<TimeWindow> getTimeWindows(double time){
|
||||
return timeWindowManager.getTimeWindows(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue