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.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,6 +125,12 @@ 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
|
||||||
|
|
@ -129,9 +139,14 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
|
||||||
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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue