mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
add multiple time windows to services
This commit is contained in:
parent
954f2588a4
commit
7582c5e038
13 changed files with 278 additions and 51 deletions
|
|
@ -35,6 +35,7 @@ import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculator that calculates the best insertion position for a {@link Service}.
|
* Calculator that calculates the best insertion position for a {@link Service}.
|
||||||
|
|
@ -123,14 +124,21 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
|
||||||
TourActivity prevAct = start;
|
TourActivity prevAct = start;
|
||||||
double prevActStartTime = newVehicleDepartureTime;
|
double prevActStartTime = newVehicleDepartureTime;
|
||||||
int actIndex = 0;
|
int actIndex = 0;
|
||||||
boolean loopBroken = false;
|
Iterator<TourActivity> activityIterator = currentRoute.getActivities().iterator();
|
||||||
for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){
|
boolean tourEnd = false;
|
||||||
|
while(!tourEnd){
|
||||||
|
TourActivity nextAct;
|
||||||
|
if(activityIterator.hasNext()) nextAct = activityIterator.next();
|
||||||
|
else{
|
||||||
|
nextAct = end;
|
||||||
|
tourEnd = true;
|
||||||
|
}
|
||||||
double actArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(),deliveryAct2Insert.getLocation(),prevActStartTime,newDriver,newVehicle);
|
double actArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(),deliveryAct2Insert.getLocation(),prevActStartTime,newDriver,newVehicle);
|
||||||
Collection<TimeWindow> timeWindows = service.getTimeWindows(actArrTime);
|
Collection<TimeWindow> timeWindows = service.getTimeWindows(actArrTime);
|
||||||
boolean not_fulfilled_break = true;
|
boolean not_fulfilled_break = true;
|
||||||
for(TimeWindow timeWindow : timeWindows) {
|
for(TimeWindow timeWindow : timeWindows) {
|
||||||
deliveryAct2Insert.setTheoreticalEarliestStart(timeWindow.getStart());
|
deliveryAct2Insert.setTheoreticalEarliestOperationStartTime(timeWindow.getStart());
|
||||||
deliveryAct2Insert.setTheoreticalLatestStart(timeWindow.getEnd());
|
deliveryAct2Insert.setTheoreticalLatestOperationStartTime(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
|
||||||
|
|
@ -146,34 +154,18 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
|
||||||
not_fulfilled_break = false;
|
not_fulfilled_break = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(not_fulfilled_break){
|
if(not_fulfilled_break) break;
|
||||||
loopBroken = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActStartTime, newDriver, newVehicle);
|
double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActStartTime, newDriver, newVehicle);
|
||||||
prevActStartTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct);
|
prevActStartTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct);
|
||||||
prevAct = nextAct;
|
prevAct = nextAct;
|
||||||
actIndex++;
|
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);
|
|
||||||
double additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, end, deliveryAct2Insert, prevActStartTime);
|
|
||||||
if(additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts < bestCost){
|
|
||||||
bestCost = additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts;
|
|
||||||
insertionIndex = actIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(insertionIndex == InsertionData.NO_INDEX) {
|
if(insertionIndex == InsertionData.NO_INDEX) {
|
||||||
return InsertionData.createEmptyInsertionData();
|
return InsertionData.createEmptyInsertionData();
|
||||||
}
|
}
|
||||||
InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver);
|
InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver);
|
||||||
|
deliveryAct2Insert.setTheoreticalEarliestOperationStartTime(bestTimeWindow.getStart());
|
||||||
|
deliveryAct2Insert.setTheoreticalLatestOperationStartTime(bestTimeWindow.getEnd());
|
||||||
insertionData.getEvents().add(new InsertActivity(currentRoute,newVehicle,deliveryAct2Insert,insertionIndex));
|
insertionData.getEvents().add(new InsertActivity(currentRoute,newVehicle,deliveryAct2Insert,insertionIndex));
|
||||||
insertionData.getEvents().add(new SwitchVehicle(currentRoute,newVehicle,newVehicleDepartureTime));
|
insertionData.getEvents().add(new SwitchVehicle(currentRoute,newVehicle,newVehicleDepartureTime));
|
||||||
insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
|
insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ 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.problem.solution.route.activity.TimeWindows;
|
||||||
|
import jsprit.core.problem.solution.route.activity.TimeWindowsImpl;
|
||||||
import jsprit.core.util.Coordinate;
|
import jsprit.core.util.Coordinate;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
@ -86,10 +87,14 @@ public class Service extends AbstractJob {
|
||||||
|
|
||||||
protected Location location;
|
protected Location location;
|
||||||
|
|
||||||
protected TimeWindows timeWindows;
|
protected TimeWindows timeWindows = new TimeWindowsImpl();
|
||||||
|
|
||||||
|
private boolean twAdded = false;
|
||||||
|
|
||||||
Builder(String id){
|
Builder(String id){
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
timeWindows = new TimeWindowsImpl();
|
||||||
|
((TimeWindowsImpl)timeWindows).add(timeWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -163,9 +168,33 @@ public class Service extends AbstractJob {
|
||||||
public Builder setTimeWindow(TimeWindow tw){
|
public Builder setTimeWindow(TimeWindow tw){
|
||||||
if(tw == null) throw new IllegalArgumentException("time-window arg must not be null");
|
if(tw == null) throw new IllegalArgumentException("time-window arg must not be null");
|
||||||
this.timeWindow = tw;
|
this.timeWindow = tw;
|
||||||
|
this.timeWindows = new TimeWindowsImpl();
|
||||||
|
((TimeWindowsImpl) timeWindows).add(tw);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder addTimeWindow(TimeWindow timeWindow) {
|
||||||
|
if(timeWindow == null) throw new IllegalArgumentException("time-window arg must not be null");
|
||||||
|
if(!twAdded){
|
||||||
|
timeWindows = new TimeWindowsImpl();
|
||||||
|
twAdded = true;
|
||||||
|
}
|
||||||
|
for(TimeWindow tw : ((TimeWindowsImpl)timeWindows).getTimeWindows()){
|
||||||
|
if(timeWindow.getStart() > tw.getStart() && timeWindow.getStart() < tw.getEnd()){
|
||||||
|
throw new IllegalStateException("time-windows cannot overlap each other. overlap: " + tw + ", " + timeWindow);
|
||||||
|
}
|
||||||
|
if(timeWindow.getEnd() > tw.getStart() && timeWindow.getEnd() < tw.getEnd()){
|
||||||
|
throw new IllegalStateException("time-windows cannot overlap each other. overlap: " + tw + ", " + timeWindow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
((TimeWindowsImpl) timeWindows).add(timeWindow);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder addTimeWindow(double earliest, double latest) {
|
||||||
|
return addTimeWindow(TimeWindow.newInstance(earliest, latest));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the service.
|
* Builds the service.
|
||||||
*
|
*
|
||||||
|
|
@ -189,6 +218,9 @@ public class Service extends AbstractJob {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -222,8 +254,8 @@ public class Service extends AbstractJob {
|
||||||
timeWindowManager = builder.timeWindows;
|
timeWindowManager = builder.timeWindows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<TimeWindow> getTimeWindows(double time){
|
public Collection<TimeWindow> getTimeWindows(double arrTime){
|
||||||
return timeWindowManager.getTimeWindows(time);
|
return timeWindowManager.getTimeWindows(arrTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc
|
||||||
|
|
||||||
private double endTime;
|
private double endTime;
|
||||||
|
|
||||||
|
private double theoreticalEarliest;
|
||||||
|
|
||||||
|
private double theoreticalLatest;
|
||||||
|
|
||||||
public DeliverService(Delivery delivery) {
|
public DeliverService(Delivery delivery) {
|
||||||
super();
|
super();
|
||||||
this.delivery = delivery;
|
this.delivery = delivery;
|
||||||
|
|
@ -41,10 +45,22 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc
|
||||||
this.delivery=deliveryActivity.getJob();
|
this.delivery=deliveryActivity.getJob();
|
||||||
this.arrTime=deliveryActivity.getArrTime();
|
this.arrTime=deliveryActivity.getArrTime();
|
||||||
this.endTime=deliveryActivity.getEndTime();
|
this.endTime=deliveryActivity.getEndTime();
|
||||||
|
this.theoreticalEarliest = deliveryActivity.getTheoreticalEarliestOperationStartTime();
|
||||||
|
this.theoreticalLatest = deliveryActivity.getTheoreticalLatestOperationStartTime();
|
||||||
capacity = deliveryActivity.getSize();
|
capacity = deliveryActivity.getSize();
|
||||||
setIndex(deliveryActivity.getIndex());
|
setIndex(deliveryActivity.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTheoreticalEarliestOperationStartTime(double earliest) {
|
||||||
|
theoreticalEarliest = earliest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTheoreticalLatestOperationStartTime(double latest) {
|
||||||
|
theoreticalLatest = latest;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return delivery.getType();
|
return delivery.getType();
|
||||||
|
|
@ -62,12 +78,12 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getTheoreticalEarliestOperationStartTime() {
|
public double getTheoreticalEarliestOperationStartTime() {
|
||||||
return delivery.getTimeWindow().getStart();
|
return theoreticalEarliest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getTheoreticalLatestOperationStartTime() {
|
public double getTheoreticalLatestOperationStartTime() {
|
||||||
return delivery.getTimeWindow().getEnd();
|
return theoreticalLatest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,16 @@ public final class DeliverShipment extends AbstractActivity implements DeliveryA
|
||||||
return shipment;
|
return shipment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTheoreticalEarliestOperationStartTime(double earliest) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTheoreticalLatestOperationStartTime(double latest) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "deliverShipment";
|
return "deliverShipment";
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,7 @@ public final class End extends AbstractActivity implements TourActivity {
|
||||||
+ "][twEnd=" + Activities.round(theoretical_latestOperationStartTime) + "]";
|
+ "][twEnd=" + Activities.round(theoretical_latestOperationStartTime) + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "end";
|
return "end";
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@ public final class PickupService extends AbstractActivity implements PickupActiv
|
||||||
|
|
||||||
private double depTime;
|
private double depTime;
|
||||||
|
|
||||||
|
private double theoreticalEarliest;
|
||||||
|
|
||||||
|
private double theoreticalLatest;
|
||||||
|
|
||||||
public PickupService(Pickup pickup) {
|
public PickupService(Pickup pickup) {
|
||||||
super();
|
super();
|
||||||
this.pickup = pickup;
|
this.pickup = pickup;
|
||||||
|
|
@ -43,9 +47,21 @@ public final class PickupService extends AbstractActivity implements PickupActiv
|
||||||
this.pickup=pickupActivity.getJob();
|
this.pickup=pickupActivity.getJob();
|
||||||
this.arrTime=pickupActivity.getArrTime();
|
this.arrTime=pickupActivity.getArrTime();
|
||||||
this.depTime=pickupActivity.getEndTime();
|
this.depTime=pickupActivity.getEndTime();
|
||||||
|
this.theoreticalEarliest = pickupActivity.getTheoreticalEarliestOperationStartTime();
|
||||||
|
this.theoreticalLatest = pickupActivity.getTheoreticalLatestOperationStartTime();
|
||||||
setIndex(pickupActivity.getIndex());
|
setIndex(pickupActivity.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTheoreticalEarliestOperationStartTime(double earliest) {
|
||||||
|
this.theoreticalEarliest = earliest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTheoreticalLatestOperationStartTime(double latest) {
|
||||||
|
this.theoreticalLatest = latest;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return pickup.getType();
|
return pickup.getType();
|
||||||
|
|
@ -63,12 +79,12 @@ public final class PickupService extends AbstractActivity implements PickupActiv
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getTheoreticalEarliestOperationStartTime() {
|
public double getTheoreticalEarliestOperationStartTime() {
|
||||||
return pickup.getTimeWindow().getStart();
|
return theoreticalEarliest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getTheoreticalLatestOperationStartTime() {
|
public double getTheoreticalLatestOperationStartTime() {
|
||||||
return pickup.getTimeWindow().getEnd();
|
return theoreticalLatest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,16 @@ public final class PickupShipment extends AbstractActivity implements PickupActi
|
||||||
return shipment;
|
return shipment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTheoreticalEarliestOperationStartTime(double earliest) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTheoreticalLatestOperationStartTime(double latest) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "pickupShipment";
|
return "pickupShipment";
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,16 @@ import jsprit.core.problem.solution.route.activity.TourActivity.JobActivity;
|
||||||
|
|
||||||
public class ServiceActivity extends AbstractActivity implements JobActivity{
|
public class ServiceActivity extends AbstractActivity implements JobActivity{
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static int counter = 0;
|
public static int counter = 0;
|
||||||
|
|
||||||
public double arrTime;
|
public double arrTime;
|
||||||
|
|
||||||
public double endTime;
|
public double endTime;
|
||||||
|
|
||||||
|
private double theoreticalEarliest;
|
||||||
|
|
||||||
|
private double theoreticalLatest;
|
||||||
/**
|
/**
|
||||||
* @return the arrTime
|
* @return the arrTime
|
||||||
*/
|
*/
|
||||||
|
|
@ -115,11 +119,11 @@ public class ServiceActivity extends AbstractActivity implements JobActivity{
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTheoreticalEarliestOperationStartTime() {
|
public double getTheoreticalEarliestOperationStartTime() {
|
||||||
return service.getTimeWindow().getStart();
|
return theoreticalEarliest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTheoreticalLatestOperationStartTime() {
|
public double getTheoreticalLatestOperationStartTime() {
|
||||||
return service.getTimeWindow().getEnd();
|
return theoreticalLatest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -152,6 +156,16 @@ public class ServiceActivity extends AbstractActivity implements JobActivity{
|
||||||
+ "][twEnd=" + Activities.round(getTheoreticalLatestOperationStartTime()) + "]";
|
+ "][twEnd=" + Activities.round(getTheoreticalLatestOperationStartTime()) + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTheoreticalEarliestOperationStartTime(double earliest) {
|
||||||
|
theoreticalEarliest = earliest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTheoreticalLatestOperationStartTime(double latest) {
|
||||||
|
theoreticalLatest = latest;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return service.getType();
|
return service.getType();
|
||||||
|
|
|
||||||
|
|
@ -93,10 +93,12 @@ public final class Start extends AbstractActivity implements TourActivity {
|
||||||
return theoretical_latestOperationStartTime;
|
return theoretical_latestOperationStartTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void setTheoreticalEarliestOperationStartTime(double time) {
|
public void setTheoreticalEarliestOperationStartTime(double time) {
|
||||||
this.theoretical_earliestOperationStartTime=time;
|
this.theoretical_earliestOperationStartTime=time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void setTheoreticalLatestOperationStartTime(double time) {
|
public void setTheoreticalLatestOperationStartTime(double time) {
|
||||||
this.theoretical_latestOperationStartTime=time;
|
this.theoretical_latestOperationStartTime=time;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package jsprit.core.problem.solution.route.activity;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 26/05/15.
|
||||||
|
*/
|
||||||
|
public class TimeWindowsImpl implements TimeWindows {
|
||||||
|
|
||||||
|
private Collection<TimeWindow> timeWindows = new ArrayList<TimeWindow>();
|
||||||
|
|
||||||
|
public void add(TimeWindow timeWindow){
|
||||||
|
timeWindows.add(timeWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<TimeWindow> getTimeWindows() {
|
||||||
|
return Collections.unmodifiableCollection(timeWindows);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<TimeWindow> getTimeWindows(double time) {
|
||||||
|
return Collections.unmodifiableCollection(timeWindows);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -31,6 +31,10 @@ import jsprit.core.problem.job.Job;
|
||||||
*/
|
*/
|
||||||
public interface TourActivity extends HasIndex {
|
public interface TourActivity extends HasIndex {
|
||||||
|
|
||||||
|
public void setTheoreticalEarliestOperationStartTime(double earliest);
|
||||||
|
|
||||||
|
public void setTheoreticalLatestOperationStartTime(double latest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic interface of job-activies.
|
* Basic interface of job-activies.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
package jsprit.core.algorithm;
|
||||||
|
|
||||||
|
import jsprit.core.algorithm.box.Jsprit;
|
||||||
|
import jsprit.core.problem.Location;
|
||||||
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import jsprit.core.problem.job.Service;
|
||||||
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
|
import jsprit.core.util.Solutions;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 26/05/15.
|
||||||
|
*/
|
||||||
|
public class MultipleTimeWindowsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void service2ShouldNotBeInserted(){
|
||||||
|
Service s = Service.Builder.newInstance("s1").setLocation(Location.newInstance(10,0)).build();
|
||||||
|
|
||||||
|
Service s2 = Service.Builder.newInstance("s2")
|
||||||
|
.addTimeWindow(50.,60.)
|
||||||
|
.setLocation(Location.newInstance(20, 0)).build();
|
||||||
|
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(0,0))
|
||||||
|
.setEarliestStart(0.).setLatestArrival(40).build();
|
||||||
|
|
||||||
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(s).addJob(s2).addVehicle(v).build();
|
||||||
|
VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(vrp);
|
||||||
|
algorithm.setMaxIterations(100);
|
||||||
|
VehicleRoutingProblemSolution solution = Solutions.bestOf(algorithm.searchSolutions());
|
||||||
|
|
||||||
|
Assert.assertEquals(1,solution.getUnassignedJobs().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void service2ShouldBeInsertedIntoNewVehicle(){
|
||||||
|
Service s = Service.Builder.newInstance("s1").setLocation(Location.newInstance(10,0))
|
||||||
|
.addTimeWindow(5.,15.).build();
|
||||||
|
|
||||||
|
Service s2 = Service.Builder.newInstance("s2")
|
||||||
|
.addTimeWindow(50.,60.)
|
||||||
|
.setLocation(Location.newInstance(20, 0)).build();
|
||||||
|
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(0,0))
|
||||||
|
.setEarliestStart(0.).setLatestArrival(40).build();
|
||||||
|
|
||||||
|
VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2").setStartLocation(Location.newInstance(0,0))
|
||||||
|
.setEarliestStart(40.).setLatestArrival(80).build();
|
||||||
|
|
||||||
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(s).addJob(s2).addVehicle(v).addVehicle(v2).build();
|
||||||
|
VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(vrp);
|
||||||
|
algorithm.setMaxIterations(100);
|
||||||
|
VehicleRoutingProblemSolution solution = Solutions.bestOf(algorithm.searchSolutions());
|
||||||
|
|
||||||
|
Assert.assertEquals(0,solution.getUnassignedJobs().size());
|
||||||
|
Assert.assertEquals(2, solution.getRoutes().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void service2ShouldBeInserted(){
|
||||||
|
Service s = Service.Builder.newInstance("s1").setLocation(Location.newInstance(10,0)).build();
|
||||||
|
|
||||||
|
Service s2 = Service.Builder.newInstance("s2")
|
||||||
|
.addTimeWindow(50., 60.).addTimeWindow(15., 25)
|
||||||
|
.setLocation(Location.newInstance(20, 0)).build();
|
||||||
|
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v1").setStartLocation(Location.newInstance(0,0))
|
||||||
|
.setEarliestStart(0.).setLatestArrival(40).build();
|
||||||
|
|
||||||
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(s).addJob(s2).addVehicle(v).build();
|
||||||
|
VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(vrp);
|
||||||
|
algorithm.setMaxIterations(100);
|
||||||
|
VehicleRoutingProblemSolution solution = Solutions.bestOf(algorithm.searchSolutions());
|
||||||
|
|
||||||
|
Assert.assertEquals(0,solution.getUnassignedJobs().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -184,4 +184,28 @@ public class ServiceTest {
|
||||||
assertEquals("name",s.getName());
|
assertEquals("name",s.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldKnowMultipleTimeWindows(){
|
||||||
|
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.addTimeWindow(TimeWindow.newInstance(0., 10.)).addTimeWindow(TimeWindow.newInstance(20., 30.))
|
||||||
|
.setName("name").build();
|
||||||
|
assertEquals(2,s.getTimeWindows(0.).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void whenMultipleTWOverlap_throwEx(){
|
||||||
|
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.addTimeWindow(TimeWindow.newInstance(0.,10.))
|
||||||
|
.addTimeWindow(TimeWindow.newInstance(5., 30.))
|
||||||
|
.setName("name").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void whenMultipleTWOverlap2_throwEx(){
|
||||||
|
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||||
|
.addTimeWindow(TimeWindow.newInstance(20., 30.))
|
||||||
|
.addTimeWindow(TimeWindow.newInstance(0., 25.))
|
||||||
|
.setName("name").build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue