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 @@
+