From 390340140f83c39f3e9d53bbbc1eb0813f79ffeb Mon Sep 17 00:00:00 2001 From: oblonski Date: Tue, 22 Dec 2015 09:16:27 +0100 Subject: [PATCH 1/3] add getActivityDuration method --- .../core/problem/cost/VehicleRoutingActivityCosts.java | 1 + .../main/java/jsprit/core/problem/cost/WaitingTimeCosts.java | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/jsprit-core/src/main/java/jsprit/core/problem/cost/VehicleRoutingActivityCosts.java b/jsprit-core/src/main/java/jsprit/core/problem/cost/VehicleRoutingActivityCosts.java index ec9ea858..812ed19b 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/cost/VehicleRoutingActivityCosts.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/cost/VehicleRoutingActivityCosts.java @@ -58,5 +58,6 @@ public interface VehicleRoutingActivityCosts { */ public double getActivityCost(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle); + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle); } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/cost/WaitingTimeCosts.java b/jsprit-core/src/main/java/jsprit/core/problem/cost/WaitingTimeCosts.java index 73b9a35a..183aafc5 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/cost/WaitingTimeCosts.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/cost/WaitingTimeCosts.java @@ -19,4 +19,9 @@ public class WaitingTimeCosts implements VehicleRoutingActivityCosts { return 0; } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + } From e5f6edeae4f464b9d7aa475daf141692292fd73d Mon Sep 17 00:00:00 2001 From: oblonski Date: Wed, 6 Jan 2016 20:52:43 +0100 Subject: [PATCH 2/3] switch to getActivityDuration method --- .../algorithm/PrettyAlgorithmBuilder.java | 4 +- .../io/VehicleRoutingAlgorithms.java | 4 +- .../recreate/AuxilliaryCostCalculator.java | 2 +- .../recreate/BreakInsertionCalculator.java | 9 +- .../JobInsertionCostsCalculatorBuilder.java | 6 +- ...LocalActivityInsertionCostsCalculator.java | 7 +- .../recreate/ServiceInsertionCalculator.java | 9 +- ...erviceInsertionOnRouteLevelCalculator.java | 2 +- .../recreate/ShipmentInsertionCalculator.java | 15 +- .../VariableTransportCostCalculator.java | 11 +- .../algorithm/state/UpdateActivityTimes.java | 9 +- .../state/UpdatePracticalTimeWindows.java | 8 +- .../algorithm/state/UpdateVariableCosts.java | 4 +- ...eVehicleDependentPracticalTimeWindows.java | 8 +- .../core/analysis/SolutionAnalyser.java | 12 +- .../AdditionalTransportationCosts.java | 10 +- .../problem/constraint/ConstraintManager.java | 2 +- .../constraint/TimeWindowConstraint.java | 142 ------------------ ...VehicleDependentTimeWindowConstraints.java | 11 +- .../core/problem/cost/WaitingTimeCosts.java | 2 +- .../jsprit/core/util/ActivityTimeTracker.java | 13 +- .../jsprit/core/util/CalculationUtils.java | 1 + .../java/jsprit/core/util/RouteUtils.java | 111 -------------- .../ExampleActivityCostFunction.java | 7 +- .../VariableDepartureAndWaitingTime_IT.java | 5 + ...erviceInsertionAndLoadConstraintsTest.java | 11 +- .../ShipmentInsertionCalculatorTest.java | 15 +- .../TestCalculatesServiceInsertion.java | 2 +- .../recreate/TestDepartureTimeOpt.java | 30 ++++ ...LocalActivityInsertionCostsCalculator.java | 6 +- ...teLevelActivityInsertionCostEstimator.java | 5 + ...uteLevelServiceInsertionCostEstimator.java | 5 + .../state/UpdatePracticalTimeWindowTest.java | 7 +- .../UpdateVehicleDependentTimeWindowTest.java | 9 +- .../problem/VehicleRoutingProblemTest.java | 5 + .../VehicleDependentTimeWindowTest.java | 33 ++-- ...wWithStartTimeAndMaxOperationTimeTest.java | 31 ++-- .../test/resources/infiniteWriterV2Test.xml | 81 ++++++---- .../jsprit/examples/MultipleDepotExample.java | 2 +- 39 files changed, 277 insertions(+), 379 deletions(-) delete mode 100644 jsprit-core/src/main/java/jsprit/core/problem/constraint/TimeWindowConstraint.java delete mode 100644 jsprit-core/src/main/java/jsprit/core/util/RouteUtils.java diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/PrettyAlgorithmBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/PrettyAlgorithmBuilder.java index 733bb05c..77bf3fda 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/PrettyAlgorithmBuilder.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/PrettyAlgorithmBuilder.java @@ -93,7 +93,7 @@ public class PrettyAlgorithmBuilder { constraintManager.addConstraint(new SwitchNotFeasible(stateManager)); stateManager.updateLoadStates(); stateManager.updateTimeWindowStates(); - UpdateVehicleDependentPracticalTimeWindows twUpdater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts()); + UpdateVehicleDependentPracticalTimeWindows twUpdater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts()); twUpdater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() { Map uniqueTypes = new HashMap(); @@ -116,7 +116,7 @@ public class PrettyAlgorithmBuilder { stateManager.addStateUpdater(twUpdater); stateManager.updateSkillStates(); stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen()); - stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS)); + stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS, vrp.getActivityCosts())); stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager)); stateManager.addStateUpdater(new UpdateFutureWaitingTimes(stateManager, vrp.getTransportCosts())); } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java index f0ea52a3..4fc12840 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java @@ -542,7 +542,7 @@ public class VehicleRoutingAlgorithms { } else switchAllowed = true; ActivityTimeTracker.ActivityPolicy activityPolicy; if (stateManager.timeWindowUpdateIsActivated()) { - UpdateVehicleDependentPracticalTimeWindows timeWindowUpdater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts()); + UpdateVehicleDependentPracticalTimeWindows timeWindowUpdater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts()); timeWindowUpdater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() { Map uniqueTypes = new HashMap(); @@ -565,7 +565,7 @@ public class VehicleRoutingAlgorithms { } else { activityPolicy = ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_ARRIVED; } - stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), activityPolicy)); + stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), activityPolicy, vrp.getActivityCosts())); stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager, activityPolicy)); final SolutionCostCalculator costCalculator; diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java index c8ab1b1d..dc60e412 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java @@ -67,7 +67,7 @@ final class AuxilliaryCostCalculator { double transportTime = routingCosts.getTransportTime(prevAct.getLocation(), act.getLocation(), departureTimePrevAct, driver, vehicle); cost += transportCost; double actStartTime = departureTimePrevAct + transportTime; - departureTimePrevAct = Math.max(actStartTime, act.getTheoreticalEarliestOperationStartTime()) + act.getOperationTime(); + departureTimePrevAct = Math.max(actStartTime, act.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(act,actStartTime,driver,vehicle); cost += activityCosts.getActivityCost(act, actStartTime, driver, vehicle); prevAct = act; } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/BreakInsertionCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/BreakInsertionCalculator.java index bdf14b0f..268a9c2c 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/BreakInsertionCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/BreakInsertionCalculator.java @@ -20,6 +20,7 @@ import jsprit.core.problem.JobActivityFactory; import jsprit.core.problem.Location; import jsprit.core.problem.constraint.*; import jsprit.core.problem.constraint.HardActivityConstraint.ConstraintsStatus; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.driver.Driver; import jsprit.core.problem.job.Break; @@ -31,7 +32,6 @@ import jsprit.core.problem.solution.route.activity.End; import jsprit.core.problem.solution.route.activity.Start; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.Vehicle; -import jsprit.core.util.CalculationUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -58,15 +58,18 @@ final class BreakInsertionCalculator implements JobInsertionCostsCalculator { private VehicleRoutingTransportCosts transportCosts; + private final VehicleRoutingActivityCosts activityCosts; + private ActivityInsertionCostsCalculator additionalTransportCostsCalculator; private JobActivityFactory activityFactory; private AdditionalAccessEgressCalculator additionalAccessEgressCalculator; - public BreakInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator additionalTransportCostsCalculator, ConstraintManager constraintManager) { + public BreakInsertionCalculator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts, ActivityInsertionCostsCalculator additionalTransportCostsCalculator, ConstraintManager constraintManager) { super(); this.transportCosts = routingCosts; + this.activityCosts = activityCosts; hardRouteLevelConstraint = constraintManager; hardActivityLevelConstraint = constraintManager; softActivityConstraint = constraintManager; @@ -159,7 +162,7 @@ final class BreakInsertionCalculator implements JobInsertionCostsCalculator { } } double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActStartTime, newDriver, newVehicle); - prevActStartTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct); + prevActStartTime = Math.max(nextActArrTime, nextAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(nextAct,nextActArrTime,newDriver,newVehicle); prevAct = nextAct; actIndex++; if (breakThis) break; diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionCostsCalculatorBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionCostsCalculatorBuilder.java index 1a056438..ee739020 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionCostsCalculatorBuilder.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/JobInsertionCostsCalculatorBuilder.java @@ -286,12 +286,12 @@ public class JobInsertionCostsCalculatorBuilder { } }; - ShipmentInsertionCalculator shipmentInsertion = new ShipmentInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager); + ShipmentInsertionCalculator shipmentInsertion = new ShipmentInsertionCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), actInsertionCalc, constraintManager); shipmentInsertion.setJobActivityFactory(activityFactory); - ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager); + ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), actInsertionCalc, constraintManager); serviceInsertion.setJobActivityFactory(activityFactory); - BreakInsertionCalculator breakInsertionCalculator = new BreakInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager); + BreakInsertionCalculator breakInsertionCalculator = new BreakInsertionCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), actInsertionCalc, constraintManager); breakInsertionCalculator.setJobActivityFactory(activityFactory); JobCalculatorSwitcher switcher = new JobCalculatorSwitcher(); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/LocalActivityInsertionCostsCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/LocalActivityInsertionCostsCalculator.java index 11b42742..0e74aad8 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/LocalActivityInsertionCostsCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/LocalActivityInsertionCostsCalculator.java @@ -25,7 +25,6 @@ import jsprit.core.problem.solution.route.activity.End; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter; import jsprit.core.problem.vehicle.Vehicle; -import jsprit.core.util.CalculationUtils; /** * Calculates activity insertion costs locally, i.e. by comparing the additional costs of insertion the new activity k between @@ -61,7 +60,7 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocation(), newAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct; - double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct); + double newAct_endTime = Math.max(newAct_arrTime, newAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); @@ -70,7 +69,7 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal double tp_costs_newAct_nextAct = routingCosts.getTransportCost(newAct.getLocation(), nextAct.getLocation(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double tp_time_newAct_nextAct = routingCosts.getTransportTime(newAct.getLocation(), nextAct.getLocation(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double nextAct_arrTime = newAct_endTime + tp_time_newAct_nextAct; - double endTime_nextAct_new = CalculationUtils.getActivityEndTime(nextAct_arrTime, nextAct); + double endTime_nextAct_new = Math.max(nextAct_arrTime, nextAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(nextAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double act_costs_nextAct = activityCosts.getActivityCost(nextAct, nextAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct + solutionCompletenessRatio * activityCostsWeight * (act_costs_newAct + act_costs_nextAct); @@ -82,7 +81,7 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal } else { double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle()); double arrTime_nextAct = depTimeAtPrevAct + routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle()); - double endTime_nextAct_old = CalculationUtils.getActivityEndTime(arrTime_nextAct, nextAct); + double endTime_nextAct_old = Math.max(arrTime_nextAct, nextAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(nextAct, nextAct_arrTime, iFacts.getRoute().getDriver(),iFacts.getRoute().getVehicle()); double actCost_nextAct = activityCosts.getActivityCost(nextAct, arrTime_nextAct, iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle()); double endTimeDelay_nextAct = Math.max(0, endTime_nextAct_new - endTime_nextAct_old); 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 d530c49c..0c368e81 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 @@ -19,6 +19,7 @@ package jsprit.core.algorithm.recreate; import jsprit.core.problem.JobActivityFactory; import jsprit.core.problem.constraint.*; import jsprit.core.problem.constraint.HardActivityConstraint.ConstraintsStatus; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.driver.Driver; import jsprit.core.problem.job.Job; @@ -29,7 +30,6 @@ import jsprit.core.problem.solution.route.activity.End; import jsprit.core.problem.solution.route.activity.Start; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.Vehicle; -import jsprit.core.util.CalculationUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -54,15 +54,18 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator { private VehicleRoutingTransportCosts transportCosts; + private final VehicleRoutingActivityCosts activityCosts; + private ActivityInsertionCostsCalculator additionalTransportCostsCalculator; private JobActivityFactory activityFactory; private AdditionalAccessEgressCalculator additionalAccessEgressCalculator; - public ServiceInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator additionalTransportCostsCalculator, ConstraintManager constraintManager) { + public ServiceInsertionCalculator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts, ActivityInsertionCostsCalculator additionalTransportCostsCalculator, ConstraintManager constraintManager) { super(); this.transportCosts = routingCosts; + this.activityCosts = activityCosts; hardRouteLevelConstraint = constraintManager; hardActivityLevelConstraint = constraintManager; softActivityConstraint = constraintManager; @@ -141,7 +144,7 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator { break; } double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActStartTime, newDriver, newVehicle); - prevActStartTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct); + prevActStartTime = Math.max(nextActArrTime, nextAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(nextAct,nextActArrTime,newDriver,newVehicle); prevAct = nextAct; actIndex++; } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionOnRouteLevelCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionOnRouteLevelCalculator.java index 0f189d16..66ca9041 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionOnRouteLevelCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionOnRouteLevelCalculator.java @@ -203,7 +203,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC /** * departure time at nextAct with new vehicle */ - double depTime_nextAct_newVehicle = Math.max(arrTime_nextAct_newVehicle, nextAct.getTheoreticalEarliestOperationStartTime()) + nextAct.getOperationTime(); + double depTime_nextAct_newVehicle = Math.max(arrTime_nextAct_newVehicle, nextAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(nextAct, arrTime_nextAct_newVehicle,newDriver,newVehicle); /** * set previous to next 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..f490cc25 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 @@ -19,6 +19,7 @@ package jsprit.core.algorithm.recreate; import jsprit.core.problem.JobActivityFactory; import jsprit.core.problem.constraint.*; import jsprit.core.problem.constraint.HardActivityConstraint.ConstraintsStatus; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.driver.Driver; import jsprit.core.problem.job.Job; @@ -30,7 +31,6 @@ import jsprit.core.problem.solution.route.activity.End; import jsprit.core.problem.solution.route.activity.Start; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.Vehicle; -import jsprit.core.util.CalculationUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -53,11 +53,13 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator { private VehicleRoutingTransportCosts transportCosts; + private final VehicleRoutingActivityCosts activityCosts; + private JobActivityFactory activityFactory; private AdditionalAccessEgressCalculator additionalAccessEgressCalculator; - public ShipmentInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, ConstraintManager constraintManager) { + public ShipmentInsertionCalculator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, ConstraintManager constraintManager) { super(); this.activityInsertionCostsCalculator = activityInsertionCostsCalculator; this.hardRouteLevelConstraint = constraintManager; @@ -65,6 +67,7 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator { this.softActivityConstraint = constraintManager; this.softRouteConstraint = constraintManager; this.transportCosts = routingCosts; + this.activityCosts = activityCosts; additionalAccessEgressCalculator = new AdditionalAccessEgressCalculator(routingCosts); logger.debug("initialise {}", this); } @@ -136,7 +139,7 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator { 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); + prevActEndTime = Math.max(nextActArrTime, nextAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(nextAct,nextActArrTime,newDriver,newVehicle); prevAct = nextAct; i++; continue; @@ -148,7 +151,7 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator { TourActivity prevAct_deliveryLoop = pickupShipment; double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), pickupShipment.getLocation(), prevActEndTime, newDriver, newVehicle); - double shipmentPickupEndTime = CalculationUtils.getActivityEndTime(shipmentPickupArrTime, pickupShipment); + double shipmentPickupEndTime = Math.max(shipmentPickupArrTime, pickupShipment.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(pickupShipment, shipmentPickupArrTime,newDriver,newVehicle); pickupContext.setArrivalTime(shipmentPickupArrTime); pickupContext.setEndTime(shipmentPickupEndTime); @@ -190,13 +193,13 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator { } //update prevAct and endTime double nextActArrTime = prevActEndTime_deliveryLoop + transportCosts.getTransportTime(prevAct_deliveryLoop.getLocation(), nextAct_deliveryLoop.getLocation(), prevActEndTime_deliveryLoop, newDriver, newVehicle); - prevActEndTime_deliveryLoop = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct_deliveryLoop); + prevActEndTime_deliveryLoop = Math.max(nextActArrTime, nextAct_deliveryLoop.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(nextAct_deliveryLoop,nextActArrTime,newDriver,newVehicle); prevAct_deliveryLoop = nextAct_deliveryLoop; j++; } //update prevAct and endTime double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActEndTime, newDriver, newVehicle); - prevActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct); + prevActEndTime = Math.max(nextActArrTime, nextAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(nextAct,nextActArrTime,newDriver,newVehicle); prevAct = nextAct; i++; } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/VariableTransportCostCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/VariableTransportCostCalculator.java index 29b401bb..bc7b3a69 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/VariableTransportCostCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/VariableTransportCostCalculator.java @@ -17,19 +17,22 @@ package jsprit.core.algorithm.recreate; import jsprit.core.problem.constraint.SoftActivityConstraint; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.misc.JobInsertionContext; import jsprit.core.problem.solution.route.activity.End; import jsprit.core.problem.solution.route.activity.TourActivity; -import jsprit.core.util.CalculationUtils; public class VariableTransportCostCalculator implements SoftActivityConstraint { - private VehicleRoutingTransportCosts routingCosts; + private final VehicleRoutingTransportCosts routingCosts; - public VariableTransportCostCalculator(VehicleRoutingTransportCosts routingCosts) { + private final VehicleRoutingActivityCosts activityCosts; + + public VariableTransportCostCalculator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) { super(); this.routingCosts = routingCosts; + this.activityCosts = activityCosts; } @Override @@ -38,7 +41,7 @@ public class VariableTransportCostCalculator implements SoftActivityConstraint { double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct; - double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct); + double newAct_endTime = Math.max(newAct_arrTime, newAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(newAct,newAct_arrTime,iFacts.getNewDriver(),iFacts.getNewVehicle()); //open routes if (nextAct instanceof End) { 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 175c8701..a2d9b02c 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 @@ -17,6 +17,7 @@ package jsprit.core.algorithm.state; import jsprit.core.problem.cost.ForwardTransportTime; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.activity.ActivityVisitor; import jsprit.core.problem.solution.route.activity.TourActivity; @@ -45,13 +46,13 @@ public class UpdateActivityTimes implements ActivityVisitor, StateUpdater { * activity.getArrTime() and * activity.getEndTime() */ - public UpdateActivityTimes(ForwardTransportTime transportTime) { + public UpdateActivityTimes(ForwardTransportTime transportTime, VehicleRoutingActivityCosts activityCosts) { super(); - timeTracker = new ActivityTimeTracker(transportTime); + timeTracker = new ActivityTimeTracker(transportTime,activityCosts ); } - public UpdateActivityTimes(ForwardTransportTime transportTime, ActivityTimeTracker.ActivityPolicy activityPolicy) { - timeTracker = new ActivityTimeTracker(transportTime, activityPolicy); + public UpdateActivityTimes(ForwardTransportTime transportTime, ActivityTimeTracker.ActivityPolicy activityPolicy, VehicleRoutingActivityCosts activityCosts) { + timeTracker = new ActivityTimeTracker(transportTime, activityPolicy, activityCosts); } @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 index 2ed9d99d..4000b917 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdatePracticalTimeWindows.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdatePracticalTimeWindows.java @@ -16,6 +16,7 @@ ******************************************************************************/ package jsprit.core.algorithm.state; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.activity.ReverseActivityVisitor; @@ -34,14 +35,17 @@ class UpdatePracticalTimeWindows implements ReverseActivityVisitor, StateUpdater private VehicleRoutingTransportCosts transportCosts; + private VehicleRoutingActivityCosts activityCosts; + private double latestArrTimeAtPrevAct; private TourActivity prevAct; - public UpdatePracticalTimeWindows(StateManager states, VehicleRoutingTransportCosts tpCosts) { + public UpdatePracticalTimeWindows(StateManager states, VehicleRoutingTransportCosts tpCosts, VehicleRoutingActivityCosts activityCosts) { super(); this.states = states; this.transportCosts = tpCosts; + this.activityCosts = activityCosts; } @Override @@ -53,7 +57,7 @@ class UpdatePracticalTimeWindows implements ReverseActivityVisitor, StateUpdater @Override public void visit(TourActivity activity) { - double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocation(), prevAct.getLocation(), latestArrTimeAtPrevAct, route.getDriver(), route.getVehicle()) - activity.getOperationTime(); + double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocation(), prevAct.getLocation(), latestArrTimeAtPrevAct, route.getDriver(), route.getVehicle()) - activityCosts.getActivityDuration(activity,latestArrTimeAtPrevAct,route.getDriver(),route.getVehicle()); double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct); states.putInternalTypedActivityState(activity, InternalStates.LATEST_OPERATION_START_TIME, latestArrivalTime); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVariableCosts.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVariableCosts.java index 8dddca4b..9351dfda 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVariableCosts.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVariableCosts.java @@ -64,14 +64,14 @@ public class UpdateVariableCosts implements ActivityVisitor, StateUpdater { this.activityCost = activityCost; this.transportCost = transportCost; this.states = states; - timeTracker = new ActivityTimeTracker(transportCost); + timeTracker = new ActivityTimeTracker(transportCost, activityCost); } public UpdateVariableCosts(VehicleRoutingActivityCosts activityCosts, VehicleRoutingTransportCosts transportCosts, StateManager stateManager, ActivityTimeTracker.ActivityPolicy activityPolicy) { this.activityCost = activityCosts; this.transportCost = transportCosts; this.states = stateManager; - timeTracker = new ActivityTimeTracker(transportCosts, activityPolicy); + timeTracker = new ActivityTimeTracker(transportCosts, activityPolicy, activityCosts); } @Override 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 5e97668e..1390cdfb 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 @@ -18,6 +18,7 @@ package jsprit.core.algorithm.state; import jsprit.core.problem.Location; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.solution.route.RouteVisitor; import jsprit.core.problem.solution.route.VehicleRoute; @@ -59,6 +60,8 @@ public class UpdateVehicleDependentPracticalTimeWindows implements RouteVisitor, private final VehicleRoutingTransportCosts transportCosts; + private final VehicleRoutingActivityCosts activityCosts; + private VehicleRoute route; private double[] latest_arrTimes_at_prevAct; @@ -67,10 +70,11 @@ public class UpdateVehicleDependentPracticalTimeWindows implements RouteVisitor, private Collection vehicles; - public UpdateVehicleDependentPracticalTimeWindows(StateManager stateManager, VehicleRoutingTransportCosts tpCosts) { + public UpdateVehicleDependentPracticalTimeWindows(StateManager stateManager, VehicleRoutingTransportCosts tpCosts, VehicleRoutingActivityCosts activityCosts) { super(); this.stateManager = stateManager; this.transportCosts = tpCosts; + this.activityCosts = activityCosts; latest_arrTimes_at_prevAct = new double[stateManager.getMaxIndexOfVehicleTypeIdentifiers() + 1]; location_of_prevAct = new Location[stateManager.getMaxIndexOfVehicleTypeIdentifiers() + 1]; } @@ -95,7 +99,7 @@ public class UpdateVehicleDependentPracticalTimeWindows implements RouteVisitor, double latestArrTimeAtPrevAct = latest_arrTimes_at_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()]; Location prevLocation = location_of_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()]; double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocation(), prevLocation, - latestArrTimeAtPrevAct, route.getDriver(), vehicle) - activity.getOperationTime(); + latestArrTimeAtPrevAct, route.getDriver(), vehicle) - activityCosts.getActivityDuration(activity, latestArrTimeAtPrevAct, route.getDriver(), route.getVehicle()); double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct); if (latestArrivalTime < activity.getTheoreticalEarliestOperationStartTime()) { stateManager.putTypedInternalRouteState(route, vehicle, InternalStates.SWITCH_NOT_FEASIBLE, true); diff --git a/jsprit-core/src/main/java/jsprit/core/analysis/SolutionAnalyser.java b/jsprit-core/src/main/java/jsprit/core/analysis/SolutionAnalyser.java index 655e9d5b..b3e01c85 100644 --- a/jsprit-core/src/main/java/jsprit/core/analysis/SolutionAnalyser.java +++ b/jsprit-core/src/main/java/jsprit/core/analysis/SolutionAnalyser.java @@ -23,6 +23,7 @@ import jsprit.core.problem.Capacity; import jsprit.core.problem.Location; import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.cost.TransportDistance; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.solution.SolutionCostCalculator; import jsprit.core.problem.solution.VehicleRoutingProblemSolution; @@ -231,6 +232,8 @@ public class SolutionAnalyser { private StateManager stateManager; + private final VehicleRoutingActivityCosts activityCosts; + private ActivityTimeTracker.ActivityPolicy activityPolicy; private VehicleRoute route; @@ -245,13 +248,14 @@ public class SolutionAnalyser { double prevActDeparture; - private SumUpActivityTimes(StateId waiting_time_id, StateId transport_time_id, StateId service_time_id, StateId too_late_id, StateManager stateManager, ActivityTimeTracker.ActivityPolicy activityPolicy) { + private SumUpActivityTimes(StateId waiting_time_id, StateId transport_time_id, StateId service_time_id, StateId too_late_id, StateManager stateManager, ActivityTimeTracker.ActivityPolicy activityPolicy, VehicleRoutingActivityCosts activityCosts) { this.waiting_time_id = waiting_time_id; this.transport_time_id = transport_time_id; this.service_time_id = service_time_id; this.too_late_id = too_late_id; this.stateManager = stateManager; this.activityPolicy = activityPolicy; + this.activityCosts = activityCosts; } @Override @@ -280,7 +284,7 @@ public class SolutionAnalyser { sum_transport_time += transportTime; prevActDeparture = activity.getEndTime(); //service time - sum_service_time += activity.getOperationTime(); + sum_service_time += activityCosts.getActivityDuration(activity,activity.getArrTime(),route.getDriver(),route.getVehicle()); stateManager.putActivityState(activity, transport_time_id, sum_transport_time); @@ -547,7 +551,7 @@ public class SolutionAnalyser { this.stateManager.updateLoadStates(); this.stateManager.updateSkillStates(); activityPolicy = ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS; - this.stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), activityPolicy)); + this.stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), activityPolicy, vrp.getActivityCosts())); this.stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager)); waiting_time_id = stateManager.createStateId("waiting-time"); transport_time_id = stateManager.createStateId("transport-time"); @@ -561,7 +565,7 @@ public class SolutionAnalyser { last_transport_distance_id = stateManager.createStateId("last-transport-distance"); last_transport_time_id = stateManager.createStateId("last-transport-time"); - stateManager.addStateUpdater(new SumUpActivityTimes(waiting_time_id, transport_time_id, service_time_id, too_late_id, stateManager, activityPolicy)); + stateManager.addStateUpdater(new SumUpActivityTimes(waiting_time_id, transport_time_id, service_time_id, too_late_id, stateManager, activityPolicy, vrp.getActivityCosts())); stateManager.addStateUpdater(new DistanceUpdater(distance_id, stateManager, distanceCalculator)); stateManager.addStateUpdater(new BackhaulAndShipmentUpdater(backhaul_id, shipment_id, stateManager)); stateManager.addStateUpdater(new SkillUpdater(stateManager, skill_id)); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/AdditionalTransportationCosts.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/AdditionalTransportationCosts.java index 777716e3..eafb1ec6 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/constraint/AdditionalTransportationCosts.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/AdditionalTransportationCosts.java @@ -16,11 +16,11 @@ ******************************************************************************/ package jsprit.core.problem.constraint; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.misc.JobInsertionContext; import jsprit.core.problem.solution.route.activity.End; import jsprit.core.problem.solution.route.activity.TourActivity; -import jsprit.core.util.CalculationUtils; /** * Calculates additional transportation costs induced by inserting newAct. @@ -31,6 +31,8 @@ class AdditionalTransportationCosts implements SoftActivityConstraint { private VehicleRoutingTransportCosts routingCosts; + private VehicleRoutingActivityCosts activityCosts; + /** * Constructs the calculator that calculates additional transportation costs induced by inserting new activity. *

@@ -38,10 +40,12 @@ class AdditionalTransportationCosts implements SoftActivityConstraint { *

If newVehicle.isReturnToDepot == false then the additional costs of inserting act_new between act_i and end is c(act_i,act_new) [since act_new is then the new end-of-route] * * @param routingCosts + * @param activityCosts */ - public AdditionalTransportationCosts(VehicleRoutingTransportCosts routingCosts) { + public AdditionalTransportationCosts(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) { super(); this.routingCosts = routingCosts; + this.activityCosts = activityCosts; } /** @@ -56,7 +60,7 @@ class AdditionalTransportationCosts implements SoftActivityConstraint { double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct; - double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct); + double newAct_endTime = Math.max(newAct_arrTime, newAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(newAct,newAct_arrTime,iFacts.getNewDriver(),iFacts.getNewVehicle()); //open routes if (nextAct instanceof End) { diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java index 65b2212c..6f685ae3 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java @@ -98,7 +98,7 @@ public class ConstraintManager implements HardActivityConstraint, HardRouteConst public void addTimeWindowConstraint() { if (!timeWindowConstraintsSet) { - addConstraint(new VehicleDependentTimeWindowConstraints(stateManager, vrp.getTransportCosts()), Priority.HIGH); + addConstraint(new VehicleDependentTimeWindowConstraints(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts()), Priority.HIGH); timeWindowConstraintsSet = true; } } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/TimeWindowConstraint.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/TimeWindowConstraint.java deleted file mode 100644 index 6b09061d..00000000 --- a/jsprit-core/src/main/java/jsprit/core/problem/constraint/TimeWindowConstraint.java +++ /dev/null @@ -1,142 +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.problem.constraint; - -import jsprit.core.algorithm.state.InternalStates; -import jsprit.core.problem.Location; -import jsprit.core.problem.cost.VehicleRoutingTransportCosts; -import jsprit.core.problem.misc.JobInsertionContext; -import jsprit.core.problem.solution.route.activity.End; -import jsprit.core.problem.solution.route.activity.TourActivity; -import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter; -import jsprit.core.util.CalculationUtils; - - -/** - * @author stefan - */ -class TimeWindowConstraint implements HardActivityConstraint { - - private RouteAndActivityStateGetter states; - - private VehicleRoutingTransportCosts routingCosts; - - public TimeWindowConstraint(RouteAndActivityStateGetter states, VehicleRoutingTransportCosts routingCosts) { - super(); - this.states = states; - this.routingCosts = routingCosts; - } - - @Override - public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) { - double latestVehicleArrival = iFacts.getNewVehicle().getLatestArrival(); - Double latestArrTimeAtNextAct; - Location nextActLocation; - if (nextAct instanceof End) { - latestArrTimeAtNextAct = latestVehicleArrival; - nextActLocation = iFacts.getNewVehicle().getEndLocation(); - if (!iFacts.getNewVehicle().isReturnToDepot()) { - nextActLocation = newAct.getLocation(); - } - } else { - latestArrTimeAtNextAct = states.getActivityState(nextAct, InternalStates.LATEST_OPERATION_START_TIME, Double.class); - if (latestArrTimeAtNextAct == null) - latestArrTimeAtNextAct = nextAct.getTheoreticalLatestOperationStartTime(); - nextActLocation = nextAct.getLocation(); - } - - /* - * if latest arrival of vehicle (at its end) is smaller than earliest operation start times of activities, - * then vehicle can never conduct activities. - * - * |--- vehicle's operation time ---| - * |--- prevAct or newAct or nextAct ---| - */ - if (latestVehicleArrival < prevAct.getTheoreticalEarliestOperationStartTime() || - latestVehicleArrival < newAct.getTheoreticalEarliestOperationStartTime() || - latestVehicleArrival < nextAct.getTheoreticalEarliestOperationStartTime()) { - return ConstraintsStatus.NOT_FULFILLED_BREAK; - } - /* - * if the latest operation start-time of new activity is smaller than the earliest start of prev. activity, - * then - * - * |--- prevAct ---| - * |--- newAct ---| - */ - if (newAct.getTheoreticalLatestOperationStartTime() < prevAct.getTheoreticalEarliestOperationStartTime()) { - return ConstraintsStatus.NOT_FULFILLED_BREAK; - } - - /* - * |--- prevAct ---| - * |- earliest arrival of vehicle - * |--- nextAct ---| - */ - double arrTimeAtNextOnDirectRouteWithNewVehicle = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); - if (arrTimeAtNextOnDirectRouteWithNewVehicle > nextAct.getTheoreticalLatestOperationStartTime()) { - return ConstraintsStatus.NOT_FULFILLED_BREAK; - } - /* - * |--- newAct ---| - * |--- nextAct ---| - */ - if (newAct.getTheoreticalEarliestOperationStartTime() > nextAct.getTheoreticalLatestOperationStartTime()) { - return ConstraintsStatus.NOT_FULFILLED; - } - // log.info("check insertion of " + newAct + " between " + prevAct + " and " + nextAct + ". prevActDepTime=" + prevActDepTime); -// double latestArrTimeAtNextAct = states.getActivityState(nextAct, StateFactory.LATEST_OPERATION_START_TIME, Double.class); - double arrTimeAtNewAct = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); - - - double latestArrTimeAtNewAct = Math.min(newAct.getTheoreticalLatestOperationStartTime(), latestArrTimeAtNextAct - - routingCosts.getBackwardTransportTime(nextActLocation, newAct.getLocation(), latestArrTimeAtNextAct, iFacts.getNewDriver(), - iFacts.getNewVehicle()) - newAct.getOperationTime()); - /* - * |--- prevAct ---| - * |--- vehicle's arrival @newAct - * latest arrival of vehicle @newAct ---| - */ - if (arrTimeAtNewAct > latestArrTimeAtNewAct) { - return ConstraintsStatus.NOT_FULFILLED; - } - - if (nextAct instanceof End) { - if (!iFacts.getNewVehicle().isReturnToDepot()) { - return ConstraintsStatus.FULFILLED; - } - } -// log.info(newAct + " arrTime=" + arrTimeAtNewAct); - double endTimeAtNewAct = CalculationUtils.getActivityEndTime(arrTimeAtNewAct, newAct); - double arrTimeAtNextAct = endTimeAtNewAct + routingCosts.getTransportTime(newAct.getLocation(), nextAct.getLocation(), endTimeAtNewAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); - - /* - * |--- newAct ---| - * |--- vehicle's arrival @nextAct - * latest arrival of vehicle @nextAct ---| - */ - if (arrTimeAtNextAct > latestArrTimeAtNextAct) { - return ConstraintsStatus.NOT_FULFILLED; - } - -// if vehicle cannot even manage direct-route - break - if (arrTimeAtNextOnDirectRouteWithNewVehicle > latestArrTimeAtNextAct) { - return ConstraintsStatus.NOT_FULFILLED_BREAK; - } - return ConstraintsStatus.FULFILLED; - } -} 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 168288cf..e7df0839 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 @@ -19,12 +19,12 @@ package jsprit.core.problem.constraint; import jsprit.core.algorithm.state.InternalStates; import jsprit.core.problem.Location; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.misc.JobInsertionContext; import jsprit.core.problem.solution.route.activity.End; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter; -import jsprit.core.util.CalculationUtils; /** @@ -36,10 +36,13 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr private VehicleRoutingTransportCosts routingCosts; - public VehicleDependentTimeWindowConstraints(RouteAndActivityStateGetter states, VehicleRoutingTransportCosts routingCosts) { + private VehicleRoutingActivityCosts activityCosts; + + public VehicleDependentTimeWindowConstraints(RouteAndActivityStateGetter states, VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) { super(); this.states = states; this.routingCosts = routingCosts; + this.activityCosts = activityCosts; } @Override @@ -108,12 +111,12 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr } // log.info("check insertion of " + newAct + " between " + prevAct + " and " + nextAct + ". prevActDepTime=" + prevActDepTime); double arrTimeAtNewAct = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocation(), newAct.getLocation(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); - double endTimeAtNewAct = CalculationUtils.getActivityEndTime(arrTimeAtNewAct, newAct); + double endTimeAtNewAct = Math.max(arrTimeAtNewAct, newAct.getTheoreticalEarliestOperationStartTime()) + activityCosts.getActivityDuration(newAct, arrTimeAtNewAct,iFacts.getNewDriver(),iFacts.getNewVehicle()); double latestArrTimeAtNewAct = Math.min(newAct.getTheoreticalLatestOperationStartTime(), latestArrTimeAtNextAct - routingCosts.getBackwardTransportTime(newAct.getLocation(), nextActLocation, latestArrTimeAtNextAct, iFacts.getNewDriver(), iFacts.getNewVehicle()) - - newAct.getOperationTime() + - activityCosts.getActivityDuration(newAct, arrTimeAtNewAct, iFacts.getNewDriver(), iFacts.getNewVehicle()) ); /* diff --git a/jsprit-core/src/main/java/jsprit/core/problem/cost/WaitingTimeCosts.java b/jsprit-core/src/main/java/jsprit/core/problem/cost/WaitingTimeCosts.java index 183aafc5..7a59beaa 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/cost/WaitingTimeCosts.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/cost/WaitingTimeCosts.java @@ -13,7 +13,7 @@ public class WaitingTimeCosts implements VehicleRoutingActivityCosts { public double getActivityCost(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { if (vehicle != null) { double waiting = vehicle.getType().getVehicleCostParams().perWaitingTimeUnit * Math.max(0., tourAct.getTheoreticalEarliestOperationStartTime() - arrivalTime); - double servicing = vehicle.getType().getVehicleCostParams().perServiceTimeUnit * tourAct.getOperationTime(); + double servicing = vehicle.getType().getVehicleCostParams().perServiceTimeUnit * getActivityDuration(tourAct,arrivalTime,driver,vehicle); return waiting + servicing; } return 0; 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 9bf07369..0b38f6ca 100644 --- a/jsprit-core/src/main/java/jsprit/core/util/ActivityTimeTracker.java +++ b/jsprit-core/src/main/java/jsprit/core/util/ActivityTimeTracker.java @@ -17,6 +17,7 @@ package jsprit.core.util; import jsprit.core.problem.cost.ForwardTransportTime; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.activity.ActivityVisitor; import jsprit.core.problem.solution.route.activity.TourActivity; @@ -29,7 +30,9 @@ public class ActivityTimeTracker implements ActivityVisitor { } - private ForwardTransportTime transportTime; + private final ForwardTransportTime transportTime; + + private final VehicleRoutingActivityCosts activityCosts; private TourActivity prevAct = null; @@ -45,15 +48,17 @@ public class ActivityTimeTracker implements ActivityVisitor { private ActivityPolicy activityPolicy = ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS; - public ActivityTimeTracker(ForwardTransportTime transportTime) { + public ActivityTimeTracker(ForwardTransportTime transportTime, VehicleRoutingActivityCosts activityCosts) { super(); this.transportTime = transportTime; + this.activityCosts = activityCosts; } - public ActivityTimeTracker(ForwardTransportTime transportTime, ActivityPolicy activityPolicy) { + public ActivityTimeTracker(ForwardTransportTime transportTime, ActivityPolicy activityPolicy, VehicleRoutingActivityCosts activityCosts) { super(); this.transportTime = transportTime; this.activityPolicy = activityPolicy; + this.activityCosts = activityCosts; } public double getActArrTime() { @@ -88,7 +93,7 @@ public class ActivityTimeTracker implements ActivityVisitor { operationStartTime = actArrTime; } else operationStartTime = actArrTime; - double operationEndTime = operationStartTime + activity.getOperationTime(); + double operationEndTime = operationStartTime + activityCosts.getActivityDuration(activity,actArrTime,route.getDriver(),route.getVehicle()); actEndTime = operationEndTime; 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 acf281a7..df922ffd 100644 --- a/jsprit-core/src/main/java/jsprit/core/util/CalculationUtils.java +++ b/jsprit-core/src/main/java/jsprit/core/util/CalculationUtils.java @@ -19,6 +19,7 @@ package jsprit.core.util; import jsprit.core.problem.solution.route.activity.TourActivity; +@Deprecated public class CalculationUtils { diff --git a/jsprit-core/src/main/java/jsprit/core/util/RouteUtils.java b/jsprit-core/src/main/java/jsprit/core/util/RouteUtils.java deleted file mode 100644 index a7ff0e5f..00000000 --- a/jsprit-core/src/main/java/jsprit/core/util/RouteUtils.java +++ /dev/null @@ -1,111 +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.util; - -import jsprit.core.algorithm.state.UpdateActivityTimes; -import jsprit.core.problem.cost.TransportTime; -import jsprit.core.problem.driver.DriverImpl; -import jsprit.core.problem.job.Job; -import jsprit.core.problem.job.Service; -import jsprit.core.problem.solution.route.RouteActivityVisitor; -import jsprit.core.problem.solution.route.VehicleRoute; -import jsprit.core.problem.solution.route.activity.TourActivity; - -import java.util.Collection; - -@Deprecated -public class RouteUtils { - - /** - * Returns total service time, i.e. sum of service time of each job. - * - * @param routes - * @return - */ - public static double calculateServiceTime(Collection routes) { - double serviceTime = 0.; - for (VehicleRoute r : routes) { - for (Job j : r.getTourActivities().getJobs()) { - serviceTime += ((Service) j).getServiceDuration(); - } - } - return serviceTime; - } - - /** - * Returns total transport time. - * - * @param routes - * @param transportTimes - * @return - */ - public static double calculateTransportTime(Collection routes, TransportTime transportTimes) { - double tpTime = 0.; - for (VehicleRoute r : routes) { - TourActivity lastact = r.getStart(); - double lastActDepTime = r.getDepartureTime(); - for (TourActivity act : r.getActivities()) { - tpTime += transportTimes.getTransportTime(lastact.getLocation(), act.getLocation(), lastActDepTime, DriverImpl.noDriver(), r.getVehicle()); - lastact = act; - lastActDepTime = act.getEndTime(); - } - tpTime += transportTimes.getTransportTime(lastact.getLocation(), r.getEnd().getLocation(), lastActDepTime, DriverImpl.noDriver(), r.getVehicle()); - } - return tpTime; - } - - /** - * Returns total waiting time. - * - * @param routes - * @return - */ - public static double calculateWaitingTime(Collection routes) { - double waitingTime = 0.; - for (VehicleRoute r : routes) { - for (TourActivity act : r.getActivities()) { - waitingTime += Math.max(0., act.getTheoreticalEarliestOperationStartTime() - act.getArrTime()); - } - } - return waitingTime; - } - - /** - * Returns total operation time. - * - * @param routes - * @return - */ - public static double calulateOperationTime(Collection routes) { - double opTime = 0.; - for (VehicleRoute r : routes) { - opTime += r.getEnd().getArrTime() - r.getDepartureTime(); - } - return opTime; - } - - /** - * Updates activity arrival/end-times of activities in specified route. - * - * @param route - * @param transportTimes - */ - public static void updateActivityTimes(VehicleRoute route, TransportTime transportTimes) { - new RouteActivityVisitor().addActivityVisitor(new UpdateActivityTimes(transportTimes)).visit(route); - } - -} diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/ExampleActivityCostFunction.java b/jsprit-core/src/test/java/jsprit/core/algorithm/ExampleActivityCostFunction.java index 3054ed95..d72fc01c 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/ExampleActivityCostFunction.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/ExampleActivityCostFunction.java @@ -40,7 +40,7 @@ public class ExampleActivityCostFunction implements VehicleRoutingActivityCosts return 0.0; } else { //waiting + act-time - double endTime = Math.max(arrivalTime, tourAct.getTheoreticalEarliestOperationStartTime()) + tourAct.getOperationTime(); + double endTime = Math.max(arrivalTime, tourAct.getTheoreticalEarliestOperationStartTime()) + getActivityDuration(tourAct,arrivalTime,driver,vehicle); double timeAtAct = endTime - arrivalTime; double totalCost = timeAtAct * parameter_timeAtAct; @@ -57,4 +57,9 @@ public class ExampleActivityCostFunction implements VehicleRoutingActivityCosts } } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/VariableDepartureAndWaitingTime_IT.java b/jsprit-core/src/test/java/jsprit/core/algorithm/VariableDepartureAndWaitingTime_IT.java index 6d94565c..44d333f0 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/VariableDepartureAndWaitingTime_IT.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/VariableDepartureAndWaitingTime_IT.java @@ -46,6 +46,11 @@ public class VariableDepartureAndWaitingTime_IT { return vehicle.getType().getVehicleCostParams().perWaitingTimeUnit * Math.max(0, tourAct.getTheoreticalEarliestOperationStartTime() - arrivalTime); } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }; algorithmFactory = new AlgorithmFactory() { @Override diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ServiceInsertionAndLoadConstraintsTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ServiceInsertionAndLoadConstraintsTest.java index c071c26f..c54bdefa 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ServiceInsertionAndLoadConstraintsTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ServiceInsertionAndLoadConstraintsTest.java @@ -63,6 +63,11 @@ public class ServiceInsertionAndLoadConstraintsTest { return 0; } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }; HardActivityConstraint hardActivityLevelConstraint = new HardActivityConstraint() { @@ -103,7 +108,7 @@ public class ServiceInsertionAndLoadConstraintsTest { private void createInsertionCalculator(HardRouteConstraint hardRouteLevelConstraint) { ConstraintManager constraintManager = new ConstraintManager(mock(VehicleRoutingProblem.class), mock(RouteAndActivityStateGetter.class)); constraintManager.addConstraint(hardRouteLevelConstraint); - insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); + insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityCosts, activityInsertionCostsCalculator, constraintManager); } @Test @@ -137,9 +142,9 @@ public class ServiceInsertionAndLoadConstraintsTest { stateManager.informInsertionStarts(Arrays.asList(route), null); JobCalculatorSwitcher switcher = new JobCalculatorSwitcher(); - ServiceInsertionCalculator serviceInsertionCalc = new ServiceInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); + ServiceInsertionCalculator serviceInsertionCalc = new ServiceInsertionCalculator(routingCosts, activityCosts, activityInsertionCostsCalculator, constraintManager); serviceInsertionCalc.setJobActivityFactory(activityFactory); - ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); + ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityCosts, activityInsertionCostsCalculator, constraintManager); insertionCalculator.setJobActivityFactory(activityFactory); switcher.put(Pickup.class, serviceInsertionCalc); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculatorTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculatorTest.java index f972b55d..011b825b 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculatorTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculatorTest.java @@ -72,6 +72,11 @@ public class ShipmentInsertionCalculatorTest { return 0; } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }; HardRouteConstraint hardRouteLevelConstraint = new HardRouteConstraint() { @@ -102,7 +107,7 @@ public class ShipmentInsertionCalculatorTest { private void createInsertionCalculator(HardRouteConstraint hardRouteLevelConstraint) { ConstraintManager constraintManager = new ConstraintManager(mock(VehicleRoutingProblem.class), mock(RouteAndActivityStateGetter.class)); constraintManager.addConstraint(hardRouteLevelConstraint); - insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); + insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityCosts, activityInsertionCostsCalculator, constraintManager); } @Test @@ -254,8 +259,8 @@ public class ShipmentInsertionCalculatorTest { constraintManager.addConstraint(new PickupAndDeliverShipmentLoadActivityLevelConstraint(stateManager), Priority.CRITICAL); constraintManager.addConstraint(new ShipmentPickupsFirstConstraint(), Priority.CRITICAL); - ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, - constraintManager); + ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityCosts, + activityInsertionCostsCalculator, constraintManager); insertionCalculator.setJobActivityFactory(vrp.getJobActivityFactory()); InsertionData iData = insertionCalculator.getInsertionData(route, shipment3, vehicle, 0.0, DriverImpl.noDriver(), Double.MAX_VALUE); @@ -289,8 +294,8 @@ public class ShipmentInsertionCalculatorTest { stateManager.informInsertionStarts(Arrays.asList(route), null); JobCalculatorSwitcher switcher = new JobCalculatorSwitcher(); - ServiceInsertionCalculator serviceInsertionCalc = new ServiceInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); - ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); + ServiceInsertionCalculator serviceInsertionCalc = new ServiceInsertionCalculator(routingCosts, activityCosts, activityInsertionCostsCalculator, constraintManager); + ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityCosts, activityInsertionCostsCalculator, constraintManager); switcher.put(Pickup.class, serviceInsertionCalc); switcher.put(Service.class, serviceInsertionCalc); switcher.put(Shipment.class, insertionCalculator); 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..7974021f 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 @@ -130,7 +130,7 @@ public class TestCalculatesServiceInsertion { VehicleRoutingActivityCosts actCosts = mock(VehicleRoutingActivityCosts.class); - serviceInsertion = new ServiceInsertionCalculator(costs, new LocalActivityInsertionCostsCalculator(costs, actCosts, states), cManager); + serviceInsertion = new ServiceInsertionCalculator(costs, vrp.getActivityCosts(), new LocalActivityInsertionCostsCalculator(costs, actCosts, states), cManager); serviceInsertion.setJobActivityFactory(new JobActivityFactory() { @Override public List createActivities(Job job) { diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestDepartureTimeOpt.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestDepartureTimeOpt.java index 9ed591c5..e05b504f 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestDepartureTimeOpt.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestDepartureTimeOpt.java @@ -60,6 +60,11 @@ public class TestDepartureTimeOpt { return waiting + late; } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }); VehicleRoutingProblem vrp = vrpBuilder.addJob(service).addVehicle(vehicle).build(); @@ -88,6 +93,11 @@ public class TestDepartureTimeOpt { return waiting + late; } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }); VehicleRoutingProblem vrp = vrpBuilder.addJob(service).addVehicle(vehicle).build(); @@ -115,6 +125,11 @@ public class TestDepartureTimeOpt { return waiting + late; } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }); VehicleRoutingProblem vrp = vrpBuilder.addJob(service).addVehicle(vehicle).build(); @@ -143,6 +158,11 @@ public class TestDepartureTimeOpt { return waiting + late; } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }); VehicleRoutingProblem vrp = vrpBuilder.addJob(service).addVehicle(vehicle).build(); @@ -175,6 +195,11 @@ public class TestDepartureTimeOpt { return waiting + late; } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }); VehicleRoutingProblem vrp = vrpBuilder.addJob(service).addJob(service2).addVehicle(vehicle).build(); @@ -207,6 +232,11 @@ public class TestDepartureTimeOpt { return waiting + late; } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }); VehicleRoutingProblem vrp = vrpBuilder.addJob(service).addJob(service2).addVehicle(vehicle).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..2002abfd 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 @@ -82,7 +82,7 @@ public class TestLocalActivityInsertionCostsCalculator { when(tpCosts.getTransportCost(loc("k"), loc("j"), 0.0, null, vehicle)).thenReturn(3.0); when(tpCosts.getTransportTime(loc("k"), loc("j"), 0.0, null, vehicle)).thenReturn(0.0); - actCosts = mock(VehicleRoutingActivityCosts.class); + actCosts = new WaitingTimeCosts(); calc = new LocalActivityInsertionCostsCalculator(tpCosts, actCosts, mock(StateManager.class)); } @@ -502,8 +502,8 @@ public class TestLocalActivityInsertionCostsCalculator { private StateManager getStateManager(VehicleRoutingProblem vrp, VehicleRoute route) { StateManager stateManager = new StateManager(vrp); - stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts())); - stateManager.addStateUpdater(new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts())); + stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), vrp.getActivityCosts())); + stateManager.addStateUpdater(new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts(), actCosts)); stateManager.addStateUpdater(new UpdateFutureWaitingTimes(stateManager, vrp.getTransportCosts())); stateManager.informInsertionStarts(Arrays.asList(route), new ArrayList()); return stateManager; 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..b076c269 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 @@ -73,6 +73,11 @@ public class TestRouteLevelActivityInsertionCostEstimator { return Math.max(0., arrivalTime - tourAct.getTheoreticalLatestOperationStartTime()); } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }; Service s1 = Service.Builder.newInstance("s1").setLocation(Location.newInstance("10,0")).setTimeWindow(TimeWindow.newInstance(10., 10.)).build(); Service s2 = Service.Builder.newInstance("s2").setLocation(Location.newInstance("20,0")).setTimeWindow(TimeWindow.newInstance(20., 20.)).build(); 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..686f87b1 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 @@ -83,6 +83,11 @@ public class TestRouteLevelServiceInsertionCostEstimator { return Math.max(0., arrivalTime - tourAct.getTheoreticalLatestOperationStartTime()); } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }; vrpBuilder.setActivityCosts(activityCosts); 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 index 5b97b4a5..71279ffa 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdatePracticalTimeWindowTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/state/UpdatePracticalTimeWindowTest.java @@ -22,7 +22,9 @@ 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.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.cost.WaitingTimeCosts; import jsprit.core.problem.driver.Driver; import jsprit.core.problem.job.Delivery; import jsprit.core.problem.job.Job; @@ -47,6 +49,8 @@ public class UpdatePracticalTimeWindowTest { private VehicleRoutingTransportCosts routingCosts; + private VehicleRoutingActivityCosts activityCosts; + private ReverseRouteActivityVisitor reverseActivityVisitor; private StateManager stateManager; @@ -57,13 +61,14 @@ public class UpdatePracticalTimeWindowTest { public void doBefore() { routingCosts = CostFactory.createManhattanCosts(); + activityCosts = new WaitingTimeCosts(); 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)); + reverseActivityVisitor.addActivityVisitor(new UpdatePracticalTimeWindows(stateManager, routingCosts, activityCosts)); 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(); 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 9762a0d8..8f86026f 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 @@ -4,7 +4,9 @@ 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.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.cost.WaitingTimeCosts; import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Service; import jsprit.core.problem.solution.route.VehicleRoute; @@ -39,6 +41,8 @@ public class UpdateVehicleDependentTimeWindowTest { private VehicleRoutingTransportCosts routingCosts; + private VehicleRoutingActivityCosts activityCosts; + private VehicleFleetManager fleetManager; private VehicleRoutingProblem vrp; @@ -48,6 +52,7 @@ public class UpdateVehicleDependentTimeWindowTest { VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); routingCosts = CostFactory.createEuclideanCosts(); + activityCosts = new WaitingTimeCosts(); vrpBuilder.setRoutingCost(routingCosts); vehicle = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("0,0")).setEarliestStart(0.).setLatestArrival(100.).build(); @@ -84,7 +89,7 @@ public class UpdateVehicleDependentTimeWindowTest { stateManager = new StateManager(vrp); - UpdateVehicleDependentPracticalTimeWindows updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, routingCosts); + UpdateVehicleDependentPracticalTimeWindows updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, routingCosts, activityCosts); updater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() { @Override @@ -103,7 +108,7 @@ public class UpdateVehicleDependentTimeWindowTest { @Test public void whenSwitchIsNotAllowed_itShouldCalOnlyStatesOfCurrentVehicle() { stateManager = new StateManager(vrp); - UpdateVehicleDependentPracticalTimeWindows updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, routingCosts); + UpdateVehicleDependentPracticalTimeWindows updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, routingCosts, activityCosts); stateManager.addStateUpdater(updater); stateManager.informInsertionStarts(Arrays.asList(route), Collections.emptyList()); diff --git a/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java b/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java index 62cbeaa7..f5f43e2b 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java @@ -264,6 +264,11 @@ public class VehicleRoutingProblemTest { return 4.0; } + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return tourAct.getOperationTime(); + } + }); VehicleRoutingProblem problem = builder.build(); diff --git a/jsprit-core/src/test/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowTest.java b/jsprit-core/src/test/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowTest.java index a9e4a694..5d0ec149 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowTest.java @@ -22,7 +22,9 @@ import jsprit.core.algorithm.state.StateManager; import jsprit.core.algorithm.state.UpdateActivityTimes; import jsprit.core.algorithm.state.UpdateVehicleDependentPracticalTimeWindows; import jsprit.core.problem.*; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.cost.WaitingTimeCosts; import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Service; import jsprit.core.problem.misc.JobInsertionContext; @@ -52,6 +54,8 @@ public class VehicleDependentTimeWindowTest { private VehicleRoutingTransportCosts routingCosts; + private VehicleRoutingActivityCosts activityCosts; + private VehicleImpl v3; private VehicleImpl v4; private VehicleImpl v5; @@ -61,6 +65,9 @@ public class VehicleDependentTimeWindowTest { public void doBefore() { VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); routingCosts = CostFactory.createEuclideanCosts(); + + activityCosts = new WaitingTimeCosts(); + vrpBuilder.setRoutingCost(routingCosts); VehicleType type = VehicleTypeImpl.Builder.newInstance("type").build(); @@ -112,7 +119,7 @@ public class VehicleDependentTimeWindowTest { final VehicleFleetManager fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager(); - UpdateVehicleDependentPracticalTimeWindows timeWindow_updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, routingCosts); + UpdateVehicleDependentPracticalTimeWindows timeWindow_updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, routingCosts, activityCosts); timeWindow_updater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() { @Override @@ -125,7 +132,7 @@ public class VehicleDependentTimeWindowTest { }); stateManager.addStateUpdater(timeWindow_updater); - stateManager.addStateUpdater(new UpdateActivityTimes(routingCosts)); + stateManager.addStateUpdater(new UpdateActivityTimes(routingCosts, activityCosts)); stateManager.informInsertionStarts(Arrays.asList(route), Collections.emptyList()); } @@ -155,7 +162,7 @@ public class VehicleDependentTimeWindowTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, vehicle, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); assertTrue(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -170,7 +177,7 @@ public class VehicleDependentTimeWindowTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, vehicle, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -185,7 +192,7 @@ public class VehicleDependentTimeWindowTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, vehicle, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); /* driverTime = 10 + 10 + 30 + 20 + 30 = 100 */ @@ -207,7 +214,7 @@ public class VehicleDependentTimeWindowTest { driverTime = 10 + 10 + 31 + 21 + 30 = 102 */ - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(1), serviceAct, route.getActivities().get(2), 20.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -225,7 +232,7 @@ public class VehicleDependentTimeWindowTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v2, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); @@ -244,7 +251,7 @@ public class VehicleDependentTimeWindowTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v3, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -262,7 +269,7 @@ public class VehicleDependentTimeWindowTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v4, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -280,7 +287,7 @@ public class VehicleDependentTimeWindowTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v6, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(1), serviceAct, route.getActivities().get(2), 30.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -298,7 +305,7 @@ public class VehicleDependentTimeWindowTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v6, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(0), serviceAct, route.getActivities().get(1), 10.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -316,7 +323,7 @@ public class VehicleDependentTimeWindowTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v6, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); assertTrue(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -332,7 +339,7 @@ public class VehicleDependentTimeWindowTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v5, route.getDriver(), 60.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 90.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); diff --git a/jsprit-core/src/test/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest.java b/jsprit-core/src/test/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest.java index 652e55f4..cc2567cc 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/constraint/VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest.java @@ -22,7 +22,9 @@ import jsprit.core.algorithm.state.StateManager; import jsprit.core.algorithm.state.UpdateActivityTimes; import jsprit.core.algorithm.state.UpdateVehicleDependentPracticalTimeWindows; import jsprit.core.problem.*; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.cost.WaitingTimeCosts; import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Service; import jsprit.core.problem.misc.JobInsertionContext; @@ -52,6 +54,8 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { private VehicleRoutingTransportCosts routingCosts; + private VehicleRoutingActivityCosts activityCosts; + private VehicleImpl v3; private VehicleImpl v4; private VehicleImpl v5; @@ -61,6 +65,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { public void doBefore() { VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); routingCosts = CostFactory.createEuclideanCosts(); + activityCosts = new WaitingTimeCosts(); vrpBuilder.setRoutingCost(routingCosts); VehicleType type = VehicleTypeImpl.Builder.newInstance("type").build(); @@ -112,7 +117,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { final VehicleFleetManager fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager(); // stateManager.updateTimeWindowStates(); - UpdateVehicleDependentPracticalTimeWindows timeWindow_updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, routingCosts); + UpdateVehicleDependentPracticalTimeWindows timeWindow_updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, routingCosts, activityCosts); timeWindow_updater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() { @Override @@ -125,7 +130,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { }); stateManager.addStateUpdater(timeWindow_updater); - stateManager.addStateUpdater(new UpdateActivityTimes(routingCosts)); + stateManager.addStateUpdater(new UpdateActivityTimes(routingCosts,activityCosts)); stateManager.informInsertionStarts(Arrays.asList(route), Collections.emptyList()); } @@ -155,7 +160,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, vehicle, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); assertTrue(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -170,7 +175,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, vehicle, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -185,7 +190,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, vehicle, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); /* driverTime = 10 + 10 + 30 + 20 + 30 = 100 */ @@ -207,7 +212,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { driverTime = 10 + 10 + 31 + 21 + 30 = 102 */ - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(1), serviceAct, route.getActivities().get(2), 20.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -225,7 +230,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v2, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); @@ -244,7 +249,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v3, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -262,7 +267,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v4, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -280,7 +285,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v6, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(1), serviceAct, route.getActivities().get(2), 30.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -298,7 +303,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v6, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(0), serviceAct, route.getActivities().get(1), 10.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -316,7 +321,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v6, route.getDriver(), 0.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 30.); assertTrue(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); @@ -332,7 +337,7 @@ public class VehicleDependentTimeWindowWithStartTimeAndMaxOperationTimeTest { JobInsertionContext insertionContext = new JobInsertionContext(route, s4, v5, route.getDriver(), 60.); - HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts); + HardActivityConstraint twConstraint = new VehicleDependentTimeWindowConstraints(stateManager, routingCosts, activityCosts); HardActivityConstraint.ConstraintsStatus status = twConstraint.fulfilled(insertionContext, route.getActivities().get(2), serviceAct, route.getEnd(), 90.); assertFalse(status.equals(HardActivityConstraint.ConstraintsStatus.FULFILLED)); diff --git a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml index 07c5406a..2d9058ab 100644 --- a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml +++ b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml @@ -2,24 +2,9 @@ - FINITE + INFINITE - - v2 - vehType2 - - loc - - - loc - - - 0.0 - 1.7976931348623157E308 - - true - v1 vehType @@ -48,16 +33,58 @@ - - 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/MultipleDepotExample.java b/jsprit-examples/src/main/java/jsprit/examples/MultipleDepotExample.java index 88cffa3c..b61abb74 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/MultipleDepotExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/MultipleDepotExample.java @@ -105,7 +105,7 @@ public class MultipleDepotExample { SolutionPrinter.print(Solutions.bestOf(solutions)); - new Plotter(vrp, Solutions.bestOf(solutions)).plot("output/p01_solution.png", "p01"); + new Plotter(vrp, Solutions.bestOf(solutions)).setLabel(Plotter.Label.ID).plot("output/p01_solution.png", "p01"); new GraphStreamViewer(vrp, Solutions.bestOf(solutions)).setRenderDelay(100).display(); From 4f921d053c012f5814ed085115c7a09a29530660 Mon Sep 17 00:00:00 2001 From: oblonski Date: Thu, 7 Jan 2016 07:35:23 +0100 Subject: [PATCH 3/3] add example --- ...vicePickupsWithMultipleDepots2Example.java | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 jsprit-examples/src/main/java/jsprit/examples/ServicePickupsWithMultipleDepots2Example.java diff --git a/jsprit-examples/src/main/java/jsprit/examples/ServicePickupsWithMultipleDepots2Example.java b/jsprit-examples/src/main/java/jsprit/examples/ServicePickupsWithMultipleDepots2Example.java new file mode 100644 index 00000000..2d341394 --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/ServicePickupsWithMultipleDepots2Example.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * 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.problem.Location; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; +import jsprit.core.problem.driver.Driver; +import jsprit.core.problem.job.Service; +import jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.vehicle.Vehicle; +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.Solutions; +import jsprit.util.Examples; + +import java.util.Collection; + + +public class ServicePickupsWithMultipleDepots2Example { + + public static void main(String[] args) { + /* + * some preparation - create output folder + */ + Examples.createOutputFolder(); + + /* + * get a vehicle type-builder and build a type with the typeId "vehicleType" and a capacity of 2 + */ + VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType1").addCapacityDimension(0, 8); + vehicleTypeBuilder.setCostPerDistance(1.0); + VehicleType vehicleType = vehicleTypeBuilder.build(); + + VehicleTypeImpl.Builder vehicleTypeBuilder2 = VehicleTypeImpl.Builder.newInstance("vehicleType2").addCapacityDimension(0, 8); + vehicleTypeBuilder2.setCostPerDistance(1.0); + VehicleType vehicleType2 = vehicleTypeBuilder2.build(); + + /* + * define two depots, i.e. two vehicle locations ([10,10],[50,50]) and equip them with an infinite number of vehicles of type 'vehicleType' + */ + Builder vehicleBuilder1 = Builder.newInstance("vehicles@[10,10]"); + vehicleBuilder1.setStartLocation(Location.newInstance(10, 10)); + vehicleBuilder1.setType(vehicleType); + VehicleImpl vehicle1 = vehicleBuilder1.build(); + + Builder vehicleBuilder2 = Builder.newInstance("vehicles@[50,50]"); + vehicleBuilder2.setStartLocation(Location.newInstance(50, 50)); + vehicleBuilder2.setType(vehicleType2); + VehicleImpl vehicle2 = vehicleBuilder2.build(); + + + /* + * build shipments at the required locations, each with a capacity-demand of 1. + * 4 shipments + * 1: (5,7)->(6,9) + * 2: (5,13)->(6,11) + * 3: (15,7)->(14,9) + * 4: (15,13)->(14,11) + */ + + Service shipment1 = Service.Builder.newInstance("1") + .setServiceTime(20.).addSizeDimension(0, 1).setLocation(Location.newInstance(5, 7)).build(); + Service shipment2 = Service.Builder.newInstance("2") + .setServiceTime(20.).addSizeDimension(0, 1).setLocation(Location.newInstance(5, 13)).build(); + + Service shipment3 = Service.Builder.newInstance("3") + .setServiceTime(20).addSizeDimension(0, 1).setLocation(Location.newInstance(15, 7)).build(); + Service shipment4 = Service.Builder.newInstance("4") + .setServiceTime(20.).addSizeDimension(0, 1).setLocation(Location.newInstance(15, 13)).build(); + + Service shipment5 = Service.Builder.newInstance("5") + .setServiceTime(20).addSizeDimension(0, 1).setLocation(Location.newInstance(55, 57)).build(); + Service shipment6 = Service.Builder.newInstance("6") + .setServiceTime(20).addSizeDimension(0, 1).setLocation(Location.newInstance(55, 63)).build(); + + Service shipment7 = Service.Builder.newInstance("7") + .setServiceTime(20).addSizeDimension(0, 1).setLocation(Location.newInstance(65, 57)).build(); + Service shipment8 = Service.Builder.newInstance("8") + .setServiceTime(20).addSizeDimension(0, 1).setLocation(Location.newInstance(65, 63)).build(); + + + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addVehicle(vehicle1).addVehicle(vehicle2); + vrpBuilder.addJob(shipment1).addJob(shipment2).addJob(shipment3).addJob(shipment4); + vrpBuilder.addJob(shipment5).addJob(shipment6).addJob(shipment7).addJob(shipment8); + + vrpBuilder.setActivityCosts(new VehicleRoutingActivityCosts() { + + @Override + public double getActivityCost(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + return 0; + } + + @Override + public double getActivityDuration(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) { + if(vehicle.getType().getTypeId().equals("vehicleType1")){ + return tourAct.getOperationTime(); + } + else return tourAct.getOperationTime() / 10.; + } + + }); +// vrpBuilder.setFleetSize(FleetSize.FINITE); + VehicleRoutingProblem problem = vrpBuilder.build(); + + /* + * get the algorithm out-of-the-box. + */ + VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(problem); + algorithm.setMaxIterations(100); + + /* + * and search a solution + */ + Collection solutions = algorithm.searchSolutions(); + + /* + * get the best + */ + VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions); + + /* + * print nRoutes and totalCosts of bestSolution + */ + SolutionPrinter.print(problem,bestSolution, SolutionPrinter.Print.VERBOSE); + + /* + * plot problem with solution + */ + Plotter solutionPlotter = new Plotter(problem, bestSolution); + solutionPlotter.plot("output/plot.png", "vehicle dependent service time"); + + + } + +}