From e12136393ac7de594e67102999e7b5c7fa4efc4a Mon Sep 17 00:00:00 2001 From: oblonski Date: Thu, 15 Oct 2015 17:02:19 +0200 Subject: [PATCH] speed up regret insertion --- .../jsprit/core/algorithm/box/Jsprit.java | 9 +-- .../algorithm/recreate/InsertionBuilder.java | 5 +- .../recreate/InsertionDataUpdater.java | 4 +- .../algorithm/recreate/RegretInsertion.java | 17 ++-- .../recreate/RegretInsertionConcurrent.java | 43 ++++++---- .../recreate/RegretInsertionTest.java | 12 +-- .../test/resources/infiniteWriterV2Test.xml | 81 +++++++------------ .../examples/BuildAlgorithmFromScratch.java | 2 +- 8 files changed, 75 insertions(+), 98 deletions(-) diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/box/Jsprit.java b/jsprit-core/src/main/java/jsprit/core/algorithm/box/Jsprit.java index 4287e723..037e7b38 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/box/Jsprit.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/box/Jsprit.java @@ -404,7 +404,7 @@ public class Jsprit { ); AbstractInsertionStrategy regret; - final RegretInsertion.DefaultScorer scorer; + final DefaultScorer scorer; if (es != null) { RegretInsertionConcurrent regretInsertion = (RegretInsertionConcurrent) new InsertionBuilder(vrp, fm, stateManager, constraintManager) @@ -424,7 +424,6 @@ public class Jsprit { .considerFixedCosts(toDouble(getProperty(Parameter.FIXED_COST_PARAM.toString()))) .setActivityInsertionCostCalculator(activityInsertion) .build(); - regretInsertion.setFleetManager(fm); scorer = getRegretScorer(vrp); regretInsertion.setScoringFunction(scorer); regret = regretInsertion; @@ -522,9 +521,9 @@ public class Jsprit { } - private RegretInsertion.DefaultScorer getRegretScorer(VehicleRoutingProblem vrp) { - RegretInsertion.DefaultScorer scorer; - scorer = new RegretInsertion.DefaultScorer(vrp); + private DefaultScorer getRegretScorer(VehicleRoutingProblem vrp) { + DefaultScorer scorer; + scorer = new DefaultScorer(vrp); scorer.setTimeWindowParam(Double.valueOf(properties.getProperty(Parameter.REGRET_TIME_WINDOW_SCORER.toString()))); scorer.setDepotDistanceParam(Double.valueOf(properties.getProperty(Parameter.REGRET_DISTANCE_SCORER.toString()))); return scorer; diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionBuilder.java index db23af02..c1660260 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionBuilder.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionBuilder.java @@ -166,12 +166,11 @@ public class InsertionBuilder { } } else if (strategy.equals(Strategy.REGRET)) { if (executor == null) { - RegretInsertion regret = new RegretInsertion(costCalculator, vrp); - regret.setFleetManager(fleetManager); + RegretInsertion regret = new RegretInsertion(costCalculator, vrp, fleetManager); insertion = regret; } else { - insertion = new RegretInsertionConcurrent(costCalculator, vrp, executor); + insertion = new RegretInsertionConcurrent(costCalculator, vrp, executor, fleetManager); } } else throw new IllegalStateException("you should never get here"); for (InsertionListener l : iListeners) insertion.addListener(l); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionDataUpdater.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionDataUpdater.java index 09bf21e0..ffc63cdf 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionDataUpdater.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/InsertionDataUpdater.java @@ -13,7 +13,7 @@ import java.util.*; */ class InsertionDataUpdater { - static void update(VehicleFleetManager fleetManager, JobInsertionCostsCalculator insertionCostsCalculator, TreeSet insertionDataSet, int updateRound, Map updates, Job unassignedJob, Collection routes) { + static boolean update(VehicleFleetManager fleetManager, JobInsertionCostsCalculator insertionCostsCalculator, TreeSet insertionDataSet, int updateRound, Job unassignedJob, Collection routes) { for(VehicleRoute route : routes) { Collection relevantVehicles = new ArrayList(); if (!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) { @@ -28,8 +28,8 @@ class InsertionDataUpdater { } insertionDataSet.add(new VersionedInsertionData(iData, updateRound, route)); } - updates.put(route, updateRound); } + return true; } static VehicleRoute findRoute(Collection routes, Job job) { diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertion.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertion.java index 1c7ffe16..48771a41 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertion.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertion.java @@ -47,10 +47,6 @@ public class RegretInsertion extends AbstractInsertionStrategy { private VehicleFleetManager fleetManager; - public void setFleetManager(VehicleFleetManager fleetManager) { - this.fleetManager = fleetManager; - } - /** * Sets the scoring function. *

@@ -62,10 +58,11 @@ public class RegretInsertion extends AbstractInsertionStrategy { this.scoringFunction = scoringFunction; } - public RegretInsertion(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem) { + public RegretInsertion(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem, VehicleFleetManager fleetManager) { super(vehicleRoutingProblem); this.scoringFunction = new DefaultScorer(vehicleRoutingProblem); this.insertionCostsCalculator = jobInsertionCalculator; + this.fleetManager = fleetManager; this.vrp = vehicleRoutingProblem; logger.debug("initialise {}", this); } @@ -117,10 +114,12 @@ public class RegretInsertion extends AbstractInsertionStrategy { if(!firstRun && lastModified == null) throw new IllegalStateException("fooo"); if(firstRun){ firstRun = false; - updateInsertionData(priorityQueues, routes, unassignedJobList, badJobList, updateRound, updates); + updateInsertionData(priorityQueues, routes, unassignedJobList, updateRound); + for(VehicleRoute r : routes) updates.put(r,updateRound); } else{ - updateInsertionData(priorityQueues, Arrays.asList(lastModified), unassignedJobList, badJobList, updateRound, updates); + updateInsertionData(priorityQueues, Arrays.asList(lastModified), unassignedJobList, updateRound); + updates.put(lastModified,updateRound); } updateRound++; ScoredJob bestScoredJob = InsertionDataUpdater.getBest(fleetManager,insertionCostsCalculator,scoringFunction,priorityQueues,updates,unassignedJobList,badJobList); @@ -141,12 +140,12 @@ public class RegretInsertion extends AbstractInsertionStrategy { return badJobs; } - private void updateInsertionData(TreeSet[] priorityQueues, Collection routes, List unassignedJobList, List badJobList, int updateRound, Map updates) { + private void updateInsertionData(TreeSet[] priorityQueues, Collection routes, List unassignedJobList, int updateRound) { for (Job unassignedJob : unassignedJobList) { if(priorityQueues[unassignedJob.getIndex()] == null){ priorityQueues[unassignedJob.getIndex()] = new TreeSet(InsertionDataUpdater.getComparator()); } - InsertionDataUpdater.update(fleetManager,insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, updates, unassignedJob, routes); + InsertionDataUpdater.update(fleetManager,insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, routes); } } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertionConcurrent.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertionConcurrent.java index b972d1af..9bc33503 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertionConcurrent.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertionConcurrent.java @@ -26,8 +26,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.util.*; -import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; /** * Insertion based on regret approach. @@ -48,15 +49,10 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy { private final JobInsertionCostsCalculator insertionCostsCalculator; - private final ExecutorCompletionService completionService; + private final ExecutorService executor; private VehicleFleetManager fleetManager; - - public void setFleetManager(VehicleFleetManager fleetManager) { - this.fleetManager = fleetManager; - } - /** * Sets the scoring function. *

@@ -68,12 +64,13 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy { this.scoringFunction = scoringFunction; } - public RegretInsertionConcurrent(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem, ExecutorService executorService) { + public RegretInsertionConcurrent(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem, ExecutorService executorService, VehicleFleetManager fleetManager) { super(vehicleRoutingProblem); this.scoringFunction = new DefaultScorer(vehicleRoutingProblem); this.insertionCostsCalculator = jobInsertionCalculator; this.vrp = vehicleRoutingProblem; - completionService = new ExecutorCompletionService(executorService); + this.executor = executorService; + this.fleetManager = fleetManager; logger.debug("initialise " + this); } @@ -123,13 +120,15 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy { while (!jobs.isEmpty()) { List unassignedJobList = new ArrayList(jobs); List badJobList = new ArrayList(); - if(!firstRun && lastModified == null) throw new IllegalStateException("fooo"); + if(!firstRun && lastModified == null) throw new IllegalStateException("ho. this must not be."); if(firstRun){ firstRun = false; - updateInsertionData(priorityQueues, routes, unassignedJobList, badJobList, updateRound, updates); + updateInsertionData(priorityQueues, routes, unassignedJobList, updateRound); + for(VehicleRoute r : routes) updates.put(r,updateRound); } else{ - updateInsertionData(priorityQueues, Arrays.asList(lastModified), unassignedJobList, badJobList, updateRound, updates); + updateInsertionData(priorityQueues, Arrays.asList(lastModified), unassignedJobList, updateRound); + updates.put(lastModified,updateRound); } updateRound++; ScoredJob bestScoredJob = InsertionDataUpdater.getBest(fleetManager, insertionCostsCalculator, scoringFunction, priorityQueues, updates, unassignedJobList, badJobList); @@ -150,13 +149,25 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy { return badJobs; } - private void updateInsertionData(TreeSet[] priorityQueues, Collection routes, List unassignedJobList, List badJobList, int updateRound, Map updates) { - for (Job unassignedJob : unassignedJobList) { + private void updateInsertionData(final TreeSet[] priorityQueues, final Collection routes, List unassignedJobList, final int updateRound) { + List> tasks = new ArrayList>(); + for (final Job unassignedJob : unassignedJobList) { if(priorityQueues[unassignedJob.getIndex()] == null){ priorityQueues[unassignedJob.getIndex()] = new TreeSet(InsertionDataUpdater.getComparator()); } -// completionService.submit(ne) - InsertionDataUpdater.update(fleetManager,insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, updates, unassignedJob, routes); + final TreeSet priorityQueue = priorityQueues[unassignedJob.getIndex()]; + tasks.add(new Callable() { + @Override + public Boolean call() throws Exception { + return InsertionDataUpdater.update(fleetManager, insertionCostsCalculator, priorityQueue, updateRound, unassignedJob, routes); + } + }); + } + try { + List> futures = executor.invokeAll(tasks); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); } } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java index cf2c8bce..08677edb 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java @@ -49,8 +49,7 @@ public class RegretInsertionTest { VehicleFleetManager fm = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager(); JobInsertionCostsCalculator calculator = getCalculator(vrp); - RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp); - regretInsertion.setFleetManager(fm); + RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp, fm); Collection routes = new ArrayList(); regretInsertion.insertJobs(routes, vrp.getJobs().values()); @@ -67,8 +66,7 @@ public class RegretInsertionTest { VehicleFleetManager fm = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager(); JobInsertionCostsCalculator calculator = getCalculator(vrp); - RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp); - regretInsertion.setFleetManager(fm); + RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp, fm); Collection routes = new ArrayList(); regretInsertion.insertJobs(routes, vrp.getJobs().values()); @@ -85,8 +83,7 @@ public class RegretInsertionTest { VehicleFleetManager fm = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager(); JobInsertionCostsCalculator calculator = getCalculator(vrp); - RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp); - regretInsertion.setFleetManager(fm); + RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp, fm); Collection routes = new ArrayList(); CkeckJobSequence position = new CkeckJobSequence(2, s1); @@ -112,8 +109,7 @@ public class RegretInsertionTest { VehicleFleetManager fm = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager(); JobInsertionCostsCalculator calculator = getShipmentCalculator(vrp); - RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp); - regretInsertion.setFleetManager(fm); + RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp, fm); Collection routes = new ArrayList(); CkeckJobSequence position = new CkeckJobSequence(2, s2); diff --git a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml index 2d9058ab..07c5406a 100644 --- a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml +++ b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml @@ -2,9 +2,24 @@ - INFINITE + FINITE + + v2 + vehType2 + + loc + + + loc + + + 0.0 + 1.7976931348623157E308 + + true + v1 vehType @@ -33,58 +48,16 @@ + + vehType2 + + 200 + + + 0.0 + 1.0 + + + - - - - loc - - - 1 - - 2.0 - - - 0.0 - 1.7976931348623157E308 - - - - - - loc2 - - - 1 - - 4.0 - - - 0.0 - 1.7976931348623157E308 - - - - - - - 10.0 - - - noDriver - v1 - 0.0 - - 1 - 0.0 - 0.0 - - 0.0 - - - - - - - diff --git a/jsprit-examples/src/main/java/jsprit/examples/BuildAlgorithmFromScratch.java b/jsprit-examples/src/main/java/jsprit/examples/BuildAlgorithmFromScratch.java index e791447a..b594e5a6 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/BuildAlgorithmFromScratch.java +++ b/jsprit-examples/src/main/java/jsprit/examples/BuildAlgorithmFromScratch.java @@ -144,7 +144,7 @@ public class BuildAlgorithmFromScratch { InsertionBuilder iBuilder = new InsertionBuilder(vrp, fleetManager, stateManager, constraintManager); iBuilder.setInsertionStrategy(InsertionBuilder.Strategy.REGRET); RegretInsertion regret = (RegretInsertion) iBuilder.build(); - RegretInsertion.DefaultScorer scoringFunction = new RegretInsertion.DefaultScorer(vrp); + DefaultScorer scoringFunction = new DefaultScorer(vrp); scoringFunction.setDepotDistanceParam(0.2); scoringFunction.setTimeWindowParam(-.2); regret.setScoringFunction(scoringFunction);