diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java index def15202..03024cb0 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java @@ -34,7 +34,6 @@ import jsprit.core.util.CalculationUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.Collection; import java.util.Iterator; /** @@ -131,17 +130,12 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator { nextAct = end; tourEnd = true; } - double actArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(),deliveryAct2Insert.getLocation(),prevActStartTime,newDriver,newVehicle); - Collection timeWindows = service.getTimeWindows(actArrTime); -// TimeWindow timeWindow = getNextTimeWindow(actArrTime,timeWindows); -// if(timeWindow == null) break; boolean not_fulfilled_break = true; - for(TimeWindow timeWindow : timeWindows) { + 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)) { - //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) { @@ -171,15 +165,4 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator { insertionData.setVehicleDepartureTime(newVehicleDepartureTime); return insertionData; } - - private TimeWindow getNextTimeWindow(double actArrTime, Collection timeWindows) { - for(TimeWindow tw : timeWindows){ - if(actArrTime >= tw.getStart() && actArrTime <= tw.getEnd()) return tw; - else if(actArrTime < tw.getStart()){ - return tw; - } - } - return null; - } - } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java index f47fa385..acfdb88d 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java @@ -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= 0; i--){ -// TimeWindow tw = activity.getTimeWindows().get(i); -// if(tw.getStart() <= arrivalTime && tw.getEnd() >= arrivalTime){ -// return arrivalTime; -// } -// else if(arrivalTime > tw.getEnd()){ -// if(last != null) return last.getStart(); -// else return arrivalTime; -// } -// last = tw; -// } -// return Math.max(arrivalTime,last.getStart()); - } - -} diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java index f4f13467..14e12a26 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java @@ -66,10 +66,10 @@ public class UpdateActivityTimes implements ActivityVisitor, StateUpdater { timeTracker.visit(activity); activity.setArrTime(timeTracker.getActArrTime()); activity.setEndTime(timeTracker.getActEndTime()); - double theoreticalLatestOperationStartTime = activity.getTheoreticalLatestOperationStartTime(); - if(activity.getArrTime() > theoreticalLatestOperationStartTime){ - throw new IllegalStateException("arrTime > latestArrTime"); - } +// double theoreticalLatestOperationStartTime = activity.getTheoreticalLatestOperationStartTime(); +// if(activity.getArrTime() > theoreticalLatestOperationStartTime){ +// throw new IllegalStateException("arrTime > latestArrTime"); +// } } @Override diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdatePracticalTimeWindows.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdatePracticalTimeWindows.java deleted file mode 100644 index 3c48c114..00000000 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdatePracticalTimeWindows.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2014 Stefan Schroeder - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - ******************************************************************************/ -package jsprit.core.algorithm.state; - -import jsprit.core.problem.cost.VehicleRoutingTransportCosts; -import jsprit.core.problem.solution.route.VehicleRoute; -import jsprit.core.problem.solution.route.activity.ReverseActivityVisitor; -import jsprit.core.problem.solution.route.activity.TimeWindow; -import jsprit.core.problem.solution.route.activity.TourActivity; - -import java.util.Collection; - -/** - * Updates and memorizes latest operation start times at activities. - * - * @author schroeder - */ -class UpdatePracticalTimeWindows implements ReverseActivityVisitor, StateUpdater { - - private StateManager states; - - private VehicleRoute route; - - private VehicleRoutingTransportCosts transportCosts; - - private double latestArrTimeAtPrevAct; - - private TourActivity prevAct; - - public UpdatePracticalTimeWindows(StateManager states, VehicleRoutingTransportCosts tpCosts) { - super(); - this.states = states; - this.transportCosts = tpCosts; - } - - @Override - public void begin(VehicleRoute route) { - this.route = route; - latestArrTimeAtPrevAct = route.getEnd().getTheoreticalLatestOperationStartTime(); - prevAct = route.getEnd(); - } - - @Override - public void visit(TourActivity activity) { - double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocation(), prevAct.getLocation(), latestArrTimeAtPrevAct, route.getDriver(),route.getVehicle()) - activity.getOperationTime(); - Collection timeWindows = activity.getTimeWindows(); - double latestArrivalTime = getLatestArrivalTime(timeWindows,potentialLatestArrivalTimeAtCurrAct); - states.putInternalTypedActivityState(activity, InternalStates.LATEST_OPERATION_START_TIME, latestArrivalTime); - - latestArrTimeAtPrevAct = latestArrivalTime; - prevAct = activity; - } - - private double getLatestArrivalTime(Collection timeWindows, double potentialLatestArrivalTimeAtCurrAct) { - TimeWindow last = null; - for(TimeWindow tw : timeWindows){ - if(tw.getStart() <= potentialLatestArrivalTimeAtCurrAct && tw.getEnd() >= potentialLatestArrivalTimeAtCurrAct){ - return potentialLatestArrivalTimeAtCurrAct; - } - else if(tw.getStart() > potentialLatestArrivalTimeAtCurrAct){ - if(last == null){ - return potentialLatestArrivalTimeAtCurrAct; - } - else return last.getEnd(); - } - last = tw; - } - return last.getEnd(); - } - - @Override - public void finish() { - } -} diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVehicleDependentPracticalTimeWindows.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVehicleDependentPracticalTimeWindows.java index f10e1be2..648ec8e7 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVehicleDependentPracticalTimeWindows.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVehicleDependentPracticalTimeWindows.java @@ -97,7 +97,8 @@ public class UpdateVehicleDependentPracticalTimeWindows implements RouteVisitor, Location prevLocation = location_of_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()]; double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocation(), prevLocation, latestArrTimeAtPrevAct, route.getDriver(), vehicle) - activity.getOperationTime(); - double latestArrivalTime = getLatestArrivalTime(activity.getTimeWindows(), potentialLatestArrivalTimeAtCurrAct); + double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct); +// getLatestArrivalTime(activity.getTimeWindows(), potentialLatestArrivalTimeAtCurrAct); if (latestArrivalTime < activity.getTheoreticalEarliestOperationStartTime()) { stateManager.putTypedInternalRouteState(route, vehicle, InternalStates.SWITCH_NOT_FEASIBLE, true); } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowConstraints.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowConstraints.java index 10296012..e8a93a6e 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowConstraints.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowConstraints.java @@ -42,21 +42,11 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr this.routingCosts = routingCosts; } - public double getLatestOperationStartTime(TourActivity act){ - return act.getTimeWindows().get(act.getTimeWindows().size()-1).getEnd(); - } - - public double getEarliestOperationStartTime(TourActivity act){ - return act.getTimeWindows().get(0).getStart(); - } - @Override public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) { double latestVehicleArrival = iFacts.getNewVehicle().getLatestArrival(); Double latestArrTimeAtNextAct; Location nextActLocation; -// double nextAct_theoreticalLatestOperationStartTime = getLatestOperationStartTime(nextAct); - if (nextAct instanceof End) { latestArrTimeAtNextAct = latestVehicleArrival; nextActLocation = iFacts.getNewVehicle().getEndLocation(); @@ -64,15 +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(); -// latestArrTimeAtNextAct = nextAct_theoreticalLatestOperationStartTime; -// throw new IllegalStateException("this is strange and should not be"); - //ToDo here, there should be another solution } nextActLocation = nextAct.getLocation(); } @@ -84,11 +68,7 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr * |--- vehicle's operation time ---| * |--- prevAct or newAct or nextAct ---| */ -// double prevAct_theoreticalEarliestOperationStartTime = getEarliestOperationStartTime(prevAct); double newAct_theoreticalEarliestOperationStartTime = newAct.getTheoreticalEarliestOperationStartTime(); -// newAct.getTheoreticalEarliestOperationStartTime(); -// double nextAct_theoreticalEarliestOperationStartTime = getEarliestOperationStartTime(nextAct); -// nextAct.getTheoreticalEarliestOperationStartTime(); if (latestVehicleArrival < prevAct.getTheoreticalEarliestOperationStartTime() || latestVehicleArrival < newAct_theoreticalEarliestOperationStartTime || diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java index b28a6a24..bc0bc6ce 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java @@ -82,14 +82,14 @@ public class Service extends AbstractJob { protected Location location; - protected TimeWindows timeWindows = new TimeWindowsImpl(); + protected TimeWindowsImpl timeWindows; private boolean twAdded = false; Builder(String id){ this.id = id; timeWindows = new TimeWindowsImpl(); - ((TimeWindowsImpl)timeWindows).add(timeWindow); + timeWindows.add(timeWindow); } /** @@ -133,11 +133,6 @@ public class Service extends AbstractJob { return this; } - public Builder setTimeWindows(TimeWindows timeWindows){ - this.timeWindows = timeWindows; - return this; - } - /** * Adds capacity dimension. * @@ -156,7 +151,7 @@ public class Service extends AbstractJob { if(tw == null) throw new IllegalArgumentException("time-window arg must not be null"); this.timeWindow = tw; this.timeWindows = new TimeWindowsImpl(); - ((TimeWindowsImpl) timeWindows).add(tw); + timeWindows.add(tw); return this; } @@ -166,15 +161,7 @@ public class Service extends AbstractJob { timeWindows = new TimeWindowsImpl(); twAdded = true; } - for(TimeWindow tw : ((TimeWindowsImpl)timeWindows).getTimeWindows()){ - if(timeWindow.getStart() > tw.getStart() && timeWindow.getStart() < tw.getEnd()){ - throw new IllegalStateException("time-windows cannot overlap each other. overlap: " + tw + ", " + timeWindow); - } - if(timeWindow.getEnd() > tw.getStart() && timeWindow.getEnd() < tw.getEnd()){ - throw new IllegalStateException("time-windows cannot overlap each other. overlap: " + tw + ", " + timeWindow); - } - } - ((TimeWindowsImpl) timeWindows).add(timeWindow); + timeWindows.add(timeWindow); return this; } @@ -251,8 +238,8 @@ public class Service extends AbstractJob { timeWindowManager = builder.timeWindows; } - public Collection getTimeWindows(double arrTime){ - return timeWindowManager.getTimeWindows(arrTime); + public Collection getTimeWindows(){ + return timeWindowManager.getTimeWindows(); } @Override @@ -281,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(); } /** diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java index da877166..7d3bc0d3 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java @@ -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 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 getPickupTimeWindows() { + return pickupTimeWindows.getTimeWindows(); + } + + @Override public int hashCode() { final int prime = 31; diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java index 6f948e1d..857b0323 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java @@ -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) *

*

This implies that for this service a serviceActivity is created with {@link TourActivityFactory} and added to the sequence of tourActivities. *

@@ -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 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 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 { diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartAsSoonAsArrived.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ActivityStartAsSoonAsArrived.java similarity index 71% rename from jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartAsSoonAsArrived.java rename to jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ActivityStartAsSoonAsArrived.java index 1d92a835..957de835 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartAsSoonAsArrived.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ActivityStartAsSoonAsArrived.java @@ -1,6 +1,4 @@ -package jsprit.core.algorithm.state; - -import jsprit.core.problem.solution.route.activity.TourActivity; +package jsprit.core.problem.solution.route.activity; /** * Created by schroeder on 08/07/15. diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartStrategy.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ActivityStartStrategy.java similarity index 62% rename from jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartStrategy.java rename to jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ActivityStartStrategy.java index bd36cde7..937f4602 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartStrategy.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ActivityStartStrategy.java @@ -1,6 +1,4 @@ -package jsprit.core.algorithm.state; - -import jsprit.core.problem.solution.route.activity.TourActivity; +package jsprit.core.problem.solution.route.activity; /** * Created by schroeder on 08/07/15. diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartsAsSoonAsTimeWindowOpens.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ActivityStartsAsSoonAsTimeWindowOpens.java similarity index 76% rename from jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartsAsSoonAsTimeWindowOpens.java rename to jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ActivityStartsAsSoonAsTimeWindowOpens.java index d3044165..40f7d0c4 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/ActivityStartsAsSoonAsTimeWindowOpens.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ActivityStartsAsSoonAsTimeWindowOpens.java @@ -1,6 +1,4 @@ -package jsprit.core.algorithm.state; - -import jsprit.core.problem.solution.route.activity.TourActivity; +package jsprit.core.problem.solution.route.activity; /** * Created by schroeder on 08/07/15. diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/BreakActivity.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/BreakActivity.java index ec1ab168..5b70c91f 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/BreakActivity.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/BreakActivity.java @@ -23,8 +23,6 @@ import jsprit.core.problem.job.Break; import jsprit.core.problem.job.Service; import jsprit.core.problem.solution.route.activity.TourActivity.JobActivity; -import java.util.List; - public class BreakActivity extends AbstractActivity implements JobActivity { public static int counter = 0; @@ -73,9 +71,9 @@ public class BreakActivity extends AbstractActivity implements JobActivity { private final Break aBreak; - private double earliest; + private double earliest = 0; - private double latest; + private double latest = Double.MAX_VALUE; protected BreakActivity(Break aBreak) { counter++; @@ -89,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(); } @@ -174,11 +174,6 @@ public class BreakActivity extends AbstractActivity implements JobActivity { this.latest = latest; } - @Override - public List getTimeWindows() { - return null; - } - @Override public String getName() { return aBreak.getType(); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java index 972bb0b6..4c94ed8f 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverService.java @@ -21,9 +21,6 @@ import jsprit.core.problem.Capacity; import jsprit.core.problem.Location; import jsprit.core.problem.job.Delivery; -import java.util.ArrayList; -import java.util.List; - public final class DeliverService extends AbstractActivity implements DeliveryActivity { private Delivery delivery; @@ -34,17 +31,14 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc private double endTime; - private double theoreticalEarliest; + private double theoreticalEarliest = 0; - private double theoreticalLatest; - - private List timeWindows; + private double theoreticalLatest = Double.MAX_VALUE; public DeliverService(Delivery delivery) { super(); this.delivery = delivery; capacity = Capacity.invert(delivery.getSize()); - timeWindows = new ArrayList(delivery.getTimeWindows(0.)); } private DeliverService(DeliverService deliveryActivity) { @@ -53,7 +47,6 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc this.endTime = deliveryActivity.getEndTime(); capacity = deliveryActivity.getSize(); setIndex(deliveryActivity.getIndex()); - timeWindows = new ArrayList(delivery.getTimeWindows(0.)); this.theoreticalEarliest = deliveryActivity.getTheoreticalEarliestOperationStartTime(); this.theoreticalLatest = deliveryActivity.getTheoreticalLatestOperationStartTime(); } @@ -83,10 +76,6 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc theoreticalLatest = latest; } - @Override - public List getTimeWindows() { - return timeWindows; - } @Override public double getTheoreticalEarliestOperationStartTime() { diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverShipment.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverShipment.java index 19f6688f..0987e752 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverShipment.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/DeliverShipment.java @@ -22,8 +22,6 @@ import jsprit.core.problem.Location; import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Shipment; -import java.util.List; - public final class DeliverShipment extends AbstractActivity implements DeliveryActivity { private Shipment shipment; @@ -34,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; @@ -47,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 @@ -56,18 +60,12 @@ public final class DeliverShipment extends AbstractActivity implements DeliveryA @Override public void setTheoreticalEarliestOperationStartTime(double earliest) { - + this.earliest = earliest; } @Override public void setTheoreticalLatestOperationStartTime(double latest) { - - } - - @Override - public List getTimeWindows() { -// return shipment.getDeliveryTimeWindow(); - return null; + this.latest = latest; } @Override @@ -87,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 diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java index 9d803069..648ae686 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java @@ -21,9 +21,6 @@ import jsprit.core.problem.Capacity; import jsprit.core.problem.Location; import jsprit.core.util.Coordinate; -import java.util.Arrays; -import java.util.List; - public final class End extends AbstractActivity implements TourActivity { @Deprecated @@ -71,11 +68,6 @@ public final class End extends AbstractActivity implements TourActivity { theoretical_latestOperationStartTime = theoreticalLatestOperationStartTime; } - @Override - public List getTimeWindows() { - return Arrays.asList(TimeWindow.newInstance(theoretical_earliestOperationStartTime,theoretical_latestOperationStartTime)); - } - public End(Location location, double theoreticalStart, double theoreticalEnd) { super(); this.location = location; diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java index 13c5e977..40854dfe 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupService.java @@ -22,9 +22,6 @@ import jsprit.core.problem.Location; import jsprit.core.problem.job.Pickup; import jsprit.core.problem.job.Service; -import java.util.ArrayList; -import java.util.List; - public final class PickupService extends AbstractActivity implements PickupActivity { private Service pickup; @@ -33,22 +30,17 @@ public final class PickupService extends AbstractActivity implements PickupActiv private double depTime; - private double theoreticalEarliest; - - private double theoreticalLatest; - - private List timeWindows; + private double theoreticalEarliest = 0; + private double theoreticalLatest = Double.MAX_VALUE; public PickupService(Pickup pickup) { super(); this.pickup = pickup; - timeWindows = new ArrayList(pickup.getTimeWindows(0.)); } public PickupService(Service service) { this.pickup = service; - timeWindows = new ArrayList(service.getTimeWindows(0.)); } private PickupService(PickupService pickupActivity) { @@ -56,7 +48,6 @@ public final class PickupService extends AbstractActivity implements PickupActiv this.arrTime = pickupActivity.getArrTime(); this.depTime = pickupActivity.getEndTime(); setIndex(pickupActivity.getIndex()); - timeWindows = new ArrayList(pickup.getTimeWindows(0.)); this.theoreticalEarliest = pickupActivity.getTheoreticalEarliestOperationStartTime(); this.theoreticalLatest = pickupActivity.getTheoreticalLatestOperationStartTime(); } @@ -96,11 +87,6 @@ public final class PickupService extends AbstractActivity implements PickupActiv this.theoreticalLatest = latest; } - @Override - public List getTimeWindows() { - return timeWindows; - } - @Override public double getOperationTime() { return pickup.getServiceDuration(); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupShipment.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupShipment.java index 55248e08..27ebe7b2 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupShipment.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/PickupShipment.java @@ -22,8 +22,6 @@ import jsprit.core.problem.Location; import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Shipment; -import java.util.List; - public final class PickupShipment extends AbstractActivity implements PickupActivity{ private Shipment shipment; @@ -32,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; @@ -43,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 @@ -52,17 +56,12 @@ public final class PickupShipment extends AbstractActivity implements PickupActi @Override public void setTheoreticalEarliestOperationStartTime(double earliest) { - + this.earliest = earliest; } @Override public void setTheoreticalLatestOperationStartTime(double latest) { - - } - - @Override - public List getTimeWindows() { - return null; + this.latest = latest; } @Override @@ -82,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 diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java index b7ef836b..4847a07b 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/ServiceActivity.java @@ -82,7 +82,7 @@ public class ServiceActivity extends AbstractActivity implements JobActivity { protected ServiceActivity(Service service) { counter++; this.service = service; - timeWindows = new ArrayList(service.getTimeWindows(0.)); + timeWindows = new ArrayList(service.getTimeWindows()); } protected ServiceActivity(ServiceActivity serviceActivity) { @@ -91,7 +91,6 @@ public class ServiceActivity extends AbstractActivity implements JobActivity { this.arrTime = serviceActivity.getArrTime(); this.endTime = serviceActivity.getEndTime(); setIndex(serviceActivity.getIndex()); - timeWindows = new ArrayList(serviceActivity.getTimeWindows()); this.theoreticalEarliest = serviceActivity.getTheoreticalEarliestOperationStartTime(); this.theoreticalLatest = serviceActivity.getTheoreticalLatestOperationStartTime(); } @@ -146,11 +145,6 @@ public class ServiceActivity extends AbstractActivity implements JobActivity { theoreticalLatest = latest; } - @Override - public List getTimeWindows() { - return timeWindows; - } - @Override public double getOperationTime() { return service.getServiceDuration(); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java index dd70e307..f0f72345 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java @@ -20,9 +20,6 @@ import jsprit.core.problem.AbstractActivity; import jsprit.core.problem.Capacity; import jsprit.core.problem.Location; -import java.util.Arrays; -import java.util.List; - public final class Start extends AbstractActivity implements TourActivity { public final static String ACTIVITY_NAME = "start"; @@ -110,12 +107,6 @@ public final class Start extends AbstractActivity implements TourActivity { this.theoretical_latestOperationStartTime = time; } - @Override - public List getTimeWindows() { - return Arrays.asList(TimeWindow.newInstance(theoretical_earliestOperationStartTime,theoretical_latestOperationStartTime)); - } - - @Deprecated @Override public String getLocationId() { diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindows.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindows.java index 050b29fe..ceeda7c1 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindows.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindows.java @@ -7,6 +7,6 @@ import java.util.Collection; */ public interface TimeWindows { - public Collection getTimeWindows(double time); + public Collection getTimeWindows(); } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindowsImpl.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindowsImpl.java index 3d2ac731..67580bac 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindowsImpl.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindowsImpl.java @@ -12,6 +12,14 @@ public class TimeWindowsImpl implements TimeWindows { private Collection timeWindows = new ArrayList(); 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); + } + } timeWindows.add(timeWindow); } @@ -19,9 +27,4 @@ public class TimeWindowsImpl implements TimeWindows { return Collections.unmodifiableCollection(timeWindows); } - @Override - public Collection getTimeWindows(double time) { - return Collections.unmodifiableCollection(timeWindows); - } - } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivity.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivity.java index 6f36087b..320a1eec 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivity.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TourActivity.java @@ -21,8 +21,6 @@ import jsprit.core.problem.HasIndex; import jsprit.core.problem.Location; import jsprit.core.problem.job.Job; -import java.util.List; - /** * Basic interface for tour-activities. *

@@ -36,8 +34,6 @@ public interface TourActivity extends HasIndex { public void setTheoreticalLatestOperationStartTime(double latest); - public List getTimeWindows(); - /** * Basic interface of job-activies. *

diff --git a/jsprit-core/src/main/java/jsprit/core/util/ActivityTimeTracker.java b/jsprit-core/src/main/java/jsprit/core/util/ActivityTimeTracker.java index 97734570..a94f33ef 100644 --- a/jsprit-core/src/main/java/jsprit/core/util/ActivityTimeTracker.java +++ b/jsprit-core/src/main/java/jsprit/core/util/ActivityTimeTracker.java @@ -16,13 +16,9 @@ ******************************************************************************/ package jsprit.core.util; -import jsprit.core.algorithm.state.ActivityStartAsSoonAsArrived; -import jsprit.core.algorithm.state.ActivityStartStrategy; -import jsprit.core.algorithm.state.ActivityStartsAsSoonAsNextTimeWindowOpens; 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 { @@ -51,7 +47,7 @@ public class ActivityTimeTracker implements ActivityVisitor { public ActivityTimeTracker(ForwardTransportTime transportTime) { super(); this.transportTime = transportTime; - this.startStrategy = new ActivityStartsAsSoonAsNextTimeWindowOpens(); + this.startStrategy = new ActivityStartsAsSoonAsTimeWindowOpens(); } public ActivityTimeTracker(ForwardTransportTime transportTime, ActivityPolicy activityPolicy) { @@ -60,7 +56,7 @@ public class ActivityTimeTracker implements ActivityVisitor { if(activityPolicy.equals(ActivityPolicy.AS_SOON_AS_ARRIVED)){ this.startStrategy = new ActivityStartAsSoonAsArrived(); } - else this.startStrategy = new ActivityStartsAsSoonAsNextTimeWindowOpens(); + else this.startStrategy = new ActivityStartsAsSoonAsTimeWindowOpens(); } public ActivityTimeTracker(ForwardTransportTime transportTime, ActivityStartStrategy startStrategy) { @@ -92,7 +88,6 @@ public class ActivityTimeTracker implements ActivityVisitor { double transportTime = this.transportTime.getTransportTime(prevAct.getLocation(), activity.getLocation(), startAtPrevAct, route.getDriver(), route.getVehicle()); double arrivalTimeAtCurrAct = startAtPrevAct + transportTime; actArrTime = arrivalTimeAtCurrAct; - assert actArrTime <= activity.getTimeWindows().get(activity.getTimeWindows().size()-1).getEnd() : "that should not be"; double operationEndTime = startStrategy.getActivityStartTime(activity,arrivalTimeAtCurrAct) + activity.getOperationTime(); actEndTime = operationEndTime; prevAct = activity; @@ -104,7 +99,6 @@ public class ActivityTimeTracker implements ActivityVisitor { double transportTime = this.transportTime.getTransportTime(prevAct.getLocation(), route.getEnd().getLocation(), startAtPrevAct, route.getDriver(), route.getVehicle()); double arrivalTimeAtCurrAct = startAtPrevAct + transportTime; actArrTime = arrivalTimeAtCurrAct; - assert actArrTime <= route.getVehicle().getLatestArrival() : "oohh. this should not be"; actEndTime = arrivalTimeAtCurrAct; beginFirst = false; } diff --git a/jsprit-core/src/main/java/jsprit/core/util/CalculationUtils.java b/jsprit-core/src/main/java/jsprit/core/util/CalculationUtils.java index 70572bfa..265fbd64 100644 --- a/jsprit-core/src/main/java/jsprit/core/util/CalculationUtils.java +++ b/jsprit-core/src/main/java/jsprit/core/util/CalculationUtils.java @@ -18,7 +18,6 @@ package jsprit.core.util; -import jsprit.core.algorithm.state.ActivityStartsAsSoonAsNextTimeWindowOpens; import jsprit.core.problem.solution.route.activity.TourActivity; public class CalculationUtils { @@ -32,7 +31,6 @@ public class CalculationUtils { * @return */ public static double getActivityEndTime(double actArrTime, TourActivity act){ - return new ActivityStartsAsSoonAsNextTimeWindowOpens().getActivityStartTime(act, actArrTime) + act.getOperationTime(); -// return Math.max(actArrTime, act.getTheoreticalEarliestOperationStartTime()) + act.getOperationTime(); + return Math.max(actArrTime, act.getTheoreticalEarliestOperationStartTime()) + act.getOperationTime(); } } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java index 28dde653..bf2d4d71 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java @@ -124,6 +124,7 @@ public class TestCalculatesServiceInsertion { states.updateLoadStates(); states.updateTimeWindowStates(); + ConstraintManager cManager = new ConstraintManager(vrp, states); cManager.addLoadConstraint(); cManager.addTimeWindowConstraint(); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java index 714f04c7..011dab8d 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java @@ -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(); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java index a6d4ec08..5a9d481d 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java @@ -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()); LocalActivityInsertionCostsCalculator calc = new LocalActivityInsertionCostsCalculator(CostFactory.createEuclideanCosts(), new WaitingTimeCosts(), stateManager); calc.setSolutionCompletenessRatio(1.); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostEstimator.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostEstimator.java index 5b74368b..7b675fc6 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostEstimator.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostEstimator.java @@ -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 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); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelServiceInsertionCostEstimator.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelServiceInsertionCostEstimator.java index 01ca4a44..4bc8754e 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelServiceInsertionCostEstimator.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelServiceInsertionCostEstimator.java @@ -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 createActivities(Job job) { @@ -169,7 +178,10 @@ public class TestRouteLevelServiceInsertionCostEstimator { public List createActivities(Job job) { List 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 createActivities(Job job) { List 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 createActivities(Job job) { List 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; } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/state/GetLatestArrivalTimeTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/state/GetLatestArrivalTimeTest.java deleted file mode 100644 index 3f0bf65c..00000000 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/state/GetLatestArrivalTimeTest.java +++ /dev/null @@ -1,235 +0,0 @@ -package jsprit.core.algorithm.state; - -import jsprit.core.problem.solution.route.activity.TimeWindow; -import junit.framework.Assert; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -/** - * Created by schroeder on 08/07/15. - */ -public class GetLatestArrivalTimeTest { - - @Test - public void whenSingleTW_itShouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(0,10); - Assert.assertEquals(10.,getLatestArrivalTime(Arrays.asList(tw),20)); - } - - @Test - public void whenSingleTW2_itShouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(0,10); - Assert.assertEquals(8.,getLatestArrivalTime(Arrays.asList(tw),8)); - } - - @Test - public void whenSingleTW3_itShouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - Assert.assertEquals(1.,getLatestArrivalTime(Arrays.asList(tw),1)); - } - - @Test - public void whenMultipleTW_itShouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - Assert.assertEquals(30.,getLatestArrivalTime(Arrays.asList(tw,tw2),40)); - } - - @Test - public void whenMultipleTW2_itShouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - Assert.assertEquals(25.,getLatestArrivalTime(Arrays.asList(tw,tw2),25)); - } - - @Test - public void whenMultipleTW3_itShouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - Assert.assertEquals(10.,getLatestArrivalTime(Arrays.asList(tw,tw2),19)); - } - - @Test - public void whenMultipleTW4_itShouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - Assert.assertEquals(8.,getLatestArrivalTime(Arrays.asList(tw,tw2),8)); - } - - @Test - public void whenMultipleTW5_itShouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - Assert.assertEquals(1.,getLatestArrivalTime(Arrays.asList(tw,tw2),1)); - } - - @Test - public void whenMultiple3TW1_itShouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - TimeWindow tw3 = TimeWindow.newInstance(40,50); - Assert.assertEquals(30.,getLatestArrivalTime(Arrays.asList(tw,tw2,tw3),35)); - } - - @Test - public void whenMultiple3TW2_itShouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - TimeWindow tw3 = TimeWindow.newInstance(40,50); - Assert.assertEquals(50.,getLatestArrivalTime(Arrays.asList(tw,tw2,tw3),55)); - } - - @Test - public void whenMultiple3TW3_itShouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - TimeWindow tw3 = TimeWindow.newInstance(40,50); - Assert.assertEquals(45.,getLatestArrivalTime(Arrays.asList(tw,tw2,tw3),45)); - } - - @Test - public void whenSingleTW_ActivityStartTime_shouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - Assert.assertEquals(2.,getActivityStartTime(Arrays.asList(tw),1)); - } - - @Test - public void whenSingleTW2_ActivityStartTime_shouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - Assert.assertEquals(3.,getActivityStartTime(Arrays.asList(tw),3)); - } - - @Test - public void whenSingleTW3_ActivityStartTime_shouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - Assert.assertEquals(11.,getActivityStartTime(Arrays.asList(tw),11)); - } - - @Test - public void whenMultipleTW1_ActivityStartTime_shouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - Assert.assertEquals(2.,getActivityStartTime(Arrays.asList(tw,tw2),1)); - } - - @Test - public void whenMultipleTW2_ActivityStartTime_shouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - Assert.assertEquals(3.,getActivityStartTime(Arrays.asList(tw,tw2),3)); - } - - @Test - public void whenMultipleTW3_ActivityStartTime_shouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - Assert.assertEquals(20.,getActivityStartTime(Arrays.asList(tw,tw2),11)); - } - - @Test - public void whenMultipleTW4_ActivityStartTime_shouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - Assert.assertEquals(21.,getActivityStartTime(Arrays.asList(tw,tw2),21)); - } - - @Test - public void whenMultipleTW5_ActivityStartTime_shouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - Assert.assertEquals(31.,getActivityStartTime(Arrays.asList(tw,tw2),31)); - } - - @Test - public void whenMultiple3TW1_ActivityStartTime_shouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - TimeWindow tw3 = TimeWindow.newInstance(40,80); - Assert.assertEquals(40.,getActivityStartTime(Arrays.asList(tw,tw2,tw3),31)); - } - - @Test - public void whenMultiple3TW2_ActivityStartTime_shouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - TimeWindow tw3 = TimeWindow.newInstance(40,80); - Assert.assertEquals(90.,getActivityStartTime(Arrays.asList(tw,tw2,tw3),90)); - } - - @Test - public void whenMultiple4TW1_ActivityStartTime_shouldReturnCorrectTime(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw2 = TimeWindow.newInstance(20,30); - TimeWindow tw3 = TimeWindow.newInstance(40,80); - TimeWindow tw4 = TimeWindow.newInstance(140,180); - Assert.assertEquals(140.,getActivityStartTime(Arrays.asList(tw,tw2,tw3,tw4),130)); - } - - private double getLatestArrivalTime(Collection timeWindows, double potentialLatestArrivalTimeAtCurrAct) { - TimeWindow last = null; - for(TimeWindow tw : timeWindows){ - if(tw.getStart() <= potentialLatestArrivalTimeAtCurrAct && tw.getEnd() >= potentialLatestArrivalTimeAtCurrAct){ - return potentialLatestArrivalTimeAtCurrAct; - } - else if(tw.getStart() > potentialLatestArrivalTimeAtCurrAct){ - if(last == null){ - return potentialLatestArrivalTimeAtCurrAct; - } - else return last.getEnd(); - } - last = tw; - } - return last.getEnd(); - } - - private double getActivityStartTime(List timeWindows, double arrivalTime) { - TimeWindow last = null; - for(int i=timeWindows.size()-1; i >= 0; i--){ - TimeWindow tw = timeWindows.get(i); - if(tw.getStart() <= arrivalTime && tw.getEnd() >= arrivalTime){ - return arrivalTime; - } - else if(arrivalTime > tw.getEnd()){ - if(last != null) return last.getStart(); - else return arrivalTime; - } - last = tw; - } - return Math.max(arrivalTime,last.getStart()); - } - - @Test - public void singleTWshouldWork(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - Assert.assertEquals(tw,getNextTimeWindow(11, Arrays.asList(tw))); - } - - @Test - public void multipleTWshouldWork(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw1 = TimeWindow.newInstance(20,30); - Assert.assertEquals(tw1,getNextTimeWindow(19,Arrays.asList(tw,tw1))); - } - - @Test - public void multipleTW2shouldWork(){ - TimeWindow tw = TimeWindow.newInstance(2,10); - TimeWindow tw1 = TimeWindow.newInstance(20,30); - TimeWindow tw2 = TimeWindow.newInstance(40,50); - Assert.assertEquals(tw2,getNextTimeWindow(31,Arrays.asList(tw,tw1,tw2))); - } - - private TimeWindow getNextTimeWindow(double actArrTime, Collection timeWindows) { - for(TimeWindow tw : timeWindows){ - if(actArrTime >= tw.getStart() && actArrTime <= tw.getEnd()) return tw; - else if(actArrTime < tw.getStart()){ - return tw; - } - } - return null; - } - -} diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdatePracticalTimeWindowTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdatePracticalTimeWindowTest.java deleted file mode 100644 index 5b97b4a5..00000000 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdatePracticalTimeWindowTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Stefan Schroeder. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Contributors: - * Stefan Schroeder - initial API and implementation - ******************************************************************************/ -package jsprit.core.algorithm.state; - -import jsprit.core.problem.AbstractActivity; -import jsprit.core.problem.JobActivityFactory; -import jsprit.core.problem.Location; -import jsprit.core.problem.VehicleRoutingProblem; -import jsprit.core.problem.cost.VehicleRoutingTransportCosts; -import jsprit.core.problem.driver.Driver; -import jsprit.core.problem.job.Delivery; -import jsprit.core.problem.job.Job; -import jsprit.core.problem.job.Pickup; -import jsprit.core.problem.solution.route.ReverseRouteActivityVisitor; -import jsprit.core.problem.solution.route.VehicleRoute; -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; -import jsprit.core.util.CostFactory; -import org.junit.Before; -import org.junit.Test; - -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class UpdatePracticalTimeWindowTest { - - private VehicleRoutingTransportCosts routingCosts; - - private ReverseRouteActivityVisitor reverseActivityVisitor; - - private StateManager stateManager; - - private VehicleRoute route; - - @Before - public void doBefore() { - - routingCosts = CostFactory.createManhattanCosts(); - - VehicleRoutingProblem vrpMock = mock(VehicleRoutingProblem.class); - when(vrpMock.getFleetSize()).thenReturn(VehicleRoutingProblem.FleetSize.FINITE); - stateManager = new StateManager(vrpMock); - - reverseActivityVisitor = new ReverseRouteActivityVisitor(); - reverseActivityVisitor.addActivityVisitor(new UpdatePracticalTimeWindows(stateManager, routingCosts)); - - Pickup pickup = (Pickup) Pickup.Builder.newInstance("pick").setLocation(Location.newInstance("0,20")).setTimeWindow(TimeWindow.newInstance(0, 30)).build(); - Delivery delivery = (Delivery) Delivery.Builder.newInstance("del").setLocation(Location.newInstance("20,20")).setTimeWindow(TimeWindow.newInstance(10, 40)).build(); - Pickup pickup2 = (Pickup) Pickup.Builder.newInstance("pick2").setLocation(Location.newInstance("20,0")).setTimeWindow(TimeWindow.newInstance(20, 50)).build(); - - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("0,0")).setType(mock(VehicleType.class)).build(); - - VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); - final VehicleRoutingProblem vrp = vrpBuilder.addJob(pickup).addJob(pickup2).addJob(delivery).build(); - - route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).setJobActivityFactory(new JobActivityFactory() { - @Override - public List createActivities(Job job) { - return vrp.copyAndGetActivities(job); - } - }) - .addService(pickup).addService(delivery).addService(pickup2).build(); - - reverseActivityVisitor.visit(route); - - } - - @Test - public void whenVehicleRouteHasPickupAndDeliveryAndPickup_latestStartTimeOfAct3MustBeCorrect() { - assertEquals(50., route.getActivities().get(2).getTheoreticalLatestOperationStartTime(), 0.01); - assertEquals(50., stateManager.getActivityState(route.getActivities().get(2), InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); - } - - @Test - public void whenVehicleRouteHasPickupAndDeliveryAndPickup_latestStartTimeOfAct2MustBeCorrect() { - assertEquals(40., route.getActivities().get(1).getTheoreticalLatestOperationStartTime(), 0.01); - assertEquals(30., stateManager.getActivityState(route.getActivities().get(1), InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); - } - - @Test - public void whenVehicleRouteHasPickupAndDeliveryAndPickup_latestStartTimeOfAct1MustBeCorrect() { - assertEquals(30., route.getActivities().get(0).getTheoreticalLatestOperationStartTime(), 0.01); - assertEquals(10., stateManager.getActivityState(route.getActivities().get(0), InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); - } - -} diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdateVehicleDependentTimeWindowTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdateVehicleDependentTimeWindowTest.java index f0dc96bc..5d457a43 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdateVehicleDependentTimeWindowTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdateVehicleDependentTimeWindowTest.java @@ -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; @@ -192,7 +193,7 @@ public class UpdateVehicleDependentTimeWindowTest { .setRoutingCost(routingCosts).build(); VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle).setJobActivityFactory(vrp.getJobActivityFactory()) - .addService(service).addService(service2).build(); + .addService(service).addService(service2, TimeWindow.newInstance(70,80)).build(); StateManager stateManager = new StateManager(vrp); UpdateVehicleDependentPracticalTimeWindows updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager,routingCosts); diff --git a/jsprit-core/src/test/java/jsprit/core/analysis/SolutionAnalyserTest.java b/jsprit-core/src/test/java/jsprit/core/analysis/SolutionAnalyserTest.java index 1d1c3e4f..b3c98aee 100644 --- a/jsprit-core/src/test/java/jsprit/core/analysis/SolutionAnalyserTest.java +++ b/jsprit-core/src/test/java/jsprit/core/analysis/SolutionAnalyserTest.java @@ -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(); diff --git a/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java b/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java index c519b351..bc19ac63 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java @@ -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 { @@ -152,6 +154,27 @@ public class ServiceTest { assertEquals(2.0, s.getTimeWindow().getEnd(), 0.01); } + @Test + 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 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")) @@ -189,7 +212,7 @@ public class ServiceTest { Service s = Service.Builder.newInstance("s").setLocation(Location.newInstance("loc")) .addTimeWindow(TimeWindow.newInstance(0., 10.)).addTimeWindow(TimeWindow.newInstance(20., 30.)) .setName("name").build(); - assertEquals(2,s.getTimeWindows(0.).size()); + assertEquals(2,s.getTimeWindows().size()); } @Test(expected = IllegalStateException.class) diff --git a/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java b/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java index ac750087..57b45b5d 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java @@ -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") diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java index c0ad72c7..e059cadc 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java @@ -20,6 +20,7 @@ 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.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl; import org.junit.Test; @@ -42,6 +43,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 +54,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 +69,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 +87,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 +107,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 +131,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 +159,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 +186,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()); diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/BreakActivityTest.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/BreakActivityTest.java index 0d168850..9ffa63aa 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/BreakActivityTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/BreakActivityTest.java @@ -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 diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/DeliverServiceTest.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/DeliverServiceTest.java index 880ca947..685a699c 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/DeliverServiceTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/DeliverServiceTest.java @@ -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 diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/DeliverShipmentTest.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/DeliverShipmentTest.java index c26fff73..bd94b2e5 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/DeliverShipmentTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/DeliverShipmentTest.java @@ -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 diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/PickupServiceTest.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/PickupServiceTest.java index 2593ff2a..c192c644 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/PickupServiceTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/PickupServiceTest.java @@ -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 diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/PickupShipmentTest.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/PickupShipmentTest.java index 3627d7c0..b7e3e07d 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/PickupShipmentTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/PickupShipmentTest.java @@ -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 diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/ServiceActivityTest.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/ServiceActivityTest.java index 15ead4cd..5c4a672a 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/ServiceActivityTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/activity/ServiceActivityTest.java @@ -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 diff --git a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml index 2d9058ab..07c5406a 100644 --- a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml +++ b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml @@ -2,9 +2,24 @@ - INFINITE + FINITE + + v2 + vehType2 + + loc + + + loc + + + 0.0 + 1.7976931348623157E308 + + true + v1 vehType @@ -33,58 +48,16 @@ + + vehType2 + + 200 + + + 0.0 + 1.0 + + + - - - - loc - - - 1 - - 2.0 - - - 0.0 - 1.7976931348623157E308 - - - - - - loc2 - - - 1 - - 4.0 - - - 0.0 - 1.7976931348623157E308 - - - - - - - 10.0 - - - noDriver - v1 - 0.0 - - 1 - 0.0 - 0.0 - - 0.0 - - - - - - - diff --git a/jsprit-examples/src/main/java/jsprit/examples/MultipleTimeWindowExample.java b/jsprit-examples/src/main/java/jsprit/examples/MultipleTimeWindowExample.java index 6ad57b16..9d8206d6 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/MultipleTimeWindowExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/MultipleTimeWindowExample.java @@ -58,28 +58,30 @@ public class MultipleTimeWindowExample { * build services at the required locations, each with a capacity-demand of 1. */ Service service1 = Service.Builder.newInstance("1") - .addTimeWindow(5, 10) + .addTimeWindow(50,100) .addTimeWindow(20,35) .addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(10, 0)).build(); Service service2 = Service.Builder.newInstance("2") - .addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(20, 0)).build(); + .addSizeDimension(WEIGHT_INDEX, 1) +// .setServiceTime(10) + .setLocation(Location.newInstance(20, 0)).setServiceTime(10).build(); Service service3 = Service.Builder.newInstance("3") .addTimeWindow(5, 10) - .addTimeWindow(35, 40) + .addTimeWindow(35, 50) .addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(30, 0)).build(); Service service4 = Service.Builder.newInstance("4") // .addTimeWindow(5,10) .addTimeWindow(20, 40) - .addTimeWindow(70, 80) + .addTimeWindow(45, 80) .addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(40, 0)).build(); Service service5 = Service.Builder.newInstance("5") .addTimeWindow(5,10) -// .addTimeWindow(20, 40) - .addTimeWindow(35,100) + .addTimeWindow(20, 40) + .addTimeWindow(60,100) .addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(20, 0)).build(); diff --git a/jsprit-examples/src/main/java/jsprit/examples/MultipleTimeWindowExample2.java b/jsprit-examples/src/main/java/jsprit/examples/MultipleTimeWindowExample2.java new file mode 100644 index 00000000..8aff3890 --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/MultipleTimeWindowExample2.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (C) 2014 Stefan Schroeder + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + ******************************************************************************/ +package jsprit.examples; + +import jsprit.analysis.toolbox.Plotter; +import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.box.Jsprit; +import jsprit.core.analysis.SolutionAnalyser; +import jsprit.core.problem.Location; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.cost.TransportDistance; +import jsprit.core.problem.job.Service; +import jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import jsprit.core.problem.vehicle.VehicleImpl; +import jsprit.core.problem.vehicle.VehicleImpl.Builder; +import jsprit.core.problem.vehicle.VehicleType; +import jsprit.core.problem.vehicle.VehicleTypeImpl; +import jsprit.core.reporting.SolutionPrinter; +import jsprit.core.util.RandomNumberGeneration; +import jsprit.core.util.Solutions; + +import java.util.Collection; +import java.util.Random; + + +public class MultipleTimeWindowExample2 { + + + public static void main(String[] args) { + + /* + * get a vehicle type-builder and build a type with the typeId "vehicleType" and one capacity dimension, i.e. weight, and capacity dimension value of 2 + */ + VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType") + .addCapacityDimension(0, 60) + .setCostPerWaitingTime(0.8) + ; + VehicleType vehicleType = vehicleTypeBuilder.build(); + + /* + * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" + */ + Builder vehicleBuilder = Builder.newInstance("vehicle"); + vehicleBuilder.setStartLocation(Location.newInstance(0, 0)); + vehicleBuilder.setType(vehicleType); + vehicleBuilder.setLatestArrival(800); + VehicleImpl vehicle = vehicleBuilder.build(); + +// Builder vehicleBuilder2 = Builder.newInstance("vehicle2"); +// vehicleBuilder2.setStartLocation(Location.newInstance(0, 0)); +// vehicleBuilder2.setType(vehicleType); +// vehicleBuilder2.setEarliestStart(250).setLatestArrival(450); +// VehicleImpl vehicle2 = vehicleBuilder2.build(); +// +// +// Builder vehicleBuilder3 = Builder.newInstance("vehicle3"); +// vehicleBuilder3.setStartLocation(Location.newInstance(0, 0)); +// vehicleBuilder3.setType(vehicleType); +// vehicleBuilder3.setEarliestStart(380).setLatestArrival(600); +// VehicleImpl vehicle3 = vehicleBuilder3.build(); + + /* + * build services at the required locations, each with a capacity-demand of 1. + */ + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addVehicle(vehicle); +// .addVehicle(vehicle2).addVehicle(vehicle3); + vrpBuilder.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE); + + + Random random = RandomNumberGeneration.newInstance(); + for(int i=0;i<40;i++){ + Service service = Service.Builder.newInstance("" + (i + 1)) + .addTimeWindow(random.nextInt(50), 200) + .addTimeWindow(220 + random.nextInt(50), 350) + .addTimeWindow(400 + random.nextInt(50), 550) +// .addSizeDimension(0, 1) + .setServiceTime(1) + .setLocation(Location.newInstance(random.nextInt(50), random.nextInt(50))).build(); + vrpBuilder.addJob(service); + } + + for(int i=0;i<12;i++){ + Service service = Service.Builder.newInstance(""+(i+51)) +// .addTimeWindow(0, 80) +//// .addTimeWindow(120, 200) +// .addTimeWindow(250,500) +// .addSizeDimension(0, 1) + .setServiceTime(2) + .setLocation(Location.newInstance(50 + random.nextInt(20), 20 + random.nextInt(25))).build(); + vrpBuilder.addJob(service); + } + + Service service = Service.Builder.newInstance("100") + .addTimeWindow(50, 80) + .setServiceTime(10) + .setLocation(Location.newInstance(40, 1)).build(); + vrpBuilder.addJob(service); + + final VehicleRoutingProblem problem = vrpBuilder.build(); + + VehicleRoutingAlgorithm algorithm = Jsprit.Builder.newInstance(problem).buildAlgorithm(); + + /* + * and search a solution + */ + Collection solutions = algorithm.searchSolutions(); + + /* + * get the best + */ + VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions); + +// new VrpXMLWriter(problem, solutions).write("output/problem-with-solution.xml"); + + SolutionPrinter.print(problem, bestSolution, SolutionPrinter.Print.VERBOSE); + + /* + * plot + */ + new Plotter(problem,bestSolution).setLabel(Plotter.Label.ID).plot("output/plot", "mtw"); + + SolutionAnalyser a = new SolutionAnalyser(problem, bestSolution, new TransportDistance() { + @Override + public double getDistance(Location from, Location to) { + return problem.getTransportCosts().getTransportTime(from,to,0.,null,null); + } + }); + + System.out.println("distance: " + a.getDistance()); + System.out.println("ttime: " + a.getTransportTime()); + System.out.println("completion: " + a.getOperationTime()); + System.out.println("waiting: " + a.getWaitingTime()); + +// new GraphStreamViewer(problem, bestSolution).labelWith(Label.ID).setRenderDelay(200).display(); + } + +} diff --git a/jsprit-instances/src/main/java/jsprit/instance/reader/BelhaizaReader.java b/jsprit-instances/src/main/java/jsprit/instance/reader/BelhaizaReader.java index 95deb5b4..2707e75f 100644 --- a/jsprit-instances/src/main/java/jsprit/instance/reader/BelhaizaReader.java +++ b/jsprit-instances/src/main/java/jsprit/instance/reader/BelhaizaReader.java @@ -11,7 +11,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . ******************************************************************************/ package jsprit.instance.reader; @@ -35,16 +35,18 @@ import java.io.IOException; /** * Reader that reads the well-known solomon-instances. - * + * *

See: neo.org - * + * * @author stefan * */ public class BelhaizaReader { - /** + private int fixedCosts; + + /** * @param costProjectionFactor the costProjectionFactor to set */ public void setVariableCostProjectionFactor(double costProjectionFactor) { @@ -73,7 +75,7 @@ public class BelhaizaReader { this.vrpBuilder = vrpBuilder; this.fixedCostPerVehicle=fixedCostPerVehicle; } - + public void read(String solomonFile){ vrpBuilder.setFleetSize(FleetSize.INFINITE); BufferedReader reader = getReader(solomonFile); @@ -95,8 +97,10 @@ public class BelhaizaReader { double serviceTime = Double.parseDouble(tokens[3])*timeProjectionFactor; if(counter == 3){ VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance("solomonType").addCapacityDimension(0, vehicleCapacity); - typeBuilder.setCostPerDistance(1.0*variableCostProjectionFactor).setFixedCost(fixedCostPerVehicle); - VehicleTypeImpl vehicleType = typeBuilder.build(); + typeBuilder.setCostPerDistance(1.0*variableCostProjectionFactor).setFixedCost(fixedCostPerVehicle) + .setCostPerWaitingTime(0.8); + System.out.println("fix: " + fixedCostPerVehicle + "; perDistance: 1.0; perWaitingTime: 0.8"); + VehicleTypeImpl vehicleType = typeBuilder.build(); double end = Double.parseDouble(tokens[8])*timeProjectionFactor; for(int i=0;i<10;i++) { VehicleImpl vehicle = VehicleImpl.Builder.newInstance("solomonVehicle"+(i+1)).setEarliestStart(0.).setLatestArrival(end) @@ -104,7 +108,7 @@ public class BelhaizaReader { .setCoordinate(coord).build()).setType(vehicleType).build(); vrpBuilder.addVehicle(vehicle); } - + } else{ Service.Builder serviceBuilder = Service.Builder.newInstance(customerId); @@ -146,7 +150,7 @@ public class BelhaizaReader { return null; } } - + private Coordinate makeCoord(String xString, String yString) { double x = Double.parseDouble(xString); double y = Double.parseDouble(yString); @@ -167,6 +171,10 @@ public class BelhaizaReader { public void setTimeProjectionFactor(double timeProjection) { this.timeProjectionFactor=timeProjection; - + } + + public void setFixedCosts(int fixedCosts) { + this.fixedCostPerVehicle = fixedCosts; + } } diff --git a/jsprit-instances/src/test/java/jsprit/instance/reader/BelhaizaReaderTest.java b/jsprit-instances/src/test/java/jsprit/instance/reader/BelhaizaReaderTest.java index e1751855..edca9b01 100644 --- a/jsprit-instances/src/test/java/jsprit/instance/reader/BelhaizaReaderTest.java +++ b/jsprit-instances/src/test/java/jsprit/instance/reader/BelhaizaReaderTest.java @@ -1,17 +1,17 @@ /******************************************************************************* * Copyright (C) 2013 Stefan Schroeder - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either + * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public + * + * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . ******************************************************************************/ package jsprit.instance.reader; @@ -36,7 +36,7 @@ import static org.junit.Assert.assertEquals; public class BelhaizaReaderTest { - + @Test public void whenReadingBelhaizaInstance_nuOfCustomersIsCorrect(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); @@ -58,7 +58,7 @@ public class BelhaizaReaderTest { VehicleRoutingProblem vrp = builder.build(); assertEquals(FleetSize.INFINITE,vrp.getFleetSize()); } - + @Test public void whenReadingBelhaizaInstance_vehicleCapacitiesAreCorrect(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); @@ -68,7 +68,7 @@ public class BelhaizaReaderTest { assertEquals(200,v.getType().getCapacityDimensions().get(0)); } } - + @Test public void whenReadingBelhaizaInstance_vehicleLocationsAreCorrect_and_correspondToDepotLocation(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); @@ -79,7 +79,7 @@ public class BelhaizaReaderTest { assertEquals(50.0,v.getStartLocation().getCoordinate().getY(),0.01); } } - + @Test public void whenReadingBelhaizaInstance_demandOfCustomerOneIsCorrect(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); @@ -87,7 +87,7 @@ public class BelhaizaReaderTest { VehicleRoutingProblem vrp = builder.build(); assertEquals(10,vrp.getJobs().get("1").getSize().get(0)); } - + @Test public void whenReadingBelhaizaInstance_serviceDurationOfCustomerTwoIsCorrect(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); @@ -101,7 +101,7 @@ public class BelhaizaReaderTest { VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); new BelhaizaReader(builder).read(getPath()); VehicleRoutingProblem vrp = builder.build(); - assertEquals(5,((Service)vrp.getJobs().get("1")).getTimeWindows(0.).size()); + assertEquals(5,((Service)vrp.getJobs().get("1")).getTimeWindows().size()); } @Test @@ -109,7 +109,7 @@ public class BelhaizaReaderTest { VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); new BelhaizaReader(builder).read(getPath()); VehicleRoutingProblem vrp = builder.build(); - assertEquals(10,((Service)vrp.getJobs().get("2")).getTimeWindows(0.).size()); + assertEquals(10,((Service)vrp.getJobs().get("2")).getTimeWindows().size()); } @Test @@ -117,8 +117,8 @@ public class BelhaizaReaderTest { VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); new BelhaizaReader(builder).read(getPath()); VehicleRoutingProblem vrp = builder.build(); - assertEquals(20.,((Service)vrp.getJobs().get("1")).getTimeWindows(0.).iterator().next().getStart(),0.1); - assertEquals(31.,((Service)vrp.getJobs().get("1")).getTimeWindows(0.).iterator().next().getEnd(),0.1); + assertEquals(20.,((Service)vrp.getJobs().get("1")).getTimeWindows().iterator().next().getStart(),0.1); + assertEquals(31.,((Service)vrp.getJobs().get("1")).getTimeWindows().iterator().next().getEnd(),0.1); } @Test @@ -126,7 +126,7 @@ public class BelhaizaReaderTest { VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); new BelhaizaReader(builder).read(getPath()); VehicleRoutingProblem vrp = builder.build(); - List timeWindows = new ArrayList(((Service)vrp.getJobs().get("1")).getTimeWindows(0.)); + List timeWindows = new ArrayList(((Service)vrp.getJobs().get("1")).getTimeWindows()); assertEquals(118.,timeWindows.get(1).getStart(),0.1); assertEquals(148.,timeWindows.get(1).getEnd(),0.1); } @@ -136,7 +136,7 @@ public class BelhaizaReaderTest { VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); new BelhaizaReader(builder).read(getPath()); VehicleRoutingProblem vrp = builder.build(); - List timeWindows = new ArrayList(((Service)vrp.getJobs().get("1")).getTimeWindows(0.)); + List timeWindows = new ArrayList(((Service)vrp.getJobs().get("1")).getTimeWindows()); assertEquals(235.,timeWindows.get(2).getStart(),0.1); assertEquals(258.,timeWindows.get(2).getEnd(),0.1); } @@ -146,7 +146,7 @@ public class BelhaizaReaderTest { VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); new BelhaizaReader(builder).read(getPath()); VehicleRoutingProblem vrp = builder.build(); - List timeWindows = new ArrayList(((Service)vrp.getJobs().get("1")).getTimeWindows(0.)); + List timeWindows = new ArrayList(((Service)vrp.getJobs().get("1")).getTimeWindows()); assertEquals(343.,timeWindows.get(3).getStart(),0.1); assertEquals(355.,timeWindows.get(3).getEnd(),0.1); } @@ -156,7 +156,7 @@ public class BelhaizaReaderTest { VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); new BelhaizaReader(builder).read(getPath()); VehicleRoutingProblem vrp = builder.build(); - List timeWindows = new ArrayList(((Service)vrp.getJobs().get("1")).getTimeWindows(0.)); + List timeWindows = new ArrayList(((Service)vrp.getJobs().get("1")).getTimeWindows()); assertEquals(441.,timeWindows.get(4).getStart(),0.1); assertEquals(457.,timeWindows.get(4).getEnd(),0.1); } diff --git a/pom.xml b/pom.xml index ab9124ab..121bdc1d 100644 --- a/pom.xml +++ b/pom.xml @@ -84,6 +84,7 @@ UTF-8 4.10 1.9.5 + 1.3 2.0 false @@ -271,6 +272,8 @@ test + + org.apache.logging.log4j log4j-api