From 3bf9c288ca2c6d5173af722e80ac113c20eec1c5 Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Fri, 23 Aug 2013 15:05:30 +0200 Subject: [PATCH] internal experiments with insertionCalc --- .../src/main/java/algorithms/CalcUtils.java | 14 ++++++++++++++ .../algorithms/CalculatesServiceInsertion.java | 16 +++++++++++----- .../main/java/algorithms/CalculatorBuilder.java | 2 +- .../main/java/algorithms/MarginalsCalculus.java | 2 +- .../MarginalsCalculusTriangleInequality.java | 17 +++++++++-------- .../BuildCVRPAlgoFromScratchTest.java | 6 +++--- .../java/algorithms/GendreauPostOptTest.java | 2 +- .../TestCalculatesServiceInsertion.java | 2 +- 8 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 jsprit-core/src/main/java/algorithms/CalcUtils.java diff --git a/jsprit-core/src/main/java/algorithms/CalcUtils.java b/jsprit-core/src/main/java/algorithms/CalcUtils.java new file mode 100644 index 00000000..c295881f --- /dev/null +++ b/jsprit-core/src/main/java/algorithms/CalcUtils.java @@ -0,0 +1,14 @@ +package algorithms; + +import basics.route.TourActivity; + +class CalcUtils { + + static double getStartTimeAtAct(double startTimeAtPrevAct, double tpTime_prevAct_nextAct, TourActivity nextAct){ + return Math.max(startTimeAtPrevAct + tpTime_prevAct_nextAct, nextAct.getTheoreticalEarliestOperationStartTime()) + nextAct.getOperationTime(); + } + + static double getStartTimeAtAct(double nextActArrTime, TourActivity nextAct){ + return Math.max(nextActArrTime, nextAct.getTheoreticalEarliestOperationStartTime()) + nextAct.getOperationTime(); + } +} diff --git a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertion.java b/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertion.java index b8f5f923..8583a008 100644 --- a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertion.java +++ b/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertion.java @@ -18,6 +18,7 @@ import util.Neighborhood; import algorithms.HardConstraints.HardRouteLevelConstraint; import basics.Job; import basics.Service; +import basics.costs.VehicleRoutingTransportCosts; import basics.route.Driver; import basics.route.End; import basics.route.ServiceActivity; @@ -45,15 +46,18 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{ private MarginalsCalculus marginalCalculus; + private VehicleRoutingTransportCosts transportCosts; + public void setNeighborhood(Neighborhood neighborhood) { this.neighborhood = neighborhood; logger.info("initialise neighborhood " + neighborhood); } - public CalculatesServiceInsertion(MarginalsCalculus marginalsCalculus, HardRouteLevelConstraint hardRouteLevelConstraint) { + public CalculatesServiceInsertion(VehicleRoutingTransportCosts routingCosts, MarginalsCalculus marginalsCalculus, HardRouteLevelConstraint hardRouteLevelConstraint) { super(); this.marginalCalculus = marginalsCalculus; this.hardRouteLevelConstraint = hardRouteLevelConstraint; + this.transportCosts = routingCosts; logger.info("initialise " + this); } @@ -89,6 +93,7 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{ End end = End.newInstance(newVehicle.getLocationId(), 0.0, newVehicle.getLatestArrival()); TourActivity prevAct = start; + double prevActStartTime = newVehicleDepartureTime; int actIndex = 0; for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){ @@ -96,7 +101,7 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{ break; } if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){ - Marginals mc = calculate(iFacts, prevAct, nextAct, deliveryAct2Insert); + Marginals mc = calculate(iFacts, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); if(mc != null){ if(mc.getAdditionalCosts() < bestCost){ bestCost = mc.getAdditionalCosts(); @@ -106,11 +111,12 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{ } } prevAct = nextAct; + prevActStartTime = CalcUtils.getStartTimeAtAct(prevActStartTime, transportCosts.getTransportTime(prevAct.getLocationId(), nextAct.getLocationId(), prevActStartTime, newDriver, newVehicle), nextAct); actIndex++; } End nextAct = end; if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){ - Marginals mc = calculate(iFacts, prevAct, nextAct, deliveryAct2Insert); + Marginals mc = calculate(iFacts, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); if(mc != null) { if(mc.getAdditionalCosts() < bestCost){ bestCost = mc.getAdditionalCosts(); @@ -129,8 +135,8 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{ return insertionData; } - public Marginals calculate(InsertionFacts iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct) { - return marginalCalculus.calculate(iFacts, prevAct, nextAct, newAct); + public Marginals calculate(InsertionFacts iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double departureTimeAtPrevAct) { + return marginalCalculus.calculate(iFacts, prevAct, nextAct, newAct, departureTimeAtPrevAct); } } diff --git a/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java b/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java index 1caee42d..6ab8e4c0 100644 --- a/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java +++ b/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java @@ -215,7 +215,7 @@ class CalculatorBuilder { private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager activityStates2){ MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), new HardConstraints.HardTimeWindowConstraint(activityStates2) ); - JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(defaultCalc, new HardConstraints.HardLoadConstraint(activityStates2)); + JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, new HardConstraints.HardLoadConstraint(activityStates2)); ((CalculatesServiceInsertion) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood()); CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion); diff --git a/jsprit-core/src/main/java/algorithms/MarginalsCalculus.java b/jsprit-core/src/main/java/algorithms/MarginalsCalculus.java index b5728fb7..26cf1635 100644 --- a/jsprit-core/src/main/java/algorithms/MarginalsCalculus.java +++ b/jsprit-core/src/main/java/algorithms/MarginalsCalculus.java @@ -4,6 +4,6 @@ import basics.route.TourActivity; interface MarginalsCalculus { - Marginals calculate(InsertionFacts iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct); + Marginals calculate(InsertionFacts iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct); } diff --git a/jsprit-core/src/main/java/algorithms/MarginalsCalculusTriangleInequality.java b/jsprit-core/src/main/java/algorithms/MarginalsCalculusTriangleInequality.java index 6332bd6e..3eb7a05a 100644 --- a/jsprit-core/src/main/java/algorithms/MarginalsCalculusTriangleInequality.java +++ b/jsprit-core/src/main/java/algorithms/MarginalsCalculusTriangleInequality.java @@ -20,19 +20,17 @@ class MarginalsCalculusTriangleInequality implements MarginalsCalculus{ } @Override - public Marginals calculate(InsertionFacts iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct) { - double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocationId(), newAct.getLocationId(), prevAct.getEndTime(), iFacts.getNewDriver(), iFacts.getNewVehicle()); - double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevAct.getEndTime(), iFacts.getNewDriver(), iFacts.getNewVehicle()); + public Marginals calculate(InsertionFacts iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) { + double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); + double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); - double newAct_arrTime = prevAct.getEndTime() + tp_time_prevAct_newAct; + double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct; if(!hardConstraint.fulfilled(iFacts, newAct, newAct_arrTime)){ return null; } - double newAct_operationStartTime = Math.max(newAct_arrTime, newAct.getTheoreticalEarliestOperationStartTime()); - - double newAct_endTime = newAct_operationStartTime + newAct.getOperationTime(); + double newAct_endTime = CalcUtils.getStartTimeAtAct(newAct_arrTime, newAct); double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); @@ -50,8 +48,10 @@ class MarginalsCalculusTriangleInequality implements MarginalsCalculus{ double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct + act_costs_newAct + act_costs_nextAct; double oldCosts; + double oldTime; if(iFacts.getRoute().isEmpty()){ oldCosts = 0.0; + oldTime = 0.0; } else{ double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocationId(), nextAct.getLocationId(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle()); @@ -59,10 +59,11 @@ class MarginalsCalculusTriangleInequality implements MarginalsCalculus{ double actCost_nextAct = activityCosts.getActivityCost(nextAct, arrTime_nextAct, iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle()); oldCosts = tp_costs_prevAct_nextAct + actCost_nextAct; + oldTime = (nextAct.getArrTime() - iFacts.getRoute().getDepartureTime()); } double additionalCosts = totalCosts - oldCosts; - double additionalTime = nextAct_arrTime - nextAct.getArrTime(); + double additionalTime = (nextAct_arrTime - iFacts.getNewDepTime()) - oldTime; return new Marginals(additionalCosts,additionalTime); } diff --git a/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java b/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java index 83d1c220..f3791e4d 100644 --- a/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java +++ b/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java @@ -41,7 +41,7 @@ public class BuildCVRPAlgoFromScratchTest { } }; MarginalsCalculus marginalCalculus = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), hardActLevelConstraint); - CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager)); + CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager)); VehicleFleetManager fleetManager = new InfiniteVehicles(vrp.getVehicles()); JobInsertionCalculator finalServiceInsertion = new CalculatesVehTypeDepServiceInsertion(fleetManager, serviceInsertion); @@ -83,7 +83,7 @@ public class BuildCVRPAlgoFromScratchTest { // System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size()); vra.addInitialSolution(iniSolution); - vra.setNuOfIterations(10000); + vra.setNuOfIterations(2000); // vra.setPrematureBreak(200); } @@ -91,7 +91,7 @@ public class BuildCVRPAlgoFromScratchTest { @Test public void testVRA(){ Collection solutions = vra.searchSolutions(); -// System.out.println("costs="+Solutions.getBest(solutions).getCost()+";#routes="+Solutions.getBest(solutions).getRoutes().size()); + System.out.println("costs="+Solutions.getBest(solutions).getCost()+";#routes="+Solutions.getBest(solutions).getRoutes().size()); assertEquals(530.0, Solutions.getBest(solutions).getCost(),15.0); assertEquals(5, Solutions.getBest(solutions).getRoutes().size()); } diff --git a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java index 305451e8..27f75beb 100644 --- a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java +++ b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java @@ -151,7 +151,7 @@ public class GendreauPostOptTest { activityCosts = new ExampleActivityCostFunction(); - CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(new MarginalsCalculusTriangleInequality(cost, activityCosts, new HardConstraints.HardTimeWindowConstraint(states)), new HardConstraints.HardLoadConstraint(states)); + CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, new MarginalsCalculusTriangleInequality(cost, activityCosts, new HardConstraints.HardTimeWindowConstraint(states)), new HardConstraints.HardLoadConstraint(states)); CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(standardServiceInsertion, states); withFixCost.setWeightOfFixCost(1.2); diff --git a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java index 69d92379..459ae877 100644 --- a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java +++ b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java @@ -156,7 +156,7 @@ public class TestCalculatesServiceInsertion { ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction(); - serviceInsertion = new CalculatesServiceInsertion(new MarginalsCalculusTriangleInequality(costs, activityCosts, new HardConstraints.HardTimeWindowConstraint(states)), new HardConstraints.HardLoadConstraint(states)); + serviceInsertion = new CalculatesServiceInsertion(costs, new MarginalsCalculusTriangleInequality(costs, activityCosts, new HardConstraints.HardTimeWindowConstraint(states)), new HardConstraints.HardLoadConstraint(states)); stateUpdater = new UpdateStates(states, costs, activityCosts);