diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/ruin/ClusterRuinStrategyFactory.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/ruin/ClusterRuinStrategyFactory.java new file mode 100644 index 00000000..2fb3d385 --- /dev/null +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/ruin/ClusterRuinStrategyFactory.java @@ -0,0 +1,20 @@ +package com.graphhopper.jsprit.core.algorithm.ruin; + +import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; + +public class ClusterRuinStrategyFactory implements RuinStrategyFactory { + + private int initialNumberJobsToRemove; + private JobNeighborhoods jobNeighborhoods; + + public ClusterRuinStrategyFactory(int initialNumberJobsToRemove, JobNeighborhoods jobNeighborhoods) { + super(); + this.initialNumberJobsToRemove = initialNumberJobsToRemove; + this.jobNeighborhoods = jobNeighborhoods; + } + + @Override + public RuinStrategy createStrategy(VehicleRoutingProblem vrp) { + return new RuinClusters(vrp, initialNumberJobsToRemove, jobNeighborhoods); + } +} \ No newline at end of file diff --git a/jsprit-io/src/main/java/com/graphhopper/jsprit/io/algorithm/VehicleRoutingAlgorithms.java b/jsprit-io/src/main/java/com/graphhopper/jsprit/io/algorithm/VehicleRoutingAlgorithms.java index 07b62bae..07ebaa97 100644 --- a/jsprit-io/src/main/java/com/graphhopper/jsprit/io/algorithm/VehicleRoutingAlgorithms.java +++ b/jsprit-io/src/main/java/com/graphhopper/jsprit/io/algorithm/VehicleRoutingAlgorithms.java @@ -26,6 +26,9 @@ import com.graphhopper.jsprit.core.algorithm.listener.VehicleRoutingAlgorithmLis import com.graphhopper.jsprit.core.algorithm.module.RuinAndRecreateModule; import com.graphhopper.jsprit.core.algorithm.recreate.InsertionStrategy; import com.graphhopper.jsprit.core.algorithm.recreate.listener.InsertionListener; +import com.graphhopper.jsprit.core.algorithm.ruin.ClusterRuinStrategyFactory; +import com.graphhopper.jsprit.core.algorithm.ruin.JobNeighborhoods; +import com.graphhopper.jsprit.core.algorithm.ruin.JobNeighborhoodsFactory; import com.graphhopper.jsprit.core.algorithm.ruin.RadialRuinStrategyFactory; import com.graphhopper.jsprit.core.algorithm.ruin.RandomRuinStrategyFactory; import com.graphhopper.jsprit.core.algorithm.ruin.RuinStrategy; @@ -482,7 +485,7 @@ public class VehicleRoutingAlgorithms { constraintManager.addSkillsConstraint(); constraintManager.addConstraint(new SwitchNotFeasible(stateManager)); - return readAndCreateAlgorithm(vrp, config, nuOfThreads, null, stateManager, constraintManager, true); + return readAndCreateAlgorithm(vrp, config, nuOfThreads, null, stateManager, constraintManager, true, true); } public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, AlgorithmConfig config, @@ -490,8 +493,20 @@ public class VehicleRoutingAlgorithms { return readAndCreateAlgorithm(vrp, config.getXMLConfiguration(), nuOfThreads, solutionCostCalculator, stateManager, constraintManager, addDefaultCostCalculators); } + + public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, AlgorithmConfig config, + int nuOfThreads, SolutionCostCalculator solutionCostCalculator, final StateManager stateManager, ConstraintManager constraintManager, boolean addDefaultCostCalculators, boolean addCoreConstraints) { + return readAndCreateAlgorithm(vrp, config.getXMLConfiguration(), nuOfThreads, solutionCostCalculator, stateManager, constraintManager, addDefaultCostCalculators, addCoreConstraints); + } + private static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, XMLConfiguration config, int nuOfThreads, final SolutionCostCalculator solutionCostCalculator, final StateManager stateManager, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { + + return readAndCreateAlgorithm(vrp, config, nuOfThreads, solutionCostCalculator, stateManager, constraintManager, addDefaultCostCalculators, true); + } + + private static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, XMLConfiguration config, + int nuOfThreads, final SolutionCostCalculator solutionCostCalculator, final StateManager stateManager, ConstraintManager constraintManager, boolean addDefaultCostCalculators, boolean addCoreConstraints) { // map to store constructed modules TypedMap definedClasses = new TypedMap(); @@ -574,6 +589,8 @@ public class VehicleRoutingAlgorithms { else costCalculator = solutionCostCalculator; PrettyAlgorithmBuilder prettyAlgorithmBuilder = PrettyAlgorithmBuilder.newInstance(vrp, vehicleFleetManager, stateManager, constraintManager); + if(addCoreConstraints) + prettyAlgorithmBuilder.addCoreStateAndConstraintStuff(); //construct initial solution creator final InsertionStrategy initialInsertionStrategy = createInitialSolution(config, vrp, vehicleFleetManager, stateManager, algorithmListeners, definedClasses, executorService, nuOfThreads, costCalculator, constraintManager, addDefaultCostCalculators); if (initialInsertionStrategy != null) @@ -839,18 +856,25 @@ public class VehicleRoutingAlgorithms { if (ruin_name == null) throw new IllegalStateException("module.ruin[@name] is missing."); String ruin_id = moduleConfig.getString("ruin[@id]"); if (ruin_id == null) ruin_id = "noId"; - String shareToRuinString = moduleConfig.getString("ruin.share"); - if (shareToRuinString == null) throw new IllegalStateException("module.ruin.share is missing."); - double shareToRuin = Double.valueOf(shareToRuinString); final RuinStrategy ruin; ModKey ruinKey = makeKey(ruin_name, ruin_id); if (ruin_name.equals("randomRuin")) { + String shareToRuinString = moduleConfig.getString("ruin.share"); + if (shareToRuinString == null) throw new IllegalStateException("module.ruin.share is missing."); + double shareToRuin = Double.valueOf(shareToRuinString); ruin = getRandomRuin(vrp, routeStates, definedClasses, ruinKey, shareToRuin); } else if (ruin_name.equals("radialRuin")) { + String shareToRuinString = moduleConfig.getString("ruin.share"); + if (shareToRuinString == null) throw new IllegalStateException("module.ruin.share is missing."); + double shareToRuin = Double.valueOf(shareToRuinString); JobDistance jobDistance = new AvgServiceAndShipmentDistance(vrp.getTransportCosts()); ruin = getRadialRuin(vrp, routeStates, definedClasses, ruinKey, shareToRuin, jobDistance); - } else - throw new IllegalStateException("ruin[@name] " + ruin_name + " is not known. Use either randomRuin or radialRuin."); + } else if (ruin_name.equals("clusterRuin")) { + String initialNumberJobsToRemoveString = moduleConfig.getString("ruin.initRemoveJobs"); + if (initialNumberJobsToRemoveString == null) throw new IllegalStateException("module.ruin.initRemoveJobs is missing."); + int initialNumberJobsToRemove = Integer.valueOf(initialNumberJobsToRemoveString); + ruin = getClusterRuin(vrp, routeStates, definedClasses, ruinKey, initialNumberJobsToRemove); + } else throw new IllegalStateException("ruin[@name] " + ruin_name + " is not known. Use either randomRuin or radialRuin."); String insertionName = moduleConfig.getString("insertion[@name]"); if (insertionName == null) @@ -877,7 +901,8 @@ public class VehicleRoutingAlgorithms { "\n\tcurrently there are following modules available: " + "\n\tbestInsertion" + "\n\trandomRuin" + - "\n\tradialRuin"); + "\n\tradialRuin" + + "\n\tclusterRuin"); } private static RuinStrategy getRadialRuin(final VehicleRoutingProblem vrp, final StateManager routeStates, TypedMap definedClasses, ModKey modKey, double shareToRuin, JobDistance jobDistance) { @@ -890,6 +915,17 @@ public class VehicleRoutingAlgorithms { return ruin; } + private static RuinStrategy getClusterRuin(final VehicleRoutingProblem vrp, final StateManager routeStates, TypedMap definedClasses, ModKey modKey, int initialNumberJobsToRemove) { + JobNeighborhoods jobNeighborhoods = new JobNeighborhoodsFactory().createNeighborhoods(vrp, new AvgServiceAndShipmentDistance(vrp.getTransportCosts())); + RuinStrategyKey stratKey = new RuinStrategyKey(modKey); + RuinStrategy ruin = definedClasses.get(stratKey); + if (ruin == null) { + ruin = new ClusterRuinStrategyFactory(initialNumberJobsToRemove, jobNeighborhoods).createStrategy(vrp); + definedClasses.put(stratKey, ruin); + } + return ruin; + } + private static RuinStrategy getRandomRuin(final VehicleRoutingProblem vrp, final StateManager routeStates, TypedMap definedClasses, ModKey modKey, double shareToRuin) { RuinStrategyKey stratKey = new RuinStrategyKey(modKey); RuinStrategy ruin = definedClasses.get(stratKey); diff --git a/jsprit-io/src/main/resources/algorithm_schema.xsd b/jsprit-io/src/main/resources/algorithm_schema.xsd index 555c0b99..d8bd7ec2 100644 --- a/jsprit-io/src/main/resources/algorithm_schema.xsd +++ b/jsprit-io/src/main/resources/algorithm_schema.xsd @@ -205,6 +205,13 @@ + + + + + + + @@ -218,6 +225,7 @@ +