From 07944d6dd6f31cea7fc7b4a99ed6e60a542e24da Mon Sep 17 00:00:00 2001 From: kandelirina Date: Thu, 25 Oct 2018 13:38:46 +0300 Subject: [PATCH] With random insertion in jsprit (#66) * with random insertion in jsprit * just random * oops * add to defaults * select randomly in random * test added --- .../algorithm/PrettyAlgorithmBuilder.java | 13 ++-- .../jsprit/core/algorithm/box/Jsprit.java | 39 +++++++++-- .../jsprit/core/algorithm/box/JspritTest.java | 64 +++++++++++++++++++ 3 files changed, 103 insertions(+), 13 deletions(-) diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/PrettyAlgorithmBuilder.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/PrettyAlgorithmBuilder.java index 7d6c4e17..b8b03985 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/PrettyAlgorithmBuilder.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/PrettyAlgorithmBuilder.java @@ -23,19 +23,15 @@ import com.graphhopper.jsprit.core.algorithm.acceptor.SolutionAcceptor; import com.graphhopper.jsprit.core.algorithm.listener.AlgorithmStartsListener; import com.graphhopper.jsprit.core.algorithm.recreate.InsertionStrategy; import com.graphhopper.jsprit.core.algorithm.recreate.VehicleSwitched; -import com.graphhopper.jsprit.core.algorithm.state.*; +import com.graphhopper.jsprit.core.algorithm.state.StateManager; import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; import com.graphhopper.jsprit.core.problem.constraint.ConstraintManager; -import com.graphhopper.jsprit.core.problem.constraint.SwitchNotFeasible; import com.graphhopper.jsprit.core.problem.solution.SolutionCostCalculator; import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution; -import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; -import com.graphhopper.jsprit.core.problem.vehicle.Vehicle; import com.graphhopper.jsprit.core.problem.vehicle.VehicleFleetManager; -import com.graphhopper.jsprit.core.problem.vehicle.VehicleTypeKey; -import com.graphhopper.jsprit.core.util.ActivityTimeTracker; -import java.util.*; +import java.util.Collection; +import java.util.Random; /** * Created by schroeder on 10.12.14. @@ -78,7 +74,8 @@ public class PrettyAlgorithmBuilder { } public PrettyAlgorithmBuilder withStrategy(SearchStrategy strategy, double weight) { - searchStrategyManager.addStrategy(strategy, weight); + if (weight > 0) + searchStrategyManager.addStrategy(strategy, weight); return this; } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/box/Jsprit.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/box/Jsprit.java index d7619dad..830b1b5a 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/box/Jsprit.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/box/Jsprit.java @@ -30,6 +30,7 @@ import com.graphhopper.jsprit.core.algorithm.recreate.*; import com.graphhopper.jsprit.core.algorithm.ruin.*; import com.graphhopper.jsprit.core.algorithm.ruin.distance.AvgServiceAndShipmentDistance; import com.graphhopper.jsprit.core.algorithm.selector.SelectBest; +import com.graphhopper.jsprit.core.algorithm.selector.SelectRandomly; import com.graphhopper.jsprit.core.algorithm.state.StateManager; import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; import com.graphhopper.jsprit.core.problem.constraint.ConstraintManager; @@ -82,7 +83,8 @@ public class Jsprit { CLUSTER_BEST("cluster_best"), CLUSTER_REGRET("cluster_regret"), STRING_BEST("string_best"), - STRING_REGRET("string_regret"); + STRING_REGRET("string_regret"), + RANDOM("random"); String strategyName; @@ -104,6 +106,8 @@ public class Jsprit { RANDOM_REGRET_MAX_SHARE("random_regret.max_share"), RANDOM_BEST_MIN_SHARE("random_best.min_share"), RANDOM_BEST_MAX_SHARE("random_best.max_share"), + RANDOM_RANDOM_MIN_SHARE("random_random.min_share"), + RANDOM_RANDOM_MAX_SHARE("random_random.max_share"), RADIAL_MIN_SHARE("radial.min_share"), RADIAL_MAX_SHARE("radial.max_share"), CLUSTER_MIN_SHARE("cluster.min_share"), @@ -192,6 +196,8 @@ public class Jsprit { defaults.put(Strategy.STRING_BEST.toString(), "0.0"); defaults.put(Strategy.STRING_REGRET.toString(), "0.0"); + defaults.put(Strategy.RANDOM.toString(), "0.0"); + defaults.put(Parameter.STRING_K_MIN.toString(), "1"); defaults.put(Parameter.STRING_K_MAX.toString(), "6"); defaults.put(Parameter.STRING_L_MIN.toString(), "10"); @@ -223,6 +229,8 @@ public class Jsprit { defaults.put(Parameter.RANDOM_REGRET_MAX_SHARE.toString(), String.valueOf(maxShare_)); defaults.put(Parameter.RANDOM_BEST_MIN_SHARE.toString(), String.valueOf(minShare_)); defaults.put(Parameter.RANDOM_BEST_MAX_SHARE.toString(), String.valueOf(maxShare_)); + defaults.put(Parameter.RANDOM_RANDOM_MIN_SHARE.toString(), String.valueOf(minShare_)); + defaults.put(Parameter.RANDOM_RANDOM_MAX_SHARE.toString(), String.valueOf(maxShare_)); defaults.put(Parameter.THRESHOLD_ALPHA.toString(), String.valueOf(0.15)); defaults.put(Parameter.THRESHOLD_INI.toString(), String.valueOf(0.03)); defaults.put(Parameter.INSERTION_NOISE_LEVEL.toString(), String.valueOf(0.15)); @@ -475,9 +483,17 @@ public class Jsprit { final RuinRandom random_for_best = new RuinRandom(vrp, 0.5); random_for_best.setRandom(random); random_for_best.setRuinShareFactory(new RuinShareFactoryImpl( - toInteger(properties.getProperty(Parameter.RANDOM_BEST_MIN_SHARE.toString())), - toInteger(properties.getProperty(Parameter.RANDOM_BEST_MAX_SHARE.toString())), - random) + toInteger(properties.getProperty(Parameter.RANDOM_BEST_MIN_SHARE.toString())), + toInteger(properties.getProperty(Parameter.RANDOM_BEST_MAX_SHARE.toString())), + random) + ); + + final RuinRandom random_for_random = new RuinRandom(vrp, 0.5); + random_for_random.setRandom(random); + random_for_random.setRuinShareFactory(new RuinShareFactoryImpl( + toInteger(properties.getProperty(Parameter.RANDOM_RANDOM_MIN_SHARE.toString())), + toInteger(properties.getProperty(Parameter.RANDOM_RANDOM_MAX_SHARE.toString())), + random) ); final RuinWorst worst = new RuinWorst(vrp, (int) (vrp.getJobs().values().size() * 0.5)); @@ -600,6 +616,14 @@ public class Jsprit { } best.setRandom(random); + final AbstractInsertionStrategy randomInsertion = (AbstractInsertionStrategy) new InsertionBuilder(vrp, vehicleFleetManager, stateManager, constraintManager) + .setInsertionStrategy(InsertionBuilder.Strategy.RANDOM) + .considerFixedCosts(Double.valueOf(properties.getProperty(Parameter.FIXED_COST_PARAM.toString()))) + .setAllowVehicleSwitch(toBoolean(getProperty(Parameter.VEHICLE_SWITCH.toString()))) + .setActivityInsertionCostCalculator(activityInsertion) + .build(); + randomInsertion.setRandom(random); + IterationStartsListener schrimpfThreshold = null; if(acceptor == null) { final SchrimpfAcceptance schrimpfAcceptance = new SchrimpfAcceptance(1, toDouble(getProperty(Parameter.THRESHOLD_ALPHA.toString()))); @@ -650,11 +674,15 @@ public class Jsprit { SearchStrategy stringBest = new SearchStrategy(Strategy.STRING_BEST.toString(), new SelectBest(), acceptor, objectiveFunction); stringBest.addModule(new RuinAndRecreateModule(Strategy.STRING_BEST.toString(), best, stringRuin)); + final SearchStrategy randomStrategy = new SearchStrategy(Strategy.RANDOM.toString(), new SelectRandomly(), acceptor, objectiveFunction); + randomStrategy.addModule(new RuinAndRecreateModule(Strategy.RANDOM.toString(), randomInsertion, random_for_random)); + PrettyAlgorithmBuilder prettyBuilder = PrettyAlgorithmBuilder.newInstance(vrp, vehicleFleetManager, stateManager, constraintManager); prettyBuilder.setRandom(random); if (addCoreConstraints) { prettyBuilder.addCoreStateAndConstraintStuff(); } + prettyBuilder.withStrategy(radial_regret, toDouble(getProperty(Strategy.RADIAL_REGRET.toString()))) .withStrategy(radial_best, toDouble(getProperty(Strategy.RADIAL_BEST.toString()))) .withStrategy(random_best, toDouble(getProperty(Strategy.RANDOM_BEST.toString()))) @@ -664,7 +692,8 @@ public class Jsprit { .withStrategy(clusters_regret, toDouble(getProperty(Strategy.CLUSTER_REGRET.toString()))) .withStrategy(clusters_best, toDouble(getProperty(Strategy.CLUSTER_BEST.toString()))) .withStrategy(stringBest, toDouble(getProperty(Strategy.STRING_BEST.toString()))) - .withStrategy(stringRegret, toDouble(getProperty(Strategy.STRING_REGRET.toString()))); + .withStrategy(stringRegret, toDouble(getProperty(Strategy.STRING_REGRET.toString()))) + .withStrategy(randomStrategy, toDouble((getProperty(Strategy.RANDOM.toString())))); for (SearchStrategy customStrategy : customStrategies.keySet()) { prettyBuilder.withStrategy(customStrategy, customStrategies.get(customStrategy)); diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/box/JspritTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/box/JspritTest.java index 0454e94c..40daeffb 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/box/JspritTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/box/JspritTest.java @@ -19,14 +19,21 @@ package com.graphhopper.jsprit.core.algorithm.box; import com.graphhopper.jsprit.core.algorithm.SearchStrategy; +import com.graphhopper.jsprit.core.algorithm.SearchStrategyModule; import com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm; +import com.graphhopper.jsprit.core.algorithm.acceptor.AcceptNewRemoveFirst; import com.graphhopper.jsprit.core.algorithm.listener.StrategySelectedListener; +import com.graphhopper.jsprit.core.algorithm.module.RuinAndRecreateModule; import com.graphhopper.jsprit.core.algorithm.recreate.InsertionData; import com.graphhopper.jsprit.core.algorithm.recreate.listener.BeforeJobInsertionListener; import com.graphhopper.jsprit.core.algorithm.recreate.listener.JobInsertedListener; import com.graphhopper.jsprit.core.algorithm.ruin.listener.RuinListener; +import com.graphhopper.jsprit.core.algorithm.selector.SelectBest; +import com.graphhopper.jsprit.core.algorithm.selector.SelectRandomly; +import com.graphhopper.jsprit.core.algorithm.state.StateManager; import com.graphhopper.jsprit.core.problem.Location; import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; +import com.graphhopper.jsprit.core.problem.constraint.ConstraintManager; import com.graphhopper.jsprit.core.problem.job.Job; import com.graphhopper.jsprit.core.problem.job.Service; import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution; @@ -38,6 +45,10 @@ import org.junit.Test; import java.util.*; +import static com.graphhopper.jsprit.core.algorithm.box.Jsprit.Parameter.BREAK_SCHEDULING; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + /** * Created by schroeder on 06/03/15. */ @@ -485,5 +496,58 @@ public class JspritTest { Assert.assertEquals(1, c); } + @Test + public void algBuildTest() { + Service s1 = Service.Builder.newInstance("s1").setLocation(Location.newInstance(1, 1)).build(); + Service s2 = Service.Builder.newInstance("s2").setLocation(Location.newInstance(1, 1)).build(); + Service s3 = Service.Builder.newInstance("s3").setLocation(Location.newInstance(1, 3)).build(); + Service s4 = Service.Builder.newInstance("s4").setLocation(Location.newInstance(1, 4)).build(); + + VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0, 0)).build(); + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().setFleetSize(VehicleRoutingProblem.FleetSize.FINITE).addJob(s4).addJob(s3).addVehicle(v).addJob(s2).addJob(s1).build(); + + final StateManager stateManager = new StateManager(vrp); + final ConstraintManager constraintManager = new ConstraintManager(vrp, stateManager); + final VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp).setStateAndConstraintManager(stateManager, constraintManager) + .addCoreStateAndConstraintStuff(true) + .setCustomAcceptor(new AcceptNewRemoveFirst(20)) + .setProperty(Jsprit.Parameter.RANDOM_REGRET_MIN_SHARE, String.valueOf((int) Math.ceil(Math.max(1, .5 * vrp.getJobs().size())))) + .setProperty(Jsprit.Parameter.RANDOM_REGRET_MAX_SHARE, String.valueOf((int) Math.ceil(Math.max(1, .5 * vrp.getJobs().size())))) + .setProperty(Jsprit.Parameter.CLUSTER_MIN_SHARE, String.valueOf((int) Math.ceil(Math.max(1, .2 * vrp.getJobs().size())))) + .setProperty(Jsprit.Parameter.CLUSTER_MAX_SHARE, String.valueOf((int) Math.ceil(Math.max(1, .2 * vrp.getJobs().size())))) + .setProperty(Jsprit.Parameter.RANDOM_RANDOM_MIN_SHARE, String.valueOf((int) Math.ceil(Math.max(1, .8 * vrp.getJobs().size())))) + .setProperty(Jsprit.Parameter.RANDOM_RANDOM_MAX_SHARE, String.valueOf((int) Math.ceil(Math.max(1, .8 * vrp.getJobs().size())))) + .setProperty(Jsprit.Parameter.RADIAL_MIN_SHARE, String.valueOf((int) Math.ceil(Math.max(1, .3 * vrp.getJobs().size())))) + .setProperty(Jsprit.Parameter.RADIAL_MAX_SHARE, String.valueOf((int) Math.ceil(Math.max(1, .3 * vrp.getJobs().size())))) + + .setProperty(BREAK_SCHEDULING, Boolean.FALSE.toString()) + + .setProperty(Jsprit.Strategy.RADIAL_REGRET, "0.4") + .setProperty(Jsprit.Strategy.CLUSTER_REGRET, "0.2") + .setProperty(Jsprit.Strategy.RANDOM_REGRET, "0.4") + .setProperty(Jsprit.Strategy.RANDOM, "0.01") + .setProperty(Jsprit.Strategy.RANDOM_BEST, "0") + .setProperty(Jsprit.Strategy.WORST_REGRET, "0") + .buildAlgorithm(); + + final List strategies = vra.getSearchStrategyManager().getStrategies(); + assertEquals(4, strategies.size()); + + for (SearchStrategy searchStrategy : strategies) { + if (!searchStrategy.getId().equals("random")) { + assertTrue(searchStrategy.getSolutionAcceptor() instanceof AcceptNewRemoveFirst); + assertTrue(searchStrategy.getSolutionSelector() instanceof SelectBest); + final SearchStrategyModule searchStrategyModule = searchStrategy.getSearchStrategyModules().iterator().next(); + assertTrue(searchStrategyModule instanceof RuinAndRecreateModule); + assertTrue(searchStrategyModule.getName().equals(searchStrategy.getId())); + } else { + assertTrue(searchStrategy.getSolutionAcceptor() instanceof AcceptNewRemoveFirst); + assertTrue(searchStrategy.getSolutionSelector() instanceof SelectRandomly); + final SearchStrategyModule searchStrategyModule = searchStrategy.getSearchStrategyModules().iterator().next(); + assertTrue(searchStrategyModule instanceof RuinAndRecreateModule); + assertTrue(searchStrategyModule.getName().equals("random")); + } + } + } }