diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/PrettyAlgorithmBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/PrettyAlgorithmBuilder.java
new file mode 100644
index 00000000..7d33fb35
--- /dev/null
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/PrettyAlgorithmBuilder.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (C) 2014 Stefan Schroeder
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ ******************************************************************************/
+
+package jsprit.core.algorithm;
+
+import jsprit.core.algorithm.acceptor.SchrimpfAcceptance;
+import jsprit.core.algorithm.acceptor.SolutionAcceptor;
+import jsprit.core.algorithm.listener.AlgorithmStartsListener;
+import jsprit.core.algorithm.recreate.InsertionStrategy;
+import jsprit.core.algorithm.recreate.VehicleSwitched;
+import jsprit.core.algorithm.state.*;
+import jsprit.core.problem.VehicleRoutingProblem;
+import jsprit.core.problem.constraint.ConstraintManager;
+import jsprit.core.problem.solution.SolutionCostCalculator;
+import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
+import jsprit.core.problem.solution.route.VehicleRoute;
+import jsprit.core.problem.vehicle.Vehicle;
+import jsprit.core.problem.vehicle.VehicleFleetManager;
+import jsprit.core.util.ActivityTimeTracker;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+* Created by schroeder on 10.12.14.
+*/
+public class PrettyAlgorithmBuilder {
+
+ private final VehicleRoutingProblem vrp;
+
+ private final VehicleFleetManager fleetManager;
+
+ private final StateManager stateManager;
+
+ private final ConstraintManager constraintManager;
+
+ private SearchStrategyManager searchStrategyManager;
+
+ private InsertionStrategy iniInsertionStrategy;
+
+ private SolutionCostCalculator iniObjFunction;
+
+ private boolean coreStuff = false;
+
+ public static PrettyAlgorithmBuilder newInstance(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager){
+ return new PrettyAlgorithmBuilder(vrp,fleetManager,stateManager,constraintManager);
+ }
+
+ PrettyAlgorithmBuilder(VehicleRoutingProblem vrp, VehicleFleetManager fleetManager, StateManager stateManager, ConstraintManager constraintManager){
+ this.vrp = vrp;
+ this.fleetManager = fleetManager;
+ this.stateManager = stateManager;
+ this.constraintManager = constraintManager;
+ this.searchStrategyManager = new SearchStrategyManager();
+ }
+
+ public PrettyAlgorithmBuilder withStrategy(SearchStrategy strategy, double weight){
+ searchStrategyManager.addStrategy(strategy,weight);
+ return this;
+ }
+
+ public PrettyAlgorithmBuilder constructInitialSolutionWith(InsertionStrategy insertionStrategy, SolutionCostCalculator objFunction){
+ this.iniInsertionStrategy = insertionStrategy;
+ this.iniObjFunction = objFunction;
+ return this;
+ }
+
+ public VehicleRoutingAlgorithm build(){
+ if(coreStuff){
+ constraintManager.addTimeWindowConstraint();
+ constraintManager.addLoadConstraint();
+ constraintManager.addSkillsConstraint();
+ stateManager.updateLoadStates();
+ stateManager.updateTimeWindowStates();
+ UpdateVehicleDependentPracticalTimeWindows tw_updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts());
+ tw_updater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() {
+ @Override
+ public Collection get(VehicleRoute vehicleRoute) {
+ Collection vehicles = new ArrayList();
+ vehicles.add(vehicleRoute.getVehicle());
+ vehicles.addAll(fleetManager.getAvailableVehicles(vehicleRoute.getVehicle()));
+ return vehicles;
+ }
+ });
+ stateManager.addStateUpdater(tw_updater);
+ stateManager.updateSkillStates();
+ stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen());
+ stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(), ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS));
+ stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
+ }
+ VehicleRoutingAlgorithm vra = new VehicleRoutingAlgorithm(vrp,searchStrategyManager);
+ vra.addListener(stateManager);
+ RemoveEmptyVehicles removeEmptyVehicles = new RemoveEmptyVehicles(fleetManager);
+ ResetAndIniFleetManager resetAndIniFleetManager = new ResetAndIniFleetManager(fleetManager);
+ VehicleSwitched vehicleSwitched = new VehicleSwitched(fleetManager);
+ vra.addListener(removeEmptyVehicles);
+ vra.addListener(resetAndIniFleetManager);
+ vra.addListener(vehicleSwitched);
+ if(iniInsertionStrategy != null) {
+ if (!iniInsertionStrategy.getListeners().contains(removeEmptyVehicles))
+ iniInsertionStrategy.addListener(removeEmptyVehicles);
+ if (!iniInsertionStrategy.getListeners().contains(resetAndIniFleetManager))
+ iniInsertionStrategy.addListener(resetAndIniFleetManager);
+ if (!iniInsertionStrategy.getListeners().contains(vehicleSwitched))
+ iniInsertionStrategy.addListener(vehicleSwitched);
+ if (!iniInsertionStrategy.getListeners().contains(stateManager))
+ iniInsertionStrategy.addListener(stateManager);
+ vra.addListener(new AlgorithmStartsListener() {
+ @Override
+ public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection solutions) {
+ solutions.add(new InsertionInitialSolutionFactory(iniInsertionStrategy, iniObjFunction).createSolution(vrp));
+ }
+ });
+ }
+ addArbitraryListener(vra);
+ return vra;
+ }
+
+ private void addArbitraryListener(VehicleRoutingAlgorithm vra) {
+ searchSchrimpfAndRegister(vra);
+ }
+
+ private void searchSchrimpfAndRegister(VehicleRoutingAlgorithm vra) {
+ for(SearchStrategy strategy : vra.getSearchStrategyManager().getStrategies()){
+ SolutionAcceptor acceptor = strategy.getSolutionAcceptor();
+ if(acceptor instanceof SchrimpfAcceptance){
+ vra.addListener((SchrimpfAcceptance)acceptor);
+ }
+ }
+ }
+
+ public PrettyAlgorithmBuilder addCoreStateAndConstraintStuff() {
+ this.coreStuff = true;
+ return this;
+ }
+
+}
diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java
index b5a30750..4bedad44 100644
--- a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java
+++ b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java
@@ -21,12 +21,10 @@ import jsprit.core.algorithm.*;
import jsprit.core.algorithm.acceptor.*;
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms.TypedMap.*;
import jsprit.core.algorithm.listener.AlgorithmEndsListener;
-import jsprit.core.algorithm.listener.AlgorithmStartsListener;
import jsprit.core.algorithm.listener.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
import jsprit.core.algorithm.listener.VehicleRoutingAlgorithmListeners.Priority;
import jsprit.core.algorithm.module.RuinAndRecreateModule;
import jsprit.core.algorithm.recreate.InsertionStrategy;
-import jsprit.core.algorithm.recreate.VehicleSwitched;
import jsprit.core.algorithm.recreate.listener.InsertionListener;
import jsprit.core.algorithm.ruin.RadialRuinStrategyFactory;
import jsprit.core.algorithm.ruin.RandomRuinStrategyFactory;
@@ -575,24 +573,15 @@ public class VehicleRoutingAlgorithms {
final SolutionCostCalculator costCalculator;
if(solutionCostCalculator==null) costCalculator = getDefaultCostCalculator(stateManager);
else costCalculator = solutionCostCalculator;
-
+
+ PrettyAlgorithmBuilder prettyAlgorithmBuilder = PrettyAlgorithmBuilder.newInstance(vrp,vehicleFleetManager,stateManager,constraintManager);
//construct initial solution creator
final InsertionStrategy initialInsertionStrategy = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,costCalculator, constraintManager, addDefaultCostCalculators);
- if(initialInsertionStrategy != null) algorithmListeners.add(new PrioritizedVRAListener(Priority.MEDIUM, new AlgorithmStartsListener() {
-
- @Override
- public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection solutions) {
- InsertionInitialSolutionFactory insertionInitialSolutionFactory = new InsertionInitialSolutionFactory(initialInsertionStrategy, costCalculator);
- VehicleRoutingProblemSolution vrpSol = insertionInitialSolutionFactory.createSolution(vrp);
- solutions.add(vrpSol);
- }
-
- }));
+ if(initialInsertionStrategy != null) prettyAlgorithmBuilder.constructInitialSolutionWith(initialInsertionStrategy,costCalculator);
//construct algorithm, i.e. search-strategies and its modules
int solutionMemory = config.getInt("strategy.memory");
- SearchStrategyManager searchStratManager = new SearchStrategyManager();
- List strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy");
+ List strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy");
for(HierarchicalConfiguration strategyConfig : strategyConfigs){
String name = getName(strategyConfig);
SolutionAcceptor acceptor = getAcceptor(strategyConfig,vrp,algorithmListeners,definedClasses,solutionMemory);
@@ -605,14 +594,13 @@ public class VehicleRoutingAlgorithms {
SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads, constraintManager, addDefaultCostCalculators);
strategy.addModule(module);
}
- searchStratManager.addStrategy(strategy, strategyConfig.getDouble("probability"));
- }
-
+ prettyAlgorithmBuilder.withStrategy(strategy,strategyConfig.getDouble("probability"));
+ }
+
//construct algorithm
- VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager);
- String maxIterationsString = config.getString("iterations");
- if(maxIterationsString == null) maxIterationsString = config.getString("maxIterations");
- if(maxIterationsString != null) metaAlgorithm.setMaxIterations(Integer.parseInt(maxIterationsString));
+ VehicleRoutingAlgorithm metaAlgorithm = prettyAlgorithmBuilder.build();
+ int maxIterations = getMaxIterations(config);
+ if(maxIterations > -1) metaAlgorithm.setMaxIterations(maxIterations);
//define prematureBreak
PrematureAlgorithmTermination prematureAlgorithmTermination = getPrematureTermination(config, algorithmListeners);
@@ -624,32 +612,17 @@ public class VehicleRoutingAlgorithms {
if(termination != null) metaAlgorithm.addTerminationCriterion(termination);
}
}
-
- RemoveEmptyVehicles removeEmptyVehicles = new RemoveEmptyVehicles(vehicleFleetManager);
- ResetAndIniFleetManager resetAndIniFleetManager = new ResetAndIniFleetManager(vehicleFleetManager);
- VehicleSwitched vehicleSwitched = new VehicleSwitched(vehicleFleetManager);
-
- metaAlgorithm.addListener(stateManager);
- metaAlgorithm.addListener(removeEmptyVehicles);
- metaAlgorithm.addListener(resetAndIniFleetManager);
- metaAlgorithm.addListener(vehicleSwitched);
-
- if(initialInsertionStrategy != null) {
- if(initialInsertionStrategy.getListeners() != null){
- if(!initialInsertionStrategy.getListeners().contains(stateManager)) initialInsertionStrategy.addListener(stateManager);
- if(!initialInsertionStrategy.getListeners().contains(removeEmptyVehicles)) initialInsertionStrategy.addListener(removeEmptyVehicles);
- if(!initialInsertionStrategy.getListeners().contains(resetAndIniFleetManager)) initialInsertionStrategy.addListener(resetAndIniFleetManager);
- if(!initialInsertionStrategy.getListeners().contains(vehicleSwitched)) initialInsertionStrategy.addListener(vehicleSwitched);
- }
- }
-
- //register listeners
- registerListeners(metaAlgorithm, algorithmListeners);
- registerInsertionListeners(definedClasses,insertionListeners);
- return metaAlgorithm;
+ return metaAlgorithm;
}
- private static SolutionCostCalculator getDefaultCostCalculator(final StateManager stateManager) {
+ private static int getMaxIterations(XMLConfiguration config) {
+ String maxIterationsString = config.getString("iterations");
+ if(maxIterationsString == null) maxIterationsString = config.getString("maxIterations");
+ if(maxIterationsString != null) return (Integer.parseInt(maxIterationsString));
+ return -1;
+ }
+
+ private static SolutionCostCalculator getDefaultCostCalculator(final StateManager stateManager) {
return new VariablePlusFixedSolutionCostCalculatorFactory(stateManager).createCalculator();
}
@@ -739,30 +712,12 @@ public class VehicleRoutingAlgorithms {
throw new IllegalStateException("prematureBreak basedOn " + basedOn + " is not defined");
}
- private static void registerInsertionListeners(TypedMap definedClasses, List insertionListeners) {
- for(AbstractKey> key : definedClasses.keySet()){
- if(key instanceof InsertionStrategyKey){
- InsertionStrategyKey insertionKey = (InsertionStrategyKey) key;
- InsertionStrategy insertionStrategy = definedClasses.get(insertionKey);
- for(InsertionListener l : insertionListeners){
- insertionStrategy.addListener(l);
- }
- }
- }
- }
-
- private static String getName(HierarchicalConfiguration strategyConfig) {
- if(strategyConfig.containsKey("[@name]")){
+ private static String getName(HierarchicalConfiguration strategyConfig) { if(strategyConfig.containsKey("[@name]")){
return strategyConfig.getString("[@name]");
}
return "";
}
-
- private static void registerListeners(VehicleRoutingAlgorithm metaAlgorithm, Set algorithmListeners) {
- metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners);
- }
-
private static InsertionStrategy createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, final StateManager routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, final SolutionCostCalculator solutionCostCalculator, ConstraintManager constraintManager, boolean addDefaultCostCalculators) {
List modConfigs = config.configurationsAt("construction.insertion");
if(modConfigs == null) return null;
@@ -782,12 +737,8 @@ public class VehicleRoutingAlgorithms {
algorithmListeners.addAll(prioListeners);
definedClasses.put(insertionStrategyKey,insertionStrategy);
}
- final InsertionStrategy finalInsertionStrategy = insertionStrategy;
-
- return finalInsertionStrategy;
-
-
- }
+ return insertionStrategy;
+ }
private static SolutionSelector getSelector(HierarchicalConfiguration strategyConfig, VehicleRoutingProblem vrp, Set algorithmListeners, TypedMap definedSelectors) {
String selectorName = strategyConfig.getString("selector[@name]");