mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
merge multiple time window branch
This commit is contained in:
commit
26d03f15e3
123 changed files with 9432 additions and 205 deletions
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~ Copyright (C) 2014 Stefan Schroeder
|
||||
~
|
||||
|
|
@ -81,7 +82,6 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,8 @@ final class BreakInsertionCalculator implements JobInsertionCostsCalculator {
|
|||
List<Location> locations = Arrays.asList(prevAct.getLocation(), nextAct.getLocation());
|
||||
for (Location location : locations) {
|
||||
breakAct2Insert.setLocation(location);
|
||||
breakAct2Insert.setTheoreticalEarliestOperationStartTime(breakToInsert.getTimeWindow().getStart());
|
||||
breakAct2Insert.setTheoreticalLatestOperationStartTime(breakToInsert.getTimeWindow().getEnd());
|
||||
ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, breakAct2Insert, nextAct, prevActStartTime);
|
||||
if (status.equals(ConstraintsStatus.FULFILLED)) {
|
||||
//from job2insert induced costs at activity level
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ 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;
|
||||
|
|
@ -108,6 +109,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,38 +123,46 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator {
|
|||
int actIndex = 0;
|
||||
Iterator<TourActivity> activityIterator = currentRoute.getActivities().iterator();
|
||||
boolean tourEnd = false;
|
||||
while (!tourEnd) {
|
||||
while(!tourEnd){
|
||||
TourActivity nextAct;
|
||||
if (activityIterator.hasNext()) nextAct = activityIterator.next();
|
||||
else {
|
||||
if(activityIterator.hasNext()) nextAct = activityIterator.next();
|
||||
else{
|
||||
nextAct = end;
|
||||
tourEnd = true;
|
||||
}
|
||||
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;
|
||||
boolean not_fulfilled_break = true;
|
||||
for(TimeWindow timeWindow : service.getTimeWindows()) {
|
||||
deliveryAct2Insert.setTheoreticalEarliestOperationStartTime(timeWindow.getStart());
|
||||
deliveryAct2Insert.setTheoreticalLatestOperationStartTime(timeWindow.getEnd());
|
||||
ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
|
||||
if (status.equals(ConstraintsStatus.FULFILLED)) {
|
||||
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)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(not_fulfilled_break) break;
|
||||
double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActStartTime, newDriver, newVehicle);
|
||||
prevActStartTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct);
|
||||
prevAct = nextAct;
|
||||
actIndex++;
|
||||
}
|
||||
if (insertionIndex == InsertionData.NO_INDEX) {
|
||||
if(insertionIndex == InsertionData.NO_INDEX) {
|
||||
return InsertionData.createEmptyInsertionData();
|
||||
}
|
||||
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 SwitchVehicle(currentRoute, newVehicle, newVehicleDepartureTime));
|
||||
insertionData.getEvents().add(new SwitchVehicle(currentRoute,newVehicle,newVehicleDepartureTime));
|
||||
insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
|
||||
return insertionData;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ 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;
|
||||
|
|
@ -108,6 +109,9 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator {
|
|||
int pickupInsertionIndex = InsertionData.NO_INDEX;
|
||||
int deliveryInsertionIndex = InsertionData.NO_INDEX;
|
||||
|
||||
TimeWindow bestPickupTimeWindow = null;
|
||||
TimeWindow bestDeliveryTimeWindow = null;
|
||||
|
||||
Start start = new Start(newVehicle.getStartLocation(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival());
|
||||
start.setEndTime(newVehicleDepartureTime);
|
||||
|
||||
|
|
@ -132,67 +136,83 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator {
|
|||
nextAct = end;
|
||||
tourEnd = true;
|
||||
}
|
||||
// logger.info("activity: {}, act-size: {}", i, activities.size());
|
||||
ConstraintsStatus pickupShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
|
||||
if (pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED)) {
|
||||
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActEndTime, newDriver, newVehicle);
|
||||
prevActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct);
|
||||
prevAct = nextAct;
|
||||
i++;
|
||||
continue;
|
||||
} else if (pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)) {
|
||||
break;
|
||||
}
|
||||
double additionalPickupICosts = softActivityConstraint.getCosts(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
|
||||
double pickupAIC = calculate(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
|
||||
|
||||
TourActivity prevAct_deliveryLoop = pickupShipment;
|
||||
double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), pickupShipment.getLocation(), prevActEndTime, newDriver, newVehicle);
|
||||
double shipmentPickupEndTime = CalculationUtils.getActivityEndTime(shipmentPickupArrTime, pickupShipment);
|
||||
boolean pickupInsertionNotFulfilledBreak = true;
|
||||
for(TimeWindow pickupTimeWindow : shipment.getPickupTimeWindows()) {
|
||||
pickupShipment.setTheoreticalEarliestOperationStartTime(pickupTimeWindow.getStart());
|
||||
pickupShipment.setTheoreticalLatestOperationStartTime(pickupTimeWindow.getEnd());
|
||||
ConstraintsStatus pickupShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
|
||||
if (pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED)) {
|
||||
pickupInsertionNotFulfilledBreak = false;
|
||||
continue;
|
||||
} else if(pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)) {
|
||||
continue;
|
||||
}
|
||||
else if (pickupShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)) {
|
||||
pickupInsertionNotFulfilledBreak = false;
|
||||
}
|
||||
double additionalPickupICosts = softActivityConstraint.getCosts(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
|
||||
double pickupAIC = calculate(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
|
||||
|
||||
pickupContext.setArrivalTime(shipmentPickupArrTime);
|
||||
pickupContext.setEndTime(shipmentPickupEndTime);
|
||||
pickupContext.setInsertionIndex(i);
|
||||
insertionContext.setRelatedActivityContext(pickupContext);
|
||||
TourActivity prevAct_deliveryLoop = pickupShipment;
|
||||
double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), pickupShipment.getLocation(), prevActEndTime, newDriver, newVehicle);
|
||||
double shipmentPickupEndTime = CalculationUtils.getActivityEndTime(shipmentPickupArrTime, pickupShipment);
|
||||
|
||||
double prevActEndTime_deliveryLoop = shipmentPickupEndTime;
|
||||
pickupContext.setArrivalTime(shipmentPickupArrTime);
|
||||
pickupContext.setEndTime(shipmentPickupEndTime);
|
||||
pickupContext.setInsertionIndex(i);
|
||||
insertionContext.setRelatedActivityContext(pickupContext);
|
||||
|
||||
double prevActEndTime_deliveryLoop = shipmentPickupEndTime;
|
||||
|
||||
/*
|
||||
--------------------------------
|
||||
*/
|
||||
//deliverShipmentLoop
|
||||
int j = i;
|
||||
boolean tourEnd_deliveryLoop = false;
|
||||
while (!tourEnd_deliveryLoop) {
|
||||
|
||||
// for(int j=i;j<activities.size();j++){
|
||||
TourActivity nextAct_deliveryLoop;
|
||||
if (j < activities.size()) {
|
||||
nextAct_deliveryLoop = activities.get(j);
|
||||
} else {
|
||||
nextAct_deliveryLoop = end;
|
||||
tourEnd_deliveryLoop = true;
|
||||
}
|
||||
|
||||
ConstraintsStatus deliverShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
|
||||
if (deliverShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)) {
|
||||
double additionalDeliveryICosts = softActivityConstraint.getCosts(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
|
||||
double deliveryAIC = calculate(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
|
||||
double totalActivityInsertionCosts = pickupAIC + deliveryAIC
|
||||
+ additionalICostsAtRouteLevel + additionalPickupICosts + additionalDeliveryICosts;
|
||||
if (totalActivityInsertionCosts < bestCost) {
|
||||
bestCost = totalActivityInsertionCosts;
|
||||
pickupInsertionIndex = i;
|
||||
deliveryInsertionIndex = j;
|
||||
//deliverShipmentLoop
|
||||
int j = i;
|
||||
boolean tourEnd_deliveryLoop = false;
|
||||
while (!tourEnd_deliveryLoop) {
|
||||
TourActivity nextAct_deliveryLoop;
|
||||
if (j < activities.size()) {
|
||||
nextAct_deliveryLoop = activities.get(j);
|
||||
} else {
|
||||
nextAct_deliveryLoop = end;
|
||||
tourEnd_deliveryLoop = true;
|
||||
}
|
||||
} else if (deliverShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)) {
|
||||
break;
|
||||
|
||||
boolean deliveryInsertionNotFulfilledBreak = true;
|
||||
for (TimeWindow deliveryTimeWindow : shipment.getDeliveryTimeWindows()) {
|
||||
deliverShipment.setTheoreticalEarliestOperationStartTime(deliveryTimeWindow.getStart());
|
||||
deliverShipment.setTheoreticalLatestOperationStartTime(deliveryTimeWindow.getEnd());
|
||||
|
||||
ConstraintsStatus deliverShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
|
||||
if (deliverShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)) {
|
||||
double additionalDeliveryICosts = softActivityConstraint.getCosts(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
|
||||
double deliveryAIC = calculate(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
|
||||
double totalActivityInsertionCosts = pickupAIC + deliveryAIC
|
||||
+ additionalICostsAtRouteLevel + additionalPickupICosts + additionalDeliveryICosts;
|
||||
if (totalActivityInsertionCosts < bestCost) {
|
||||
bestCost = totalActivityInsertionCosts;
|
||||
pickupInsertionIndex = i;
|
||||
deliveryInsertionIndex = j;
|
||||
bestPickupTimeWindow = pickupTimeWindow;
|
||||
bestDeliveryTimeWindow = deliveryTimeWindow;
|
||||
}
|
||||
deliveryInsertionNotFulfilledBreak = false;
|
||||
} else if (deliverShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED)) {
|
||||
deliveryInsertionNotFulfilledBreak = false;
|
||||
}
|
||||
}
|
||||
if (deliveryInsertionNotFulfilledBreak) break;
|
||||
//update prevAct and endTime
|
||||
double nextActArrTime = prevActEndTime_deliveryLoop + transportCosts.getTransportTime(prevAct_deliveryLoop.getLocation(), nextAct_deliveryLoop.getLocation(), prevActEndTime_deliveryLoop, newDriver, newVehicle);
|
||||
prevActEndTime_deliveryLoop = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct_deliveryLoop);
|
||||
prevAct_deliveryLoop = nextAct_deliveryLoop;
|
||||
j++;
|
||||
}
|
||||
//update prevAct and endTime
|
||||
double nextActArrTime = prevActEndTime_deliveryLoop + transportCosts.getTransportTime(prevAct_deliveryLoop.getLocation(), nextAct_deliveryLoop.getLocation(), prevActEndTime_deliveryLoop, newDriver, newVehicle);
|
||||
prevActEndTime_deliveryLoop = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct_deliveryLoop);
|
||||
prevAct_deliveryLoop = nextAct_deliveryLoop;
|
||||
j++;
|
||||
}
|
||||
if(pickupInsertionNotFulfilledBreak){
|
||||
break;
|
||||
}
|
||||
//update prevAct and endTime
|
||||
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActEndTime, newDriver, newVehicle);
|
||||
|
|
@ -204,6 +224,10 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator {
|
|||
return InsertionData.createEmptyInsertionData();
|
||||
}
|
||||
InsertionData insertionData = new InsertionData(bestCost, pickupInsertionIndex, deliveryInsertionIndex, newVehicle, newDriver);
|
||||
pickupShipment.setTheoreticalEarliestOperationStartTime(bestPickupTimeWindow.getStart());
|
||||
pickupShipment.setTheoreticalLatestOperationStartTime(bestPickupTimeWindow.getEnd());
|
||||
deliverShipment.setTheoreticalEarliestOperationStartTime(bestDeliveryTimeWindow.getStart());
|
||||
deliverShipment.setTheoreticalLatestOperationStartTime(bestDeliveryTimeWindow.getEnd());
|
||||
insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
|
||||
insertionData.getEvents().add(new InsertActivity(currentRoute, newVehicle, deliverShipment, deliveryInsertionIndex));
|
||||
insertionData.getEvents().add(new InsertActivity(currentRoute, newVehicle, pickupShipment, pickupInsertionIndex));
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ class NearestNeighborhoodIterator implements Iterator<Job> {
|
|||
public boolean hasNext() {
|
||||
if (jobCount < nJobs) {
|
||||
boolean hasNext = jobIter.hasNext();
|
||||
if (!hasNext)
|
||||
log.warn("more jobs are requested then iterator can iterate over. probably the number of neighbors memorized in JobNeighborhoods is too small");
|
||||
// if (!hasNext)
|
||||
// log.warn("more jobs are requested then iterator can iterate over. probably the number of neighbors memorized in JobNeighborhoods is too small");
|
||||
return hasNext;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import jsprit.core.problem.Location;
|
|||
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||
import jsprit.core.problem.solution.route.RouteVisitor;
|
||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
|
||||
|
|
@ -97,6 +98,7 @@ public class UpdateVehicleDependentPracticalTimeWindows implements RouteVisitor,
|
|||
double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocation(), prevLocation,
|
||||
latestArrTimeAtPrevAct, route.getDriver(), vehicle) - activity.getOperationTime();
|
||||
double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct);
|
||||
// getLatestArrivalTime(activity.getTimeWindows(), potentialLatestArrivalTimeAtCurrAct);
|
||||
if (latestArrivalTime < activity.getTheoreticalEarliestOperationStartTime()) {
|
||||
stateManager.putTypedInternalRouteState(route, vehicle, InternalStates.SWITCH_NOT_FEASIBLE, true);
|
||||
}
|
||||
|
|
@ -107,8 +109,8 @@ public class UpdateVehicleDependentPracticalTimeWindows implements RouteVisitor,
|
|||
}
|
||||
|
||||
|
||||
public void finish() {
|
||||
}
|
||||
public void finish() {}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,14 +54,9 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr
|
|||
nextActLocation = newAct.getLocation();
|
||||
}
|
||||
} else {
|
||||
//try to get latest_operation_start_time of newVehicle
|
||||
latestArrTimeAtNextAct = states.getActivityState(nextAct, iFacts.getNewVehicle(), InternalStates.LATEST_OPERATION_START_TIME, Double.class);
|
||||
// if(latestArrTimeAtNextAct == null) //try to get latest_operation_start_time of currVehicle
|
||||
// latestArrTimeAtNextAct = states.getActivityState(nextAct, iFacts.getRoute().getVehicle(), StateFactory.LATEST_OPERATION_START_TIME ,Double.class);
|
||||
if (latestArrTimeAtNextAct == null) {//otherwise set it to theoretical_latest_operation_startTime
|
||||
latestArrTimeAtNextAct = nextAct.getTheoreticalLatestOperationStartTime();
|
||||
// throw new IllegalStateException("this is strange and should not be");
|
||||
//ToDo here, there should be another solution
|
||||
}
|
||||
nextActLocation = nextAct.getLocation();
|
||||
}
|
||||
|
|
@ -73,8 +68,10 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr
|
|||
* |--- vehicle's operation time ---|
|
||||
* |--- prevAct or newAct or nextAct ---|
|
||||
*/
|
||||
double newAct_theoreticalEarliestOperationStartTime = newAct.getTheoreticalEarliestOperationStartTime();
|
||||
|
||||
if (latestVehicleArrival < prevAct.getTheoreticalEarliestOperationStartTime() ||
|
||||
latestVehicleArrival < newAct.getTheoreticalEarliestOperationStartTime() ||
|
||||
latestVehicleArrival < newAct_theoreticalEarliestOperationStartTime ||
|
||||
latestVehicleArrival < nextAct.getTheoreticalEarliestOperationStartTime()) {
|
||||
return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
||||
}
|
||||
|
|
@ -85,7 +82,9 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr
|
|||
* |--- prevAct ---|
|
||||
* |--- newAct ---|
|
||||
*/
|
||||
if (newAct.getTheoreticalLatestOperationStartTime() < prevAct.getTheoreticalEarliestOperationStartTime()) {
|
||||
double newAct_theoreticalLatestOperationStartTime = newAct.getTheoreticalLatestOperationStartTime();
|
||||
|
||||
if (newAct_theoreticalLatestOperationStartTime < prevAct.getTheoreticalEarliestOperationStartTime()) {
|
||||
return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
||||
}
|
||||
|
||||
|
|
@ -103,16 +102,16 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr
|
|||
* |--- newAct ---|
|
||||
* |--- nextAct ---|
|
||||
*/
|
||||
if (newAct.getTheoreticalEarliestOperationStartTime() > nextAct.getTheoreticalLatestOperationStartTime()) {
|
||||
if(newAct_theoreticalEarliestOperationStartTime > nextAct.getTheoreticalLatestOperationStartTime()){
|
||||
return ConstraintsStatus.NOT_FULFILLED;
|
||||
}
|
||||
// log.info("check insertion of " + newAct + " between " + prevAct + " and " + nextAct + ". prevActDepTime=" + prevActDepTime);
|
||||
double arrTimeAtNewAct = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||
double endTimeAtNewAct = CalculationUtils.getActivityEndTime(arrTimeAtNewAct, newAct);
|
||||
double latestArrTimeAtNewAct =
|
||||
Math.min(newAct.getTheoreticalLatestOperationStartTime(),
|
||||
Math.min(newAct_theoreticalLatestOperationStartTime,
|
||||
latestArrTimeAtNextAct -
|
||||
routingCosts.getBackwardTransportTime(newAct.getLocation(), nextActLocation, latestArrTimeAtNextAct, iFacts.getNewDriver(), iFacts.getNewVehicle())
|
||||
routingCosts.getBackwardTransportTime(newAct.getLocation(),nextActLocation,latestArrTimeAtNextAct,iFacts.getNewDriver(),iFacts.getNewVehicle())
|
||||
- newAct.getOperationTime()
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,174 @@ public class VrpXMLReader {
|
|||
this.solutions = null;
|
||||
}
|
||||
|
||||
public void read(String filename) {
|
||||
logger.debug("read vrp: {}", filename);
|
||||
XMLConfiguration xmlConfig = new XMLConfiguration();
|
||||
xmlConfig.setFileName(filename);
|
||||
xmlConfig.setAttributeSplittingDisabled(true);
|
||||
xmlConfig.setDelimiterParsingDisabled(true);
|
||||
|
||||
if (schemaValidation) {
|
||||
final InputStream resource = Resource.getAsInputStream("vrp_xml_schema.xsd");
|
||||
if (resource != null) {
|
||||
EntityResolver resolver = new EntityResolver() {
|
||||
|
||||
@Override
|
||||
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
|
||||
{
|
||||
InputSource is = new InputSource(resource);
|
||||
return is;
|
||||
}
|
||||
}
|
||||
};
|
||||
xmlConfig.setEntityResolver(resolver);
|
||||
xmlConfig.setSchemaValidation(true);
|
||||
} else {
|
||||
logger.debug("cannot find schema-xsd file (vrp_xml_schema.xsd). try to read xml without xml-file-validation.");
|
||||
}
|
||||
}
|
||||
try {
|
||||
xmlConfig.load();
|
||||
} catch (ConfigurationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
readProblemType(xmlConfig);
|
||||
readVehiclesAndTheirTypes(xmlConfig);
|
||||
|
||||
readShipments(xmlConfig);
|
||||
readServices(xmlConfig);
|
||||
|
||||
readInitialRoutes(xmlConfig);
|
||||
readSolutions(xmlConfig);
|
||||
|
||||
addJobsAndTheirLocationsToVrp();
|
||||
}
|
||||
|
||||
private void addJobsAndTheirLocationsToVrp() {
|
||||
for (Service service : serviceMap.values()) {
|
||||
if (!freezedJobIds.contains(service.getId())) {
|
||||
vrpBuilder.addJob(service);
|
||||
}
|
||||
}
|
||||
for (Shipment shipment : shipmentMap.values()) {
|
||||
if (!freezedJobIds.contains(shipment.getId())) {
|
||||
vrpBuilder.addJob(shipment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readInitialRoutes(XMLConfiguration xmlConfig) {
|
||||
List<HierarchicalConfiguration> initialRouteConfigs = xmlConfig.configurationsAt("initialRoutes.route");
|
||||
for (HierarchicalConfiguration routeConfig : initialRouteConfigs) {
|
||||
Driver driver = DriverImpl.noDriver();
|
||||
String vehicleId = routeConfig.getString("vehicleId");
|
||||
Vehicle vehicle = getVehicle(vehicleId);
|
||||
if (vehicle == null) throw new IllegalStateException("vehicle is missing.");
|
||||
String start = routeConfig.getString("start");
|
||||
if (start == null) throw new IllegalStateException("route start-time is missing.");
|
||||
double departureTime = Double.parseDouble(start);
|
||||
|
||||
VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle, driver);
|
||||
routeBuilder.setDepartureTime(departureTime);
|
||||
|
||||
List<HierarchicalConfiguration> actConfigs = routeConfig.configurationsAt("act");
|
||||
for (HierarchicalConfiguration actConfig : actConfigs) {
|
||||
String type = actConfig.getString("[@type]");
|
||||
if (type == null) throw new IllegalStateException("act[@type] is missing.");
|
||||
double arrTime = 0.;
|
||||
double endTime = 0.;
|
||||
String arrTimeS = actConfig.getString("arrTime");
|
||||
if (arrTimeS != null) arrTime = Double.parseDouble(arrTimeS);
|
||||
String endTimeS = actConfig.getString("endTime");
|
||||
if (endTimeS != null) endTime = Double.parseDouble(endTimeS);
|
||||
|
||||
String serviceId = actConfig.getString("serviceId");
|
||||
if (serviceId != null) {
|
||||
Service service = getService(serviceId);
|
||||
if (service == null)
|
||||
throw new IllegalStateException("service to serviceId " + serviceId + " is missing (reference in one of your initial routes). make sure you define the service you refer to here in <services> </services>.");
|
||||
//!!!since job is part of initial route, it does not belong to jobs in problem, i.e. variable jobs that can be assigned/scheduled
|
||||
freezedJobIds.add(serviceId);
|
||||
routeBuilder.addService(service);
|
||||
} else {
|
||||
String shipmentId = actConfig.getString("shipmentId");
|
||||
if (shipmentId == null)
|
||||
throw new IllegalStateException("either serviceId or shipmentId is missing");
|
||||
Shipment shipment = getShipment(shipmentId);
|
||||
if (shipment == null)
|
||||
throw new IllegalStateException("shipment to shipmentId " + shipmentId + " is missing (reference in one of your initial routes). make sure you define the shipment you refer to here in <shipments> </shipments>.");
|
||||
freezedJobIds.add(shipmentId);
|
||||
if (type.equals("pickupShipment")) {
|
||||
routeBuilder.addPickup(shipment);
|
||||
} else if (type.equals("deliverShipment")) {
|
||||
routeBuilder.addDelivery(shipment);
|
||||
} else
|
||||
throw new IllegalStateException("type " + type + " is not supported. Use 'pickupShipment' or 'deliverShipment' here");
|
||||
}
|
||||
}
|
||||
VehicleRoute route = routeBuilder.build();
|
||||
vrpBuilder.addInitialVehicleRoute(route);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void readSolutions(XMLConfiguration vrpProblem) {
|
||||
if (solutions == null) return;
|
||||
List<HierarchicalConfiguration> solutionConfigs = vrpProblem.configurationsAt("solutions.solution");
|
||||
for (HierarchicalConfiguration solutionConfig : solutionConfigs) {
|
||||
String totalCost = solutionConfig.getString("cost");
|
||||
double cost = -1;
|
||||
if (totalCost != null) cost = Double.parseDouble(totalCost);
|
||||
List<HierarchicalConfiguration> routeConfigs = solutionConfig.configurationsAt("routes.route");
|
||||
List<VehicleRoute> routes = new ArrayList<VehicleRoute>();
|
||||
for (HierarchicalConfiguration routeConfig : routeConfigs) {
|
||||
//! here, driverId is set to noDriver, no matter whats in driverId.
|
||||
Driver driver = DriverImpl.noDriver();
|
||||
String vehicleId = routeConfig.getString("vehicleId");
|
||||
Vehicle vehicle = getVehicle(vehicleId);
|
||||
if (vehicle == null) throw new IllegalStateException("vehicle is missing.");
|
||||
String start = routeConfig.getString("start");
|
||||
if (start == null) throw new IllegalStateException("route start-time is missing.");
|
||||
double departureTime = Double.parseDouble(start);
|
||||
|
||||
String end = routeConfig.getString("end");
|
||||
if (end == null) throw new IllegalStateException("route end-time is missing.");
|
||||
|
||||
VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle, driver);
|
||||
routeBuilder.setDepartureTime(departureTime);
|
||||
routeBuilder.setRouteEndArrivalTime(Double.parseDouble(end));
|
||||
List<HierarchicalConfiguration> actConfigs = routeConfig.configurationsAt("act");
|
||||
for (HierarchicalConfiguration actConfig : actConfigs) {
|
||||
String type = actConfig.getString("[@type]");
|
||||
if (type == null) throw new IllegalStateException("act[@type] is missing.");
|
||||
double arrTime = 0.;
|
||||
double endTime = 0.;
|
||||
String arrTimeS = actConfig.getString("arrTime");
|
||||
if (arrTimeS != null) arrTime = Double.parseDouble(arrTimeS);
|
||||
String endTimeS = actConfig.getString("endTime");
|
||||
if (endTimeS != null) endTime = Double.parseDouble(endTimeS);
|
||||
|
||||
String serviceId = actConfig.getString("serviceId");
|
||||
if (serviceId != null) {
|
||||
Service service = getService(serviceId);
|
||||
routeBuilder.addService(service);
|
||||
} else {
|
||||
String shipmentId = actConfig.getString("shipmentId");
|
||||
if (shipmentId == null)
|
||||
throw new IllegalStateException("either serviceId or shipmentId is missing");
|
||||
Shipment shipment = getShipment(shipmentId);
|
||||
if (shipment == null)
|
||||
throw new IllegalStateException("shipment with id " + shipmentId + " does not exist.");
|
||||
if (type.equals("pickupShipment")) {
|
||||
routeBuilder.addPickup(shipment);
|
||||
} else if (type.equals("deliverShipment")) {
|
||||
routeBuilder.addDelivery(shipment);
|
||||
} else
|
||||
throw new IllegalStateException("type " + type + " is not supported. Use 'pickupShipment' or 'deliverShipment' here");
|
||||
}
|
||||
}
|
||||
routes.add(routeBuilder.build());
|
||||
}
|
||||
public void read(String filename) {
|
||||
logger.debug("read vrp: {}", filename);
|
||||
XMLConfiguration xmlConfig = createXMLConfiguration();
|
||||
|
|
|
|||
|
|
@ -21,8 +21,12 @@ 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.problem.solution.route.activity.TimeWindowsImpl;
|
||||
import jsprit.core.util.Coordinate;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Service implementation of a job.
|
||||
* <p/>
|
||||
|
|
@ -78,9 +82,15 @@ public class Service extends AbstractJob {
|
|||
|
||||
protected Location location;
|
||||
|
||||
Builder(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
protected TimeWindowsImpl timeWindows;
|
||||
|
||||
private boolean twAdded = false;
|
||||
|
||||
Builder(String id){
|
||||
this.id = id;
|
||||
timeWindows = new TimeWindowsImpl();
|
||||
timeWindows.add(timeWindow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected method to set the type-name of the service.
|
||||
|
|
@ -137,21 +147,28 @@ public class Service extends AbstractJob {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time-window of this service.
|
||||
* <p/>
|
||||
* <p>The time-window indicates the time period a service/activity/operation is allowed to start.
|
||||
*
|
||||
* @param tw the time-window to be set
|
||||
* @return builder
|
||||
* @throws IllegalArgumentException if timeWindow is null
|
||||
*/
|
||||
public Builder<T> setTimeWindow(TimeWindow tw) {
|
||||
if (tw == null) throw new IllegalArgumentException("time-window arg must not be null");
|
||||
public Builder<T> setTimeWindow(TimeWindow tw){
|
||||
if(tw == null) throw new IllegalArgumentException("time-window arg must not be null");
|
||||
this.timeWindow = tw;
|
||||
this.timeWindows = new TimeWindowsImpl();
|
||||
timeWindows.add(tw);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> addTimeWindow(TimeWindow timeWindow) {
|
||||
if(timeWindow == null) throw new IllegalArgumentException("time-window arg must not be null");
|
||||
if(!twAdded){
|
||||
timeWindows = new TimeWindowsImpl();
|
||||
twAdded = true;
|
||||
}
|
||||
timeWindows.add(timeWindow);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> addTimeWindow(double earliest, double latest) {
|
||||
return addTimeWindow(TimeWindow.newInstance(earliest, latest));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the service.
|
||||
*
|
||||
|
|
@ -191,7 +208,6 @@ public class Service extends AbstractJob {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private final String id;
|
||||
|
||||
private final String type;
|
||||
|
|
@ -208,6 +224,8 @@ public class Service extends AbstractJob {
|
|||
|
||||
private final Location location;
|
||||
|
||||
private final TimeWindows timeWindowManager;
|
||||
|
||||
Service(Builder builder) {
|
||||
id = builder.id;
|
||||
serviceTime = builder.serviceTime;
|
||||
|
|
@ -217,7 +235,12 @@ public class Service extends AbstractJob {
|
|||
skills = builder.skills;
|
||||
name = builder.name;
|
||||
location = builder.location;
|
||||
}
|
||||
timeWindowManager = builder.timeWindows;
|
||||
}
|
||||
|
||||
public Collection<TimeWindow> getTimeWindows(){
|
||||
return timeWindowManager.getTimeWindows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
|
|
@ -245,11 +268,13 @@ public class Service extends AbstractJob {
|
|||
|
||||
/**
|
||||
* Returns the time-window a service(-operation) is allowed to start.
|
||||
* It is recommended to use getTimeWindows() instead. If you still use this, it returns the first time window of getTimeWindows() collection.
|
||||
*
|
||||
* @return time window
|
||||
*
|
||||
*/
|
||||
public TimeWindow getTimeWindow() {
|
||||
return timeWindow;
|
||||
return timeWindowManager.getTimeWindows().iterator().next();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ 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.TimeWindowsImpl;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -42,6 +45,7 @@ import jsprit.core.problem.solution.route.activity.TimeWindow;
|
|||
public class Shipment extends AbstractJob {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Builder that builds the shipment.
|
||||
*
|
||||
|
|
@ -73,6 +77,14 @@ public class Shipment extends AbstractJob {
|
|||
|
||||
private Location deliveryLocation_;
|
||||
|
||||
protected TimeWindowsImpl deliveryTimeWindows;
|
||||
|
||||
private boolean deliveryTimeWindowAdded = false;
|
||||
|
||||
private boolean pickupTimeWindowAdded = false;
|
||||
|
||||
private TimeWindowsImpl pickupTimeWindows;
|
||||
|
||||
/**
|
||||
* Returns new instance of this builder.
|
||||
*
|
||||
|
|
@ -86,6 +98,10 @@ public class Shipment extends AbstractJob {
|
|||
Builder(String id) {
|
||||
if (id == null) throw new IllegalArgumentException("id must not be null");
|
||||
this.id = id;
|
||||
pickupTimeWindows = new TimeWindowsImpl();
|
||||
pickupTimeWindows.add(pickupTimeWindow);
|
||||
deliveryTimeWindows = new TimeWindowsImpl();
|
||||
deliveryTimeWindows.add(deliveryTimeWindow);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -125,11 +141,15 @@ public class Shipment extends AbstractJob {
|
|||
* @throws IllegalArgumentException if timeWindow is null
|
||||
*/
|
||||
public Builder setPickupTimeWindow(TimeWindow timeWindow) {
|
||||
if (timeWindow == null) throw new IllegalArgumentException("timeWindow cannot be null");
|
||||
if (timeWindow == null) throw new IllegalArgumentException("delivery time-window must not be null");
|
||||
this.pickupTimeWindow = timeWindow;
|
||||
this.pickupTimeWindows = new TimeWindowsImpl();
|
||||
this.pickupTimeWindows.add(timeWindow);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sets delivery location.
|
||||
*
|
||||
|
|
@ -169,6 +189,8 @@ public class Shipment extends AbstractJob {
|
|||
public Builder setDeliveryTimeWindow(TimeWindow timeWindow) {
|
||||
if (timeWindow == null) throw new IllegalArgumentException("delivery time-window must not be null");
|
||||
this.deliveryTimeWindow = timeWindow;
|
||||
this.deliveryTimeWindows = new TimeWindowsImpl();
|
||||
this.deliveryTimeWindows.add(timeWindow);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -212,6 +234,35 @@ public class Shipment extends AbstractJob {
|
|||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addDeliveryTimeWindow(TimeWindow timeWindow) {
|
||||
if(timeWindow == null) throw new IllegalArgumentException("time-window arg must not be null");
|
||||
if(!deliveryTimeWindowAdded){
|
||||
deliveryTimeWindows = new TimeWindowsImpl();
|
||||
deliveryTimeWindowAdded = true;
|
||||
}
|
||||
deliveryTimeWindows.add(timeWindow);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addDeliveryTimeWindow(double earliest, double latest) {
|
||||
addDeliveryTimeWindow(TimeWindow.newInstance(earliest, latest));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addPickupTimeWindow(TimeWindow timeWindow) {
|
||||
if(timeWindow == null) throw new IllegalArgumentException("time-window arg must not be null");
|
||||
if(!pickupTimeWindowAdded){
|
||||
pickupTimeWindows = new TimeWindowsImpl();
|
||||
pickupTimeWindowAdded = true;
|
||||
}
|
||||
pickupTimeWindows.add(timeWindow);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addPickupTimeWindow(double earliest, double latest) {
|
||||
return addPickupTimeWindow(TimeWindow.newInstance(earliest, latest));
|
||||
}
|
||||
}
|
||||
|
||||
private final String id;
|
||||
|
|
@ -234,6 +285,10 @@ public class Shipment extends AbstractJob {
|
|||
|
||||
private final Location deliveryLocation_;
|
||||
|
||||
private final TimeWindowsImpl deliveryTimeWindows;
|
||||
|
||||
private final TimeWindowsImpl pickupTimeWindows;
|
||||
|
||||
Shipment(Builder builder) {
|
||||
this.id = builder.id;
|
||||
this.pickupServiceTime = builder.pickupServiceTime;
|
||||
|
|
@ -245,6 +300,8 @@ public class Shipment extends AbstractJob {
|
|||
this.name = builder.name;
|
||||
this.pickupLocation_ = builder.pickupLocation_;
|
||||
this.deliveryLocation_ = builder.deliveryLocation_;
|
||||
this.deliveryTimeWindows = builder.deliveryTimeWindows;
|
||||
this.pickupTimeWindows = builder.pickupTimeWindows;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -286,7 +343,11 @@ public class Shipment extends AbstractJob {
|
|||
* @return time-window of delivery
|
||||
*/
|
||||
public TimeWindow getDeliveryTimeWindow() {
|
||||
return deliveryTimeWindow;
|
||||
return deliveryTimeWindows.getTimeWindows().iterator().next();
|
||||
}
|
||||
|
||||
public Collection<TimeWindow> getDeliveryTimeWindows() {
|
||||
return deliveryTimeWindows.getTimeWindows();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -295,9 +356,14 @@ public class Shipment extends AbstractJob {
|
|||
* @return time-window of pickup
|
||||
*/
|
||||
public TimeWindow getPickupTimeWindow() {
|
||||
return pickupTimeWindow;
|
||||
return pickupTimeWindows.getTimeWindows().iterator().next();
|
||||
}
|
||||
|
||||
public Collection<TimeWindow> getPickupTimeWindows() {
|
||||
return pickupTimeWindows.getTimeWindows();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
|
|
|
|||
|
|
@ -212,7 +212,8 @@ public class VehicleRoute {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds a service to this route.
|
||||
* Adds a service to this route. Activity is initialized with .getTimeWindow(). If you want to explicitly set another time window
|
||||
* use .addService(Service service, TimeWindow timeWindow)
|
||||
* <p/>
|
||||
* <p>This implies that for this service a serviceActivity is created with {@link TourActivityFactory} and added to the sequence of tourActivities.
|
||||
* <p/>
|
||||
|
|
@ -223,9 +224,15 @@ public class VehicleRoute {
|
|||
* @throws IllegalArgumentException if service is null
|
||||
*/
|
||||
public Builder addService(Service service) {
|
||||
return addService(service,service.getTimeWindow());
|
||||
}
|
||||
|
||||
public Builder addService(Service service, TimeWindow timeWindow) {
|
||||
if (service == null) throw new IllegalArgumentException("service must not be null");
|
||||
List<AbstractActivity> acts = jobActivityFactory.createActivities(service);
|
||||
TourActivity act = acts.get(0);
|
||||
act.setTheoreticalEarliestOperationStartTime(timeWindow.getStart());
|
||||
act.setTheoreticalLatestOperationStartTime(timeWindow.getEnd());
|
||||
tourActivities.addActivity(act);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -238,8 +245,12 @@ public class VehicleRoute {
|
|||
*/
|
||||
public Builder addPickup(Pickup pickup) {
|
||||
if (pickup == null) throw new IllegalArgumentException("pickup must not be null");
|
||||
addService(pickup);
|
||||
return this;
|
||||
return addService(pickup);
|
||||
}
|
||||
|
||||
public Builder addPickup(Pickup pickup, TimeWindow timeWindow) {
|
||||
if (pickup == null) throw new IllegalArgumentException("pickup must not be null");
|
||||
return addService(pickup,timeWindow);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -250,8 +261,12 @@ public class VehicleRoute {
|
|||
*/
|
||||
public Builder addDelivery(Delivery delivery) {
|
||||
if (delivery == null) throw new IllegalArgumentException("delivery must not be null");
|
||||
addService(delivery);
|
||||
return this;
|
||||
return addService(delivery);
|
||||
}
|
||||
|
||||
public Builder addDelivery(Delivery delivery, TimeWindow timeWindow) {
|
||||
if (delivery == null) throw new IllegalArgumentException("delivery must not be null");
|
||||
return addService(delivery,timeWindow);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -262,10 +277,16 @@ public class VehicleRoute {
|
|||
* @throws IllegalStateException if method has already been called with the specified shipment.
|
||||
*/
|
||||
public Builder addPickup(Shipment shipment) {
|
||||
return addPickup(shipment, shipment.getPickupTimeWindow());
|
||||
}
|
||||
|
||||
public Builder addPickup(Shipment shipment, TimeWindow pickupTimeWindow) {
|
||||
if (openShipments.contains(shipment))
|
||||
throw new IllegalStateException("shipment has already been added. cannot add it twice.");
|
||||
List<AbstractActivity> acts = jobActivityFactory.createActivities(shipment);
|
||||
TourActivity act = acts.get(0);
|
||||
act.setTheoreticalEarliestOperationStartTime(pickupTimeWindow.getStart());
|
||||
act.setTheoreticalLatestOperationStartTime(pickupTimeWindow.getEnd());
|
||||
tourActivities.addActivity(act);
|
||||
openShipments.add(shipment);
|
||||
openActivities.put(shipment, acts.get(1));
|
||||
|
|
@ -280,8 +301,14 @@ public class VehicleRoute {
|
|||
* @throws IllegalStateException if specified shipment has not been picked up yet (i.e. method addPickup(shipment) has not been called yet).
|
||||
*/
|
||||
public Builder addDelivery(Shipment shipment) {
|
||||
return addDelivery(shipment,shipment.getDeliveryTimeWindow());
|
||||
}
|
||||
|
||||
public Builder addDelivery(Shipment shipment, TimeWindow deliveryTimeWindow) {
|
||||
if (openShipments.contains(shipment)) {
|
||||
TourActivity act = openActivities.get(shipment);
|
||||
act.setTheoreticalEarliestOperationStartTime(deliveryTimeWindow.getStart());
|
||||
act.setTheoreticalLatestOperationStartTime(deliveryTimeWindow.getEnd());
|
||||
tourActivities.addActivity(act);
|
||||
openShipments.remove(shipment);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
package jsprit.core.problem.solution.route.activity;
|
||||
|
||||
/**
|
||||
* Created by schroeder on 08/07/15.
|
||||
*/
|
||||
public class ActivityStartAsSoonAsArrived implements ActivityStartStrategy {
|
||||
|
||||
@Override
|
||||
public double getActivityStartTime(TourActivity activity, double arrivalTime) {
|
||||
return arrivalTime;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package jsprit.core.problem.solution.route.activity;
|
||||
|
||||
/**
|
||||
* Created by schroeder on 08/07/15.
|
||||
*/
|
||||
public interface ActivityStartStrategy {
|
||||
|
||||
public double getActivityStartTime(TourActivity activity, double arrivalTime);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package jsprit.core.problem.solution.route.activity;
|
||||
|
||||
/**
|
||||
* Created by schroeder on 08/07/15.
|
||||
*/
|
||||
public class ActivityStartsAsSoonAsTimeWindowOpens implements ActivityStartStrategy {
|
||||
|
||||
@Override
|
||||
public double getActivityStartTime(TourActivity activity, double arrivalTime) {
|
||||
return Math.max(activity.getTheoreticalEarliestOperationStartTime(),arrivalTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -71,6 +71,10 @@ public class BreakActivity extends AbstractActivity implements JobActivity {
|
|||
|
||||
private final Break aBreak;
|
||||
|
||||
private double earliest = 0;
|
||||
|
||||
private double latest = Double.MAX_VALUE;
|
||||
|
||||
protected BreakActivity(Break aBreak) {
|
||||
counter++;
|
||||
this.aBreak = aBreak;
|
||||
|
|
@ -83,6 +87,8 @@ public class BreakActivity extends AbstractActivity implements JobActivity {
|
|||
this.endTime = breakActivity.getEndTime();
|
||||
this.location = breakActivity.getLocation();
|
||||
setIndex(breakActivity.getIndex());
|
||||
this.earliest = breakActivity.getTheoreticalEarliestOperationStartTime();
|
||||
this.latest = breakActivity.getTheoreticalLatestOperationStartTime();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -118,11 +124,11 @@ public class BreakActivity extends AbstractActivity implements JobActivity {
|
|||
}
|
||||
|
||||
public double getTheoreticalEarliestOperationStartTime() {
|
||||
return aBreak.getTimeWindow().getStart();
|
||||
return earliest;
|
||||
}
|
||||
|
||||
public double getTheoreticalLatestOperationStartTime() {
|
||||
return aBreak.getTimeWindow().getEnd();
|
||||
return latest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -158,6 +164,16 @@ public class BreakActivity extends AbstractActivity implements JobActivity {
|
|||
+ "][twEnd=" + Activities.round(getTheoreticalLatestOperationStartTime()) + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalEarliestOperationStartTime(double earliest) {
|
||||
this.earliest = earliest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalLatestOperationStartTime(double latest) {
|
||||
this.latest = latest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return aBreak.getType();
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc
|
|||
|
||||
private double endTime;
|
||||
|
||||
private double theoreticalEarliest = 0;
|
||||
|
||||
private double theoreticalLatest = Double.MAX_VALUE;
|
||||
|
||||
public DeliverService(Delivery delivery) {
|
||||
super();
|
||||
this.delivery = delivery;
|
||||
|
|
@ -43,6 +47,8 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc
|
|||
this.endTime = deliveryActivity.getEndTime();
|
||||
capacity = deliveryActivity.getSize();
|
||||
setIndex(deliveryActivity.getIndex());
|
||||
this.theoreticalEarliest = deliveryActivity.getTheoreticalEarliestOperationStartTime();
|
||||
this.theoreticalLatest = deliveryActivity.getTheoreticalLatestOperationStartTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -60,14 +66,25 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc
|
|||
return delivery.getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalEarliestOperationStartTime(double earliest) {
|
||||
theoreticalEarliest = earliest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalLatestOperationStartTime(double latest) {
|
||||
theoreticalLatest = latest;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double getTheoreticalEarliestOperationStartTime() {
|
||||
return delivery.getTimeWindow().getStart();
|
||||
return theoreticalEarliest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTheoreticalLatestOperationStartTime() {
|
||||
return delivery.getTimeWindow().getEnd();
|
||||
return theoreticalLatest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ public final class DeliverShipment extends AbstractActivity implements DeliveryA
|
|||
|
||||
private Capacity capacity;
|
||||
|
||||
private double earliest = 0;
|
||||
|
||||
private double latest = Double.MAX_VALUE;
|
||||
|
||||
public DeliverShipment(Shipment shipment) {
|
||||
super();
|
||||
this.shipment = shipment;
|
||||
|
|
@ -45,6 +49,8 @@ public final class DeliverShipment extends AbstractActivity implements DeliveryA
|
|||
this.endTime = deliveryShipmentActivity.getEndTime();
|
||||
this.capacity = deliveryShipmentActivity.getSize();
|
||||
setIndex(deliveryShipmentActivity.getIndex());
|
||||
this.earliest = deliveryShipmentActivity.getTheoreticalEarliestOperationStartTime();
|
||||
this.latest = deliveryShipmentActivity.getTheoreticalLatestOperationStartTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -52,6 +58,16 @@ public final class DeliverShipment extends AbstractActivity implements DeliveryA
|
|||
return shipment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalEarliestOperationStartTime(double earliest) {
|
||||
this.earliest = earliest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalLatestOperationStartTime(double latest) {
|
||||
this.latest = latest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "deliverShipment";
|
||||
|
|
@ -69,12 +85,12 @@ public final class DeliverShipment extends AbstractActivity implements DeliveryA
|
|||
|
||||
@Override
|
||||
public double getTheoreticalEarliestOperationStartTime() {
|
||||
return shipment.getDeliveryTimeWindow().getStart();
|
||||
return earliest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTheoreticalLatestOperationStartTime() {
|
||||
return shipment.getDeliveryTimeWindow().getEnd();
|
||||
return latest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ public final class PickupService extends AbstractActivity implements PickupActiv
|
|||
|
||||
private double depTime;
|
||||
|
||||
private double theoreticalEarliest = 0;
|
||||
|
||||
private double theoreticalLatest = Double.MAX_VALUE;
|
||||
|
||||
public PickupService(Pickup pickup) {
|
||||
super();
|
||||
this.pickup = pickup;
|
||||
|
|
@ -44,6 +48,8 @@ public final class PickupService extends AbstractActivity implements PickupActiv
|
|||
this.arrTime = pickupActivity.getArrTime();
|
||||
this.depTime = pickupActivity.getEndTime();
|
||||
setIndex(pickupActivity.getIndex());
|
||||
this.theoreticalEarliest = pickupActivity.getTheoreticalEarliestOperationStartTime();
|
||||
this.theoreticalLatest = pickupActivity.getTheoreticalLatestOperationStartTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -63,12 +69,22 @@ public final class PickupService extends AbstractActivity implements PickupActiv
|
|||
|
||||
@Override
|
||||
public double getTheoreticalEarliestOperationStartTime() {
|
||||
return pickup.getTimeWindow().getStart();
|
||||
return theoreticalEarliest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTheoreticalLatestOperationStartTime() {
|
||||
return pickup.getTimeWindow().getEnd();
|
||||
return theoreticalLatest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalEarliestOperationStartTime(double earliest) {
|
||||
this.theoreticalEarliest = earliest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalLatestOperationStartTime(double latest) {
|
||||
this.theoreticalLatest = latest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import jsprit.core.problem.Location;
|
|||
import jsprit.core.problem.job.Job;
|
||||
import jsprit.core.problem.job.Shipment;
|
||||
|
||||
public final class PickupShipment extends AbstractActivity implements PickupActivity {
|
||||
public final class PickupShipment extends AbstractActivity implements PickupActivity{
|
||||
|
||||
private Shipment shipment;
|
||||
|
||||
|
|
@ -30,6 +30,10 @@ public final class PickupShipment extends AbstractActivity implements PickupActi
|
|||
|
||||
private double arrTime;
|
||||
|
||||
private double earliest = 0;
|
||||
|
||||
private double latest = Double.MAX_VALUE;
|
||||
|
||||
public PickupShipment(Shipment shipment) {
|
||||
super();
|
||||
this.shipment = shipment;
|
||||
|
|
@ -41,6 +45,8 @@ public final class PickupShipment extends AbstractActivity implements PickupActi
|
|||
this.arrTime = pickupShipmentActivity.getArrTime();
|
||||
this.endTime = pickupShipmentActivity.getEndTime();
|
||||
setIndex(pickupShipmentActivity.getIndex());
|
||||
this.earliest = pickupShipmentActivity.getTheoreticalEarliestOperationStartTime();
|
||||
this.latest = pickupShipmentActivity.getTheoreticalLatestOperationStartTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -48,6 +54,16 @@ public final class PickupShipment extends AbstractActivity implements PickupActi
|
|||
return shipment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalEarliestOperationStartTime(double earliest) {
|
||||
this.earliest = earliest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalLatestOperationStartTime(double latest) {
|
||||
this.latest = latest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "pickupShipment";
|
||||
|
|
@ -65,12 +81,12 @@ public final class PickupShipment extends AbstractActivity implements PickupActi
|
|||
|
||||
@Override
|
||||
public double getTheoreticalEarliestOperationStartTime() {
|
||||
return shipment.getPickupTimeWindow().getStart();
|
||||
return earliest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTheoreticalLatestOperationStartTime() {
|
||||
return shipment.getPickupTimeWindow().getEnd();
|
||||
return latest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -22,14 +22,22 @@ import jsprit.core.problem.Location;
|
|||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.solution.route.activity.TourActivity.JobActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ServiceActivity extends AbstractActivity implements JobActivity {
|
||||
|
||||
@Deprecated
|
||||
public static int counter = 0;
|
||||
|
||||
public double arrTime;
|
||||
|
||||
public double endTime;
|
||||
|
||||
private double theoreticalEarliest;
|
||||
|
||||
private double theoreticalLatest;
|
||||
|
||||
/**
|
||||
* @return the arrTime
|
||||
*/
|
||||
|
|
@ -80,6 +88,8 @@ public class ServiceActivity extends AbstractActivity implements JobActivity {
|
|||
this.arrTime = serviceActivity.getArrTime();
|
||||
this.endTime = serviceActivity.getEndTime();
|
||||
setIndex(serviceActivity.getIndex());
|
||||
this.theoreticalEarliest = serviceActivity.getTheoreticalEarliestOperationStartTime();
|
||||
this.theoreticalLatest = serviceActivity.getTheoreticalLatestOperationStartTime();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -115,11 +125,21 @@ public class ServiceActivity extends AbstractActivity implements JobActivity {
|
|||
}
|
||||
|
||||
public double getTheoreticalEarliestOperationStartTime() {
|
||||
return service.getTimeWindow().getStart();
|
||||
return theoreticalEarliest;
|
||||
}
|
||||
|
||||
public double getTheoreticalLatestOperationStartTime() {
|
||||
return service.getTimeWindow().getEnd();
|
||||
return theoreticalLatest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalEarliestOperationStartTime(double earliest) {
|
||||
theoreticalEarliest = earliest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTheoreticalLatestOperationStartTime(double latest) {
|
||||
theoreticalLatest = latest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -97,10 +97,12 @@ public final class Start extends AbstractActivity implements TourActivity {
|
|||
return theoretical_latestOperationStartTime;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setTheoreticalEarliestOperationStartTime(double time) {
|
||||
this.theoretical_earliestOperationStartTime = time;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setTheoreticalLatestOperationStartTime(double time) {
|
||||
this.theoretical_latestOperationStartTime = time;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
package jsprit.core.problem.solution.route.activity;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Created by schroeder on 20/05/15.
|
||||
*/
|
||||
public interface TimeWindows {
|
||||
|
||||
public Collection<TimeWindow> getTimeWindows();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
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){
|
||||
for(TimeWindow tw : timeWindows){
|
||||
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);
|
||||
}
|
||||
if(timeWindow.getStart() <= tw.getStart() && timeWindow.getEnd() >= tw.getEnd()){
|
||||
throw new IllegalStateException("time-windows cannot overlap each other. overlap: " + tw + ", " + timeWindow);
|
||||
}
|
||||
}
|
||||
timeWindows.add(timeWindow);
|
||||
}
|
||||
|
||||
public Collection<TimeWindow> getTimeWindows() {
|
||||
return Collections.unmodifiableCollection(timeWindows);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -30,6 +30,10 @@ import jsprit.core.problem.job.Job;
|
|||
*/
|
||||
public interface TourActivity extends HasIndex {
|
||||
|
||||
public void setTheoreticalEarliestOperationStartTime(double earliest);
|
||||
|
||||
public void setTheoreticalLatestOperationStartTime(double latest);
|
||||
|
||||
/**
|
||||
* Basic interface of job-activies.
|
||||
* <p/>
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ package jsprit.core.util;
|
|||
|
||||
import jsprit.core.problem.cost.ForwardTransportTime;
|
||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||
import jsprit.core.problem.solution.route.activity.ActivityVisitor;
|
||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||
import jsprit.core.problem.solution.route.activity.*;
|
||||
|
||||
public class ActivityTimeTracker implements ActivityVisitor {
|
||||
|
||||
|
|
@ -43,17 +42,27 @@ public class ActivityTimeTracker implements ActivityVisitor {
|
|||
|
||||
private double actEndTime;
|
||||
|
||||
private ActivityPolicy activityPolicy = ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS;
|
||||
private ActivityStartStrategy startStrategy;
|
||||
|
||||
public ActivityTimeTracker(ForwardTransportTime transportTime) {
|
||||
super();
|
||||
this.transportTime = transportTime;
|
||||
}
|
||||
public ActivityTimeTracker(ForwardTransportTime transportTime) {
|
||||
super();
|
||||
this.transportTime = transportTime;
|
||||
this.startStrategy = new ActivityStartsAsSoonAsTimeWindowOpens();
|
||||
}
|
||||
|
||||
public ActivityTimeTracker(ForwardTransportTime transportTime, ActivityPolicy activityPolicy) {
|
||||
super();
|
||||
this.transportTime = transportTime;
|
||||
this.activityPolicy = activityPolicy;
|
||||
if(activityPolicy.equals(ActivityPolicy.AS_SOON_AS_ARRIVED)){
|
||||
this.startStrategy = new ActivityStartAsSoonAsArrived();
|
||||
}
|
||||
else this.startStrategy = new ActivityStartsAsSoonAsTimeWindowOpens();
|
||||
}
|
||||
|
||||
public ActivityTimeTracker(ForwardTransportTime transportTime, ActivityStartStrategy startStrategy) {
|
||||
super();
|
||||
this.transportTime = transportTime;
|
||||
this.startStrategy = startStrategy;
|
||||
}
|
||||
|
||||
public double getActArrTime() {
|
||||
|
|
@ -75,36 +84,22 @@ public class ActivityTimeTracker implements ActivityVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(TourActivity activity) {
|
||||
if (!beginFirst) throw new IllegalStateException("never called begin. this however is essential here");
|
||||
if(!beginFirst) throw new IllegalStateException("never called begin. this however is essential here");
|
||||
double transportTime = this.transportTime.getTransportTime(prevAct.getLocation(), activity.getLocation(), startAtPrevAct, route.getDriver(), route.getVehicle());
|
||||
double arrivalTimeAtCurrAct = startAtPrevAct + transportTime;
|
||||
|
||||
actArrTime = arrivalTimeAtCurrAct;
|
||||
double operationStartTime;
|
||||
|
||||
if (activityPolicy.equals(ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS)) {
|
||||
operationStartTime = Math.max(activity.getTheoreticalEarliestOperationStartTime(), arrivalTimeAtCurrAct);
|
||||
} else if (activityPolicy.equals(ActivityPolicy.AS_SOON_AS_ARRIVED)) {
|
||||
operationStartTime = actArrTime;
|
||||
} else operationStartTime = actArrTime;
|
||||
|
||||
double operationEndTime = operationStartTime + activity.getOperationTime();
|
||||
|
||||
double operationEndTime = startStrategy.getActivityStartTime(activity,arrivalTimeAtCurrAct) + activity.getOperationTime();
|
||||
actEndTime = operationEndTime;
|
||||
|
||||
prevAct = activity;
|
||||
startAtPrevAct = operationEndTime;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
double transportTime = this.transportTime.getTransportTime(prevAct.getLocation(), route.getEnd().getLocation(), startAtPrevAct, route.getDriver(), route.getVehicle());
|
||||
double arrivalTimeAtCurrAct = startAtPrevAct + transportTime;
|
||||
|
||||
actArrTime = arrivalTimeAtCurrAct;
|
||||
actEndTime = arrivalTimeAtCurrAct;
|
||||
|
||||
beginFirst = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2014 Stefan Schroeder
|
||||
*
|
||||
|
|
@ -29,7 +30,7 @@ public class CalculationUtils {
|
|||
* @param act
|
||||
* @return
|
||||
*/
|
||||
public static double getActivityEndTime(double actArrTime, TourActivity act) {
|
||||
return Math.max(actArrTime, act.getTheoreticalEarliestOperationStartTime()) + act.getOperationTime();
|
||||
public static double getActivityEndTime(double actArrTime, TourActivity act){
|
||||
return Math.max(actArrTime, act.getTheoreticalEarliestOperationStartTime()) + act.getOperationTime();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
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.Break;
|
||||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||
import jsprit.core.problem.solution.route.activity.BreakActivity;
|
||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||
import jsprit.core.problem.vehicle.VehicleType;
|
||||
import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||
import jsprit.core.util.Solutions;
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Created by schroeder on 08/01/16.
|
||||
*/
|
||||
public class IgnoreBreakTimeWindowTest {
|
||||
|
||||
@Test
|
||||
public void doNotIgnoreBreakTW(){
|
||||
VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType");
|
||||
VehicleType vehicleType = vehicleTypeBuilder.setCostPerWaitingTime(0.8).build();
|
||||
|
||||
/*
|
||||
* get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType"
|
||||
*/
|
||||
|
||||
VehicleImpl vehicle2;
|
||||
{
|
||||
VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance("v2");
|
||||
vehicleBuilder.setStartLocation(Location.newInstance(0, 0));
|
||||
vehicleBuilder.setType(vehicleType);
|
||||
vehicleBuilder.setEarliestStart(10).setLatestArrival(50);
|
||||
vehicleBuilder.setBreak(Break.Builder.newInstance("lunch").setTimeWindow(TimeWindow.newInstance(14, 14)).setServiceTime(1.).build());
|
||||
vehicle2 = vehicleBuilder.build();
|
||||
}
|
||||
/*
|
||||
* build services at the required locations, each with a capacity-demand of 1.
|
||||
*/
|
||||
|
||||
|
||||
Service service4 = Service.Builder.newInstance("2").setLocation(Location.newInstance(0, 0))
|
||||
.setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(17,17)).build();
|
||||
|
||||
Service service5 = Service.Builder.newInstance("3").setLocation(Location.newInstance(0, 0))
|
||||
.setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(18, 18)).build();
|
||||
|
||||
Service service7 = Service.Builder.newInstance("4").setLocation(Location.newInstance(0, 0))
|
||||
.setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(10, 10)).build();
|
||||
|
||||
Service service8 = Service.Builder.newInstance("5").setLocation(Location.newInstance(0, 0))
|
||||
.setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(12, 12)).build();
|
||||
|
||||
Service service10 = Service.Builder.newInstance("6").setLocation(Location.newInstance(0, 0))
|
||||
.setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(16, 16)).build();
|
||||
|
||||
Service service11 = Service.Builder.newInstance("7").setLocation(Location.newInstance(0, 0))
|
||||
.setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(13, 13)).build();
|
||||
|
||||
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance()
|
||||
.addVehicle(vehicle2)
|
||||
.addJob(service4)
|
||||
.addJob(service5).addJob(service7)
|
||||
.addJob(service8).addJob(service10).addJob(service11)
|
||||
.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE)
|
||||
.build();
|
||||
|
||||
VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);
|
||||
vra.setMaxIterations(50);
|
||||
|
||||
VehicleRoutingProblemSolution solution = Solutions.bestOf(vra.searchSolutions());
|
||||
|
||||
|
||||
Assert.assertTrue(breakShouldBeTime(solution));
|
||||
}
|
||||
|
||||
private boolean breakShouldBeTime(VehicleRoutingProblemSolution solution) {
|
||||
boolean inTime = true;
|
||||
for(TourActivity act : solution.getRoutes().iterator().next().getActivities()){
|
||||
if(act instanceof BreakActivity){
|
||||
if(act.getEndTime() < ((BreakActivity) act).getJob().getTimeWindow().getStart()){
|
||||
inTime = false;
|
||||
}
|
||||
if(act.getArrTime() > ((BreakActivity) act).getJob().getTimeWindow().getEnd()){
|
||||
inTime = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return inTime;
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -124,6 +124,7 @@ public class TestCalculatesServiceInsertion {
|
|||
states.updateLoadStates();
|
||||
states.updateTimeWindowStates();
|
||||
|
||||
|
||||
ConstraintManager cManager = new ConstraintManager(vrp, states);
|
||||
cManager.addLoadConstraint();
|
||||
cManager.addTimeWindowConstraint();
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import jsprit.core.problem.solution.route.VehicleRoute;
|
|||
import jsprit.core.problem.solution.route.activity.DeliverShipment;
|
||||
import jsprit.core.problem.solution.route.activity.PickupService;
|
||||
import jsprit.core.problem.solution.route.activity.PickupShipment;
|
||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||
import jsprit.core.problem.vehicle.VehicleType;
|
||||
|
|
@ -53,6 +54,8 @@ public class TestInserter {
|
|||
when(vehicle.isReturnToDepot()).thenReturn(true);
|
||||
when(vehicle.getId()).thenReturn("vehId");
|
||||
|
||||
when(service.getTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addService(service).build();
|
||||
//start - pick(shipment) - del(shipment) - end
|
||||
Service serviceToInsert = mock(Service.class);
|
||||
|
|
@ -88,6 +91,8 @@ public class TestInserter {
|
|||
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||
when(vehicle.getId()).thenReturn("vehId");
|
||||
|
||||
when(service.getTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addService(service).build();
|
||||
Service serviceToInsert = mock(Service.class);
|
||||
when(serviceToInsert.getLocation()).thenReturn(Location.Builder.newInstance().setId("delLoc").build());
|
||||
|
|
@ -125,6 +130,9 @@ public class TestInserter {
|
|||
when(vehicle.isReturnToDepot()).thenReturn(true);
|
||||
when(vehicle.getId()).thenReturn("vehId");
|
||||
|
||||
when(shipment.getPickupTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
when(shipment.getDeliveryTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build();
|
||||
//start - pick(shipment) - del(shipment) - end
|
||||
Shipment shipmentToInsert = Shipment.Builder.newInstance("s").setDeliveryLocation(Location.newInstance("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build();
|
||||
|
|
@ -161,6 +169,9 @@ public class TestInserter {
|
|||
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||
when(vehicle.getId()).thenReturn("vehId");
|
||||
|
||||
when(shipment.getPickupTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
when(shipment.getDeliveryTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build();
|
||||
//start - pick(shipment) - del(shipment) - end
|
||||
Shipment shipmentToInsert = Shipment.Builder.newInstance("s").setDeliveryLocation(Location.newInstance("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build();
|
||||
|
|
@ -188,6 +199,9 @@ public class TestInserter {
|
|||
Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setStartLocation(Location.newInstance("vehLoc")).setType(mock(VehicleType.class)).build();
|
||||
Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setStartLocation(Location.newInstance("newVehLoc")).setType(mock(VehicleType.class)).build();
|
||||
|
||||
when(shipment.getPickupTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
when(shipment.getDeliveryTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build();
|
||||
//start - pick(shipment) - del(shipment) - end
|
||||
Shipment shipmentToInsert = Shipment.Builder.newInstance("s").setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).setDeliveryLocation(Location.newInstance("delLoc")).build();
|
||||
|
|
@ -213,6 +227,9 @@ public class TestInserter {
|
|||
Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setReturnToDepot(false).setStartLocation(Location.newInstance("vehLoc")).setType(mock(VehicleType.class)).build();
|
||||
Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setReturnToDepot(false).setStartLocation(Location.newInstance("newVehLoc")).setType(mock(VehicleType.class)).build();
|
||||
|
||||
when(shipment.getPickupTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
when(shipment.getDeliveryTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build();
|
||||
//start - pick(shipment) - del(shipment) - end
|
||||
Shipment shipmentToInsert = Shipment.Builder.newInstance("s").setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).setDeliveryLocation(Location.newInstance("delLoc")).build();
|
||||
|
|
@ -239,6 +256,9 @@ public class TestInserter {
|
|||
Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setReturnToDepot(false).setStartLocation(Location.Builder.newInstance().setId("vehLoc").build()).setType(mock(VehicleType.class)).build();
|
||||
Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setReturnToDepot(false).setStartLocation(Location.Builder.newInstance().setId("newVehLoc").build()).setType(mock(VehicleType.class)).build();
|
||||
|
||||
when(shipment.getPickupTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
when(shipment.getDeliveryTimeWindow()).thenReturn(mock(TimeWindow.class));
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build();
|
||||
//start - pick(shipment) - del(shipment) - end
|
||||
Shipment shipmentToInsert = Shipment.Builder.newInstance("s").setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).setDeliveryLocation(Location.newInstance("delLoc")).build();
|
||||
|
|
|
|||
|
|
@ -171,6 +171,8 @@ public class TestLocalActivityInsertionCostsCalculator {
|
|||
TourActivity prevAct = vrp.getActivities(prevS).get(0);
|
||||
TourActivity newAct = vrp.getActivities(newS).get(0);
|
||||
TourActivity nextAct = vrp.getActivities(nextS).get(0);
|
||||
nextAct.setTheoreticalEarliestOperationStartTime(40);
|
||||
nextAct.setTheoreticalLatestOperationStartTime(80);
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(v).setJobActivityFactory(vrp.getJobActivityFactory()).addService(prevS).addService(nextS).build();
|
||||
JobInsertionContext context = new JobInsertionContext(route, newS, v, null, 0.);
|
||||
|
|
@ -204,6 +206,9 @@ public class TestLocalActivityInsertionCostsCalculator {
|
|||
Start prevAct = new Start(Location.newInstance(0, 0), 0, 100);
|
||||
TourActivity newAct = vrp.getActivities(newS).get(0);
|
||||
TourActivity nextAct = vrp.getActivities(nextS).get(0);
|
||||
nextAct.setTheoreticalEarliestOperationStartTime(40);
|
||||
nextAct.setTheoreticalLatestOperationStartTime(50);
|
||||
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(v).setJobActivityFactory(vrp.getJobActivityFactory()).addService(nextS).build();
|
||||
JobInsertionContext context = new JobInsertionContext(route, newS, v, null, 0.);
|
||||
|
|
@ -228,6 +233,9 @@ public class TestLocalActivityInsertionCostsCalculator {
|
|||
Start prevAct = new Start(Location.newInstance(0, 0), 0, 100);
|
||||
TourActivity newAct = vrp.getActivities(newS).get(0);
|
||||
TourActivity nextAct = vrp.getActivities(nextS).get(0);
|
||||
nextAct.setTheoreticalEarliestOperationStartTime(140);
|
||||
nextAct.setTheoreticalLatestOperationStartTime(150);
|
||||
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(v2).setJobActivityFactory(vrp.getJobActivityFactory()).addService(nextS).build();
|
||||
JobInsertionContext context = new JobInsertionContext(route, newS, v2, null, 0.);
|
||||
|
|
@ -248,6 +256,9 @@ public class TestLocalActivityInsertionCostsCalculator {
|
|||
|
||||
Start prevAct = new Start(Location.newInstance(0, 0), 0, 100);
|
||||
TourActivity newAct = vrp.getActivities(newS).get(0);
|
||||
newAct.setTheoreticalEarliestOperationStartTime(100);
|
||||
newAct.setTheoreticalLatestOperationStartTime(150);
|
||||
|
||||
End nextAct = new End(Location.newInstance(0, 0), 0, 100);
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(v).setJobActivityFactory(vrp.getJobActivityFactory()).build();
|
||||
|
|
@ -273,6 +284,9 @@ public class TestLocalActivityInsertionCostsCalculator {
|
|||
TourActivity prevAct = vrp.getActivities(prevS).get(0);
|
||||
TourActivity newAct = vrp.getActivities(newS).get(0);
|
||||
TourActivity nextAct = vrp.getActivities(nextS).get(0);
|
||||
nextAct.setTheoreticalEarliestOperationStartTime(40);
|
||||
nextAct.setTheoreticalLatestOperationStartTime(50);
|
||||
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(v).setJobActivityFactory(vrp.getJobActivityFactory()).addService(prevS).addService(nextS).build();
|
||||
JobInsertionContext context = new JobInsertionContext(route, newS, v, null, 0.);
|
||||
|
|
@ -296,7 +310,13 @@ public class TestLocalActivityInsertionCostsCalculator {
|
|||
|
||||
TourActivity prevAct = vrp.getActivities(prevS).get(0);
|
||||
TourActivity newAct = vrp.getActivities(newS).get(0);
|
||||
newAct.setTheoreticalEarliestOperationStartTime(100);
|
||||
newAct.setTheoreticalLatestOperationStartTime(120);
|
||||
|
||||
TourActivity nextAct = vrp.getActivities(nextS).get(0);
|
||||
nextAct.setTheoreticalEarliestOperationStartTime(40);
|
||||
nextAct.setTheoreticalLatestOperationStartTime(500);
|
||||
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(v).setJobActivityFactory(vrp.getJobActivityFactory()).addService(prevS).addService(nextS).build();
|
||||
JobInsertionContext context = new JobInsertionContext(route, newS, v, null, 0.);
|
||||
|
|
@ -323,7 +343,13 @@ public class TestLocalActivityInsertionCostsCalculator {
|
|||
|
||||
TourActivity prevAct = vrp.getActivities(prevS).get(0);
|
||||
TourActivity newAct = vrp.getActivities(newS).get(0);
|
||||
newAct.setTheoreticalEarliestOperationStartTime(100);
|
||||
newAct.setTheoreticalLatestOperationStartTime(120);
|
||||
|
||||
TourActivity nextAct = vrp.getActivities(nextS).get(0);
|
||||
nextAct.setTheoreticalEarliestOperationStartTime(400);
|
||||
nextAct.setTheoreticalLatestOperationStartTime(500);
|
||||
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(v).setJobActivityFactory(vrp.getJobActivityFactory()).addService(prevS).addService(nextS).addService(afterNextS).build();
|
||||
|
||||
|
|
@ -358,7 +384,21 @@ public class TestLocalActivityInsertionCostsCalculator {
|
|||
|
||||
TourActivity prevAct = vrp.getActivities(prevS).get(0);
|
||||
TourActivity newAct = vrp.getActivities(newS).get(0);
|
||||
newAct.setTheoreticalEarliestOperationStartTime(100);
|
||||
newAct.setTheoreticalLatestOperationStartTime(120);
|
||||
|
||||
TourActivity nextAct = vrp.getActivities(nextS).get(0);
|
||||
nextAct.setTheoreticalEarliestOperationStartTime(40);
|
||||
nextAct.setTheoreticalLatestOperationStartTime(500);
|
||||
|
||||
TourActivity afterNextAct = vrp.getActivities(afterNextS).get(0);
|
||||
afterNextAct.setTheoreticalEarliestOperationStartTime(80);
|
||||
afterNextAct.setTheoreticalLatestOperationStartTime(500);
|
||||
|
||||
TourActivity afterAfterNextAct = vrp.getActivities(afterAfterNextS).get(0);
|
||||
afterAfterNextAct.setTheoreticalEarliestOperationStartTime(100);
|
||||
afterAfterNextAct.setTheoreticalLatestOperationStartTime(500);
|
||||
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(v).setJobActivityFactory(vrp.getJobActivityFactory()).addService(prevS).addService(nextS).addService(afterNextS).addService(afterAfterNextS).build();
|
||||
|
||||
|
|
@ -396,7 +436,20 @@ public class TestLocalActivityInsertionCostsCalculator {
|
|||
|
||||
TourActivity prevAct = vrp.getActivities(prevS).get(0);
|
||||
TourActivity newAct = vrp.getActivities(newS).get(0);
|
||||
newAct.setTheoreticalEarliestOperationStartTime(100);
|
||||
newAct.setTheoreticalLatestOperationStartTime(120);
|
||||
|
||||
TourActivity nextAct = vrp.getActivities(nextS).get(0);
|
||||
nextAct.setTheoreticalEarliestOperationStartTime(40);
|
||||
nextAct.setTheoreticalLatestOperationStartTime(500);
|
||||
|
||||
TourActivity afterNextAct = vrp.getActivities(afterNextS).get(0);
|
||||
afterNextAct.setTheoreticalEarliestOperationStartTime(80);
|
||||
afterNextAct.setTheoreticalLatestOperationStartTime(500);
|
||||
|
||||
TourActivity afterAfterNextAct = vrp.getActivities(afterAfterNextS).get(0);
|
||||
afterAfterNextAct.setTheoreticalEarliestOperationStartTime(100);
|
||||
afterAfterNextAct.setTheoreticalLatestOperationStartTime(500);
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(v).setJobActivityFactory(vrp.getJobActivityFactory()).addService(prevS).addService(nextS).addService(afterNextS).addService(afterAfterNextS).build();
|
||||
JobInsertionContext context = new JobInsertionContext(route, newS, v, null, 0.);
|
||||
|
|
@ -438,7 +491,21 @@ public class TestLocalActivityInsertionCostsCalculator {
|
|||
|
||||
TourActivity prevAct = vrp.getActivities(prevS).get(0);
|
||||
TourActivity newAct = vrp.getActivities(newS).get(0);
|
||||
newAct.setTheoreticalEarliestOperationStartTime(100);
|
||||
newAct.setTheoreticalLatestOperationStartTime(120);
|
||||
|
||||
TourActivity nextAct = vrp.getActivities(nextS).get(0);
|
||||
nextAct.setTheoreticalEarliestOperationStartTime(40);
|
||||
nextAct.setTheoreticalLatestOperationStartTime(500);
|
||||
|
||||
TourActivity afterNextAct = vrp.getActivities(afterNextS).get(0);
|
||||
afterNextAct.setTheoreticalEarliestOperationStartTime(80);
|
||||
afterNextAct.setTheoreticalLatestOperationStartTime(500);
|
||||
|
||||
TourActivity afterAfterNextAct = vrp.getActivities(afterAfterNextS).get(0);
|
||||
afterAfterNextAct.setTheoreticalEarliestOperationStartTime(100);
|
||||
afterAfterNextAct.setTheoreticalLatestOperationStartTime(500);
|
||||
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(v).setJobActivityFactory(vrp.getJobActivityFactory()).addService(prevS).addService(nextS).addService(afterNextS).addService(afterAfterNextS).build();
|
||||
JobInsertionContext context = new JobInsertionContext(route, newS, v, null, 0.);
|
||||
|
|
@ -478,13 +545,29 @@ public class TestLocalActivityInsertionCostsCalculator {
|
|||
.addJob(afterNextS).addJob(afterAfterNextS).build();
|
||||
|
||||
TourActivity prevAct = vrp.getActivities(prevS).get(0);
|
||||
|
||||
TourActivity newAct = vrp.getActivities(newS).get(0);
|
||||
newAct.setTheoreticalEarliestOperationStartTime(50);
|
||||
newAct.setTheoreticalLatestOperationStartTime(70);
|
||||
|
||||
TourActivity nextAct = vrp.getActivities(nextS).get(0);
|
||||
nextAct.setTheoreticalEarliestOperationStartTime(40);
|
||||
nextAct.setTheoreticalLatestOperationStartTime(70);
|
||||
|
||||
TourActivity afterNextAct = vrp.getActivities(afterNextS).get(0);
|
||||
afterNextAct.setTheoreticalEarliestOperationStartTime(50);
|
||||
afterNextAct.setTheoreticalEarliestOperationStartTime(100);
|
||||
|
||||
TourActivity afterAfterNextAct = vrp.getActivities(afterAfterNextS).get(0);
|
||||
afterAfterNextAct.setTheoreticalEarliestOperationStartTime(100);
|
||||
afterAfterNextAct.setTheoreticalEarliestOperationStartTime(500);
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(v).setJobActivityFactory(vrp.getJobActivityFactory()).addService(prevS).addService(nextS).addService(afterNextS).addService(afterAfterNextS).build();
|
||||
JobInsertionContext context = new JobInsertionContext(route, newS, v, null, 0.);
|
||||
|
||||
StateManager stateManager = getStateManager(vrp, route);
|
||||
stateManager.updateTimeWindowStates();
|
||||
stateManager.informInsertionStarts(Arrays.asList(route),new ArrayList<Job>());
|
||||
|
||||
LocalActivityInsertionCostsCalculator calc = new LocalActivityInsertionCostsCalculator(CostFactory.createEuclideanCosts(), new WaitingTimeCosts(), stateManager);
|
||||
calc.setSolutionCompletenessRatio(1.);
|
||||
|
|
|
|||
|
|
@ -84,6 +84,15 @@ public class TestRouteLevelActivityInsertionCostEstimator {
|
|||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
final VehicleRoutingProblem vrp = vrpBuilder.addJob(s1).addJob(s2).addJob(s3).build();
|
||||
|
||||
vrp.getActivities(s1).get(0).setTheoreticalEarliestOperationStartTime(10);
|
||||
vrp.getActivities(s1).get(0).setTheoreticalLatestOperationStartTime(10);
|
||||
|
||||
vrp.getActivities(s2).get(0).setTheoreticalEarliestOperationStartTime(20);
|
||||
vrp.getActivities(s2).get(0).setTheoreticalLatestOperationStartTime(20);
|
||||
|
||||
vrp.getActivities(s3).get(0).setTheoreticalEarliestOperationStartTime(30);
|
||||
vrp.getActivities(s3).get(0).setTheoreticalLatestOperationStartTime(30);
|
||||
|
||||
route = VehicleRoute.Builder.newInstance(vehicle).setJobActivityFactory(new JobActivityFactory() {
|
||||
@Override
|
||||
public List<AbstractActivity> createActivities(Job job) {
|
||||
|
|
@ -123,6 +132,9 @@ public class TestRouteLevelActivityInsertionCostEstimator {
|
|||
public void whenNewActWithTWAndServiceTimeInBetweenFirstAndSecond_and_forwardLookingIs0_itShouldReturnCorrectCosts() {
|
||||
Service s4 = Service.Builder.newInstance("s4").setLocation(Location.newInstance("5,0")).setServiceTime(10.).setTimeWindow(TimeWindow.newInstance(5., 5.)).build();
|
||||
PickupActivity pickupService = new PickupService(s4);
|
||||
pickupService.setTheoreticalEarliestOperationStartTime(5);
|
||||
pickupService.setTheoreticalLatestOperationStartTime(5);
|
||||
|
||||
JobInsertionContext context = new JobInsertionContext(route, s4, route.getVehicle(), route.getDriver(), 0.);
|
||||
RouteLevelActivityInsertionCostsEstimator estimator = new RouteLevelActivityInsertionCostsEstimator(routingCosts, activityCosts, stateManager);
|
||||
estimator.setForwardLooking(0);
|
||||
|
|
@ -177,6 +189,8 @@ public class TestRouteLevelActivityInsertionCostEstimator {
|
|||
public void whenNewActWithTWInBetweenSecondAndThird_and_forwardLookingIs3_itShouldReturnCorrectCosts() {
|
||||
Service s4 = Service.Builder.newInstance("s4").setLocation(Location.newInstance("5,0")).setTimeWindow(TimeWindow.newInstance(5., 5.)).build();
|
||||
PickupActivity pickupService = new PickupService(s4);
|
||||
pickupService.setTheoreticalEarliestOperationStartTime(5);
|
||||
pickupService.setTheoreticalLatestOperationStartTime(5);
|
||||
JobInsertionContext context = new JobInsertionContext(route, s4, route.getVehicle(), route.getDriver(), 0.);
|
||||
RouteLevelActivityInsertionCostsEstimator estimator = new RouteLevelActivityInsertionCostsEstimator(routingCosts, activityCosts, stateManager);
|
||||
estimator.setForwardLooking(3);
|
||||
|
|
|
|||
|
|
@ -96,6 +96,15 @@ public class TestRouteLevelServiceInsertionCostEstimator {
|
|||
vrpBuilder.addVehicle(vehicle);
|
||||
vrp = vrpBuilder.build();
|
||||
|
||||
vrp.getActivities(s1).get(0).setTheoreticalEarliestOperationStartTime(10);
|
||||
vrp.getActivities(s1).get(0).setTheoreticalLatestOperationStartTime(10);
|
||||
|
||||
vrp.getActivities(s2).get(0).setTheoreticalEarliestOperationStartTime(20);
|
||||
vrp.getActivities(s2).get(0).setTheoreticalLatestOperationStartTime(20);
|
||||
|
||||
vrp.getActivities(s3).get(0).setTheoreticalEarliestOperationStartTime(30);
|
||||
vrp.getActivities(s3).get(0).setTheoreticalLatestOperationStartTime(30);
|
||||
|
||||
activityFactory = new JobActivityFactory() {
|
||||
@Override
|
||||
public List<AbstractActivity> createActivities(Job job) {
|
||||
|
|
@ -169,7 +178,10 @@ public class TestRouteLevelServiceInsertionCostEstimator {
|
|||
public List<AbstractActivity> createActivities(Job job) {
|
||||
List<AbstractActivity> acts = activityFactory.createActivities(job);
|
||||
if (acts.isEmpty()) {
|
||||
acts.add(new PickupService(s4));
|
||||
PickupService pickupService = new PickupService(s4);
|
||||
pickupService.setTheoreticalEarliestOperationStartTime(5);
|
||||
pickupService.setTheoreticalLatestOperationStartTime(5);
|
||||
acts.add(pickupService);
|
||||
}
|
||||
return acts;
|
||||
}
|
||||
|
|
@ -195,7 +207,10 @@ public class TestRouteLevelServiceInsertionCostEstimator {
|
|||
public List<AbstractActivity> createActivities(Job job) {
|
||||
List<AbstractActivity> acts = activityFactory.createActivities(job);
|
||||
if (acts.isEmpty()) {
|
||||
acts.add(new PickupService(s4));
|
||||
PickupService pickupService = new PickupService(s4);
|
||||
pickupService.setTheoreticalEarliestOperationStartTime(5);
|
||||
pickupService.setTheoreticalLatestOperationStartTime(5);
|
||||
acts.add(pickupService);
|
||||
}
|
||||
return acts;
|
||||
}
|
||||
|
|
@ -220,7 +235,10 @@ public class TestRouteLevelServiceInsertionCostEstimator {
|
|||
public List<AbstractActivity> createActivities(Job job) {
|
||||
List<AbstractActivity> acts = activityFactory.createActivities(job);
|
||||
if (acts.isEmpty()) {
|
||||
acts.add(new PickupService(s4));
|
||||
PickupService pickupService = new PickupService(s4);
|
||||
pickupService.setTheoreticalEarliestOperationStartTime(3);
|
||||
pickupService.setTheoreticalLatestOperationStartTime(3);
|
||||
acts.add(pickupService);
|
||||
}
|
||||
return acts;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
|||
import jsprit.core.problem.job.Job;
|
||||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||
import jsprit.core.problem.vehicle.FiniteFleetManagerFactory;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
import jsprit.core.problem.vehicle.VehicleFleetManager;
|
||||
|
|
@ -179,4 +180,40 @@ public class UpdateVehicleDependentTimeWindowTest {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void twUpdateShouldWorkWithMultipleTWs(){
|
||||
//
|
||||
VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("0,0")).setEarliestStart(0.).setLatestArrival(100.).build();
|
||||
Service service = Service.Builder.newInstance("s1").setLocation(Location.newInstance("10,0"))
|
||||
.addTimeWindow(10,20).addTimeWindow(30,40).build();
|
||||
Service service2 = Service.Builder.newInstance("s2")
|
||||
.addTimeWindow(20,30).addTimeWindow(40,60).addTimeWindow(70,80).setLocation(Location.newInstance("20,0")).build();
|
||||
|
||||
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(service).addJob(service2).addVehicle(vehicle)
|
||||
.setRoutingCost(routingCosts).build();
|
||||
|
||||
VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle).setJobActivityFactory(vrp.getJobActivityFactory())
|
||||
.addService(service).addService(service2, TimeWindow.newInstance(70,80)).build();
|
||||
|
||||
StateManager stateManager = new StateManager(vrp);
|
||||
UpdateVehicleDependentPracticalTimeWindows updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager,routingCosts);
|
||||
updater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() {
|
||||
|
||||
@Override
|
||||
public Collection<Vehicle> get(VehicleRoute route) {
|
||||
Collection<Vehicle> vehicles = new ArrayList<Vehicle>();
|
||||
vehicles.add(route.getVehicle());
|
||||
// vehicles.addAll(fleetManager.getAvailableVehicles(route.getVehicle()));
|
||||
return vehicles;
|
||||
}
|
||||
|
||||
});
|
||||
stateManager.addStateUpdater(updater);
|
||||
stateManager.informInsertionStarts(Arrays.asList(route), Collections.<Job>emptyList());
|
||||
|
||||
assertEquals(80.,stateManager.getActivityState(route.getActivities().get(1),vehicle,
|
||||
InternalStates.LATEST_OPERATION_START_TIME, Double.class),0.01);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,9 @@ public class SolutionAnalyserTest {
|
|||
Service s3 = Service.Builder.newInstance("s3")
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.setLocation(TestUtils.loc(Coordinate.newInstance(10, 1))).addSizeDimension(0, 2).build();
|
||||
|
||||
Service s4 = Service.Builder.newInstance("s4").setLocation(TestUtils.loc(Coordinate.newInstance(10, 10))).addSizeDimension(0, 3).build();
|
||||
|
||||
Shipment shipment2 = Shipment.Builder.newInstance("ship2").setPickupLocation(TestUtils.loc(Coordinate.newInstance(15, 2)))
|
||||
.setPickupServiceTime(20.).setDeliveryServiceTime(20.)
|
||||
.setDeliveryLocation(TestUtils.loc(Coordinate.newInstance(16, 5))).addSizeDimension(0, 10).build();
|
||||
|
|
@ -120,12 +122,12 @@ public class SolutionAnalyserTest {
|
|||
.setLatestArrival(150.)
|
||||
.build();
|
||||
|
||||
Pickup s1 = (Pickup) Pickup.Builder.newInstance("s1")
|
||||
Pickup s1 = Pickup.Builder.newInstance("s1")
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.setLocation(Location.newInstance(-10, 1))
|
||||
.addSizeDimension(0, 10)
|
||||
.build();
|
||||
Delivery s2 = (Delivery) Delivery.Builder.newInstance("s2")
|
||||
Delivery s2 = Delivery.Builder.newInstance("s2")
|
||||
.setLocation(Location.newInstance(-10, 10))
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.addSizeDimension(0, 20)
|
||||
|
|
@ -137,12 +139,12 @@ public class SolutionAnalyserTest {
|
|||
.setPickupTimeWindow(TimeWindow.newInstance(10, 20)).setDeliveryTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.build();
|
||||
|
||||
Pickup s3 = (Pickup) Pickup.Builder.newInstance("s3")
|
||||
Pickup s3 = Pickup.Builder.newInstance("s3")
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.setLocation(TestUtils.loc(Coordinate.newInstance(10, 1)))
|
||||
.addSizeDimension(0, 10)
|
||||
.build();
|
||||
Delivery s4 = (Delivery) Delivery.Builder.newInstance("s4").setLocation(Location.newInstance(10, 10))
|
||||
Delivery s4 = Delivery.Builder.newInstance("s4").setLocation(Location.newInstance(10, 10))
|
||||
.addSizeDimension(0, 20)
|
||||
.setTimeWindow(TimeWindow.newInstance(10, 20))
|
||||
.build();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@ import org.junit.Test;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.internal.matchers.IsCollectionContaining.hasItem;
|
||||
|
||||
public class ServiceTest {
|
||||
|
||||
|
|
@ -112,62 +114,86 @@ public class ServiceTest {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void whenSettingLocationCoord_itShouldBeSetCorrectly(){
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance(1, 2)).build();
|
||||
assertEquals(1.0,s.getLocation().getCoordinate().getX(),0.01);
|
||||
assertEquals(2.0,s.getLocation().getCoordinate().getY(),0.01);
|
||||
assertEquals(1.0,s.getLocation().getCoordinate().getX(),0.01);
|
||||
assertEquals(2.0,s.getLocation().getCoordinate().getY(),0.01);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void whenSettingNeitherLocationIdNorCoord_throwsException(){
|
||||
@SuppressWarnings("unused")
|
||||
Service s = Service.Builder.newInstance("s").build();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void whenServiceTimeSmallerZero_throwIllegalStateException(){
|
||||
@SuppressWarnings("unused")
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc")).setServiceTime(-1).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingServiceTime_itShouldBeSetCorrectly(){
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc")).setServiceTime(1).build();
|
||||
assertEquals(1.0,s.getServiceDuration(),0.01);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void whenTimeWindowIsNull_throwException(){
|
||||
@SuppressWarnings("unused")
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc")).setTimeWindow(null).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingTimeWindow_itShouldBeSetCorrectly(){
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc")).setTimeWindow(TimeWindow.newInstance(1.0, 2.0)).build();
|
||||
assertEquals(1.0,s.getTimeWindow().getStart(),0.01);
|
||||
assertEquals(2.0,s.getTimeWindow().getEnd(),0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddingSkills_theyShouldBeAddedCorrectly(){
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||
.addRequiredSkill("drill").addRequiredSkill("screwdriver").build();
|
||||
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
||||
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
||||
assertTrue(s.getRequiredSkills().containsSkill("ScrewDriver"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly(){
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||
.addRequiredSkill("DriLl").addRequiredSkill("screwDriver").build();
|
||||
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
||||
assertTrue(s.getRequiredSkills().containsSkill("drilL"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingLocationCoord_itShouldBeSetCorrectly() {
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance(1, 2)).build();
|
||||
assertEquals(1.0, s.getLocation().getCoordinate().getX(), 0.01);
|
||||
assertEquals(2.0, s.getLocation().getCoordinate().getY(), 0.01);
|
||||
assertEquals(1.0, s.getLocation().getCoordinate().getX(), 0.01);
|
||||
assertEquals(2.0, s.getLocation().getCoordinate().getY(), 0.01);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void whenSettingNeitherLocationIdNorCoord_throwsException() {
|
||||
@SuppressWarnings("unused")
|
||||
Service s = Service.Builder.newInstance("s").build();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void whenServiceTimeSmallerZero_throwIllegalStateException() {
|
||||
@SuppressWarnings("unused")
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc")).setServiceTime(-1).build();
|
||||
public void whenAddingSeveralTimeWindows_itShouldBeSetCorrectly(){
|
||||
TimeWindow tw1 = TimeWindow.newInstance(1.0, 2.0);
|
||||
TimeWindow tw2 = TimeWindow.newInstance(3.0, 5.0);
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||
.addTimeWindow(tw1)
|
||||
.addTimeWindow(tw2)
|
||||
.build();
|
||||
assertEquals(2, s.getTimeWindows().size());
|
||||
assertThat(s.getTimeWindows(),hasItem(is(tw1)));
|
||||
assertThat(s.getTimeWindows(),hasItem(is(tw2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingServiceTime_itShouldBeSetCorrectly() {
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc")).setServiceTime(1).build();
|
||||
assertEquals(1.0, s.getServiceDuration(), 0.01);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void whenTimeWindowIsNull_throwException() {
|
||||
@SuppressWarnings("unused")
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc")).setTimeWindow(null).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSettingTimeWindow_itShouldBeSetCorrectly() {
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc")).setTimeWindow(TimeWindow.newInstance(1.0, 2.0)).build();
|
||||
public void whenAddingTimeWindow_itShouldBeSetCorrectly(){
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||
.addTimeWindow(TimeWindow.newInstance(1.0, 2.0)).build();
|
||||
assertEquals(1.0, s.getTimeWindow().getStart(), 0.01);
|
||||
assertEquals(2.0, s.getTimeWindow().getEnd(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddingSkills_theyShouldBeAddedCorrectly() {
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||
.addRequiredSkill("drill").addRequiredSkill("screwdriver").build();
|
||||
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
||||
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
||||
assertTrue(s.getRequiredSkills().containsSkill("ScrewDriver"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly() {
|
||||
Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc"))
|
||||
.addRequiredSkill("DriLl").addRequiredSkill("screwDriver").build();
|
||||
assertTrue(s.getRequiredSkills().containsSkill("drill"));
|
||||
assertTrue(s.getRequiredSkills().containsSkill("drilL"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly() {
|
||||
|
|
@ -184,4 +210,28 @@ public class ServiceTest {
|
|||
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().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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ import jsprit.core.util.Coordinate;
|
|||
import jsprit.core.util.TestUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.internal.matchers.IsCollectionContaining.hasItem;
|
||||
|
||||
public class ShipmentTest {
|
||||
|
||||
|
|
@ -223,6 +225,80 @@ public class ShipmentTest {
|
|||
assertEquals(2.0, s.getDeliveryTimeWindow().getEnd(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingAddDeliveryTimeWindow_itShouldBeDoneCorrectly() {
|
||||
Shipment s = Shipment.Builder.newInstance("s").addDeliveryTimeWindow(TimeWindow.newInstance(1, 2))
|
||||
.setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build();
|
||||
assertEquals(1.0, s.getDeliveryTimeWindow().getStart(), 0.01);
|
||||
assertEquals(2.0, s.getDeliveryTimeWindow().getEnd(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingAddDeliveryTimeWindow2_itShouldBeDoneCorrectly() {
|
||||
Shipment s = Shipment.Builder.newInstance("s").addDeliveryTimeWindow(1, 2)
|
||||
.setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build();
|
||||
assertEquals(1.0, s.getDeliveryTimeWindow().getStart(), 0.01);
|
||||
assertEquals(2.0, s.getDeliveryTimeWindow().getEnd(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddingMultipleDeliveryTimeWindows_itShouldBeDoneCorrectly() {
|
||||
TimeWindow tw1 = TimeWindow.newInstance(1,2);
|
||||
TimeWindow tw2 = TimeWindow.newInstance(4,5);
|
||||
Shipment s = Shipment.Builder.newInstance("s").addDeliveryTimeWindow(tw1).addDeliveryTimeWindow(tw2)
|
||||
.setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build();
|
||||
assertEquals(s.getDeliveryTimeWindows().size(),2);
|
||||
assertThat(s.getDeliveryTimeWindows(),hasItem(is(tw1)));
|
||||
assertThat(s.getDeliveryTimeWindows(),hasItem(is(tw2)));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void whenAddingMultipleOverlappingDeliveryTimeWindows_itShouldThrowException() {
|
||||
Shipment s = Shipment.Builder.newInstance("s").addDeliveryTimeWindow(1, 3).addDeliveryTimeWindow(2,5)
|
||||
.setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build();
|
||||
assertEquals(1.0, s.getDeliveryTimeWindow().getStart(), 0.01);
|
||||
assertEquals(2.0, s.getDeliveryTimeWindow().getEnd(), 0.01);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void whenUsingAddPickupTimeWindow_itShouldBeDoneCorrectly() {
|
||||
Shipment s = Shipment.Builder.newInstance("s").addPickupTimeWindow(TimeWindow.newInstance(1, 2))
|
||||
.setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build();
|
||||
assertEquals(1.0, s.getPickupTimeWindow().getStart(), 0.01);
|
||||
assertEquals(2.0, s.getPickupTimeWindow().getEnd(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingAddPickupTimeWindow2_itShouldBeDoneCorrectly() {
|
||||
Shipment s = Shipment.Builder.newInstance("s").addPickupTimeWindow(1, 2)
|
||||
.setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build();
|
||||
assertEquals(1.0, s.getPickupTimeWindow().getStart(), 0.01);
|
||||
assertEquals(2.0, s.getPickupTimeWindow().getEnd(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddingMultiplePickupTimeWindows_itShouldBeDoneCorrectly() {
|
||||
TimeWindow tw1 = TimeWindow.newInstance(1,2);
|
||||
TimeWindow tw2 = TimeWindow.newInstance(4,5);
|
||||
Shipment s = Shipment.Builder.newInstance("s").addPickupTimeWindow(tw1).addPickupTimeWindow(tw2)
|
||||
.setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build();
|
||||
assertEquals(s.getPickupTimeWindows().size(),2);
|
||||
assertThat(s.getPickupTimeWindows(), hasItem(is(tw1)));
|
||||
assertThat(s.getPickupTimeWindows(), hasItem(is(tw2)));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void whenAddingMultipleOverlappingPickupTimeWindows_itShouldThrowException() {
|
||||
Shipment s = Shipment.Builder.newInstance("s").addPickupTimeWindow(1, 3).addPickupTimeWindow(2,5)
|
||||
.setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build();
|
||||
assertEquals(1.0, s.getPickupTimeWindow().getStart(), 0.01);
|
||||
assertEquals(2.0, s.getPickupTimeWindow().getEnd(), 0.01);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void whenShipmentHasNegativeCapacityVal_throwIllegalStateExpception() {
|
||||
@SuppressWarnings("unused")
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import jsprit.core.problem.Capacity;
|
|||
import jsprit.core.problem.Location;
|
||||
import jsprit.core.problem.driver.Driver;
|
||||
import jsprit.core.problem.job.Shipment;
|
||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||
import org.junit.Test;
|
||||
|
|
@ -42,6 +44,7 @@ public class VehicleRouteBuilderTest {
|
|||
public void whenPickupIsAddedTwice_throwsException() {
|
||||
Shipment s = mock(Shipment.class);
|
||||
when(s.getSize()).thenReturn(Capacity.Builder.newInstance().build());
|
||||
when(s.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0., 10.));
|
||||
VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(mock(Vehicle.class), mock(Driver.class));
|
||||
builder.addPickup(s);
|
||||
builder.addPickup(s);
|
||||
|
|
@ -52,6 +55,8 @@ public class VehicleRouteBuilderTest {
|
|||
Shipment s = mock(Shipment.class);
|
||||
Capacity capacity = Capacity.Builder.newInstance().build();
|
||||
when(s.getSize()).thenReturn(capacity);
|
||||
when(s.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(mock(Vehicle.class), mock(Driver.class));
|
||||
builder.addPickup(s);
|
||||
builder.addDelivery(s);
|
||||
|
|
@ -65,6 +70,10 @@ public class VehicleRouteBuilderTest {
|
|||
Shipment s2 = mock(Shipment.class);
|
||||
when(s2.getSize()).thenReturn(capacity);
|
||||
when(s.getSize()).thenReturn(capacity);
|
||||
when(s2.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s2.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(mock(Vehicle.class), mock(Driver.class));
|
||||
builder.addPickup(s);
|
||||
builder.addPickup(s2);
|
||||
|
|
@ -79,6 +88,10 @@ public class VehicleRouteBuilderTest {
|
|||
Capacity capacity = Capacity.Builder.newInstance().build();
|
||||
when(s.getSize()).thenReturn(capacity);
|
||||
when(s2.getSize()).thenReturn(capacity);
|
||||
when(s2.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s2.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(mock(Vehicle.class), mock(Driver.class));
|
||||
builder.addPickup(s);
|
||||
builder.addPickup(s2);
|
||||
|
|
@ -95,6 +108,10 @@ public class VehicleRouteBuilderTest {
|
|||
Capacity capacity = Capacity.Builder.newInstance().build();
|
||||
when(s.getSize()).thenReturn(capacity);
|
||||
when(s2.getSize()).thenReturn(capacity);
|
||||
when(s2.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s2.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("vehLoc")).setEndLocation(Location.newInstance("vehLoc"))
|
||||
.build();
|
||||
|
||||
|
|
@ -115,6 +132,10 @@ public class VehicleRouteBuilderTest {
|
|||
when(s.getSize()).thenReturn(capacity);
|
||||
when(s2.getSize()).thenReturn(capacity);
|
||||
when(s2.getDeliveryLocation()).thenReturn(loc("delLoc"));
|
||||
when(s.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s2.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s2.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
Vehicle vehicle = mock(Vehicle.class);
|
||||
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||
when(vehicle.getStartLocation()).thenReturn(loc("vehLoc"));
|
||||
|
|
@ -139,6 +160,10 @@ public class VehicleRouteBuilderTest {
|
|||
when(s.getSize()).thenReturn(capacity);
|
||||
when(s2.getSize()).thenReturn(capacity);
|
||||
when(s2.getDeliveryLocation()).thenReturn(Location.Builder.newInstance().setId("delLoc").build());
|
||||
when(s.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s2.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0., 10.));
|
||||
when(s2.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
Vehicle vehicle = mock(Vehicle.class);
|
||||
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||
when(vehicle.getStartLocation()).thenReturn(Location.Builder.newInstance().setId("vehLoc").build());
|
||||
|
|
@ -162,6 +187,10 @@ public class VehicleRouteBuilderTest {
|
|||
when(s.getSize()).thenReturn(capacity);
|
||||
when(s2.getSize()).thenReturn(capacity);
|
||||
when(s2.getDeliveryLocation()).thenReturn(Location.Builder.newInstance().setId("delLoc").build());
|
||||
when(s2.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s2.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
when(s.getPickupTimeWindow()).thenReturn(TimeWindow.newInstance(0., 10.));
|
||||
when(s.getDeliveryTimeWindow()).thenReturn(TimeWindow.newInstance(0.,10.));
|
||||
Vehicle vehicle = mock(Vehicle.class);
|
||||
when(vehicle.isReturnToDepot()).thenReturn(false);
|
||||
when(vehicle.getStartLocation()).thenReturn(Location.Builder.newInstance().setId("vehLoc").build());
|
||||
|
|
|
|||
|
|
@ -33,9 +33,11 @@ public class BreakActivityTest {
|
|||
|
||||
@Before
|
||||
public void doBefore() {
|
||||
service = (Break) Break.Builder.newInstance("service")
|
||||
service = Break.Builder.newInstance("service")
|
||||
.setTimeWindow(TimeWindow.newInstance(1., 2.)).setServiceTime(3).build();
|
||||
serviceActivity = BreakActivity.newInstance(service);
|
||||
serviceActivity.setTheoreticalEarliestOperationStartTime(service.getTimeWindow().getStart());
|
||||
serviceActivity.setTheoreticalLatestOperationStartTime(service.getTimeWindow().getEnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -32,10 +32,12 @@ public class DeliverServiceTest {
|
|||
|
||||
@Before
|
||||
public void doBefore() {
|
||||
service = (Delivery) Delivery.Builder.newInstance("service").setLocation(Location.newInstance("loc")).
|
||||
service = Delivery.Builder.newInstance("service").setLocation(Location.newInstance("loc")).
|
||||
setTimeWindow(TimeWindow.newInstance(1., 2.)).
|
||||
addSizeDimension(0, 10).addSizeDimension(1, 100).addSizeDimension(2, 1000).build();
|
||||
deliver = new DeliverService(service);
|
||||
deliver.setTheoreticalEarliestOperationStartTime(service.getTimeWindow().getStart());
|
||||
deliver.setTheoreticalLatestOperationStartTime(service.getTimeWindow().getEnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ public class DeliverShipmentTest {
|
|||
.setDeliveryTimeWindow(TimeWindow.newInstance(3., 4.))
|
||||
.addSizeDimension(0, 10).addSizeDimension(1, 100).addSizeDimension(2, 1000).build();
|
||||
deliver = new DeliverShipment(shipment);
|
||||
deliver.setTheoreticalEarliestOperationStartTime(shipment.getDeliveryTimeWindow().getStart());
|
||||
deliver.setTheoreticalLatestOperationStartTime(shipment.getDeliveryTimeWindow().getEnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ public class PickupServiceTest {
|
|||
setTimeWindow(TimeWindow.newInstance(1., 2.)).
|
||||
addSizeDimension(0, 10).addSizeDimension(1, 100).addSizeDimension(2, 1000).build();
|
||||
pickup = new PickupService(service);
|
||||
pickup.setTheoreticalEarliestOperationStartTime(service.getTimeWindow().getStart());
|
||||
pickup.setTheoreticalLatestOperationStartTime(service.getTimeWindow().getEnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ public class PickupShipmentTest {
|
|||
.setDeliveryTimeWindow(TimeWindow.newInstance(3., 4.))
|
||||
.addSizeDimension(0, 10).addSizeDimension(1, 100).addSizeDimension(2, 1000).build();
|
||||
pickup = new PickupShipment(shipment);
|
||||
pickup.setTheoreticalEarliestOperationStartTime(shipment.getPickupTimeWindow().getStart());
|
||||
pickup.setTheoreticalLatestOperationStartTime(shipment.getPickupTimeWindow().getEnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ public class ServiceActivityTest {
|
|||
setTimeWindow(TimeWindow.newInstance(1., 2.)).
|
||||
addSizeDimension(0, 10).addSizeDimension(1, 100).addSizeDimension(2, 1000).build();
|
||||
serviceActivity = ServiceActivity.newInstance(service);
|
||||
serviceActivity.setTheoreticalEarliestOperationStartTime(service.getTimeWindow().getStart());
|
||||
serviceActivity.setTheoreticalLatestOperationStartTime(service.getTimeWindow().getEnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
package jsprit.core.problem.solution.route.activity;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Created by schroeder on 18/12/15.
|
||||
*/
|
||||
public class TimeWindowsImplTest {
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void overlappingTW_shouldThrowException(){
|
||||
TimeWindowsImpl tws = new TimeWindowsImpl();
|
||||
tws.add(TimeWindow.newInstance(50, 100));
|
||||
tws.add(TimeWindow.newInstance(90,150));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void overlappingTW2_shouldThrowException(){
|
||||
TimeWindowsImpl tws = new TimeWindowsImpl();
|
||||
tws.add(TimeWindow.newInstance(50, 100));
|
||||
tws.add(TimeWindow.newInstance(40,150));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void overlappingTW3_shouldThrowException(){
|
||||
TimeWindowsImpl tws = new TimeWindowsImpl();
|
||||
tws.add(TimeWindow.newInstance(50, 100));
|
||||
tws.add(TimeWindow.newInstance(50, 100));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue