1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

enable search with different insertion strategies

This commit is contained in:
oblonski 2014-12-10 13:12:15 +01:00
parent c472042781
commit 7ce6a8d68a
6 changed files with 233 additions and 31 deletions

View file

@ -494,7 +494,7 @@ public class VehicleRoutingAlgorithms {
} }
private static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, XMLConfiguration config, private static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, XMLConfiguration config,
int nuOfThreads, SolutionCostCalculator solutionCostCalculator, final StateManager stateManager, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { int nuOfThreads, final SolutionCostCalculator solutionCostCalculator, final StateManager stateManager, ConstraintManager constraintManager, boolean addDefaultCostCalculators) {
// map to store constructed modules // map to store constructed modules
TypedMap definedClasses = new TypedMap(); TypedMap definedClasses = new TypedMap();
@ -572,13 +572,22 @@ public class VehicleRoutingAlgorithms {
stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(),activityPolicy)); stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(),activityPolicy));
stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager, activityPolicy)); stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager, activityPolicy));
SolutionCostCalculator costCalculator; final SolutionCostCalculator costCalculator;
if(solutionCostCalculator==null) costCalculator = getDefaultCostCalculator(stateManager); if(solutionCostCalculator==null) costCalculator = getDefaultCostCalculator(stateManager);
else costCalculator = solutionCostCalculator; else costCalculator = solutionCostCalculator;
//construct initial solution creator //construct initial solution creator
AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,costCalculator, constraintManager, addDefaultCostCalculators); final InsertionStrategy initialInsertionStrategy = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,costCalculator, constraintManager, addDefaultCostCalculators);
if(createInitialSolution != null) algorithmListeners.add(new PrioritizedVRAListener(Priority.MEDIUM, createInitialSolution)); if(initialInsertionStrategy != null) algorithmListeners.add(new PrioritizedVRAListener(Priority.MEDIUM, new AlgorithmStartsListener() {
@Override
public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) {
InsertionInitialSolutionFactory insertionInitialSolutionFactory = new InsertionInitialSolutionFactory(initialInsertionStrategy, costCalculator);
VehicleRoutingProblemSolution vrpSol = insertionInitialSolutionFactory.createSolution(vrp);
solutions.add(vrpSol);
}
}));
//construct algorithm, i.e. search-strategies and its modules //construct algorithm, i.e. search-strategies and its modules
int solutionMemory = config.getInt("strategy.memory"); int solutionMemory = config.getInt("strategy.memory");
@ -605,13 +614,6 @@ public class VehicleRoutingAlgorithms {
if(maxIterationsString == null) maxIterationsString = config.getString("maxIterations"); if(maxIterationsString == null) maxIterationsString = config.getString("maxIterations");
if(maxIterationsString != null) metaAlgorithm.setMaxIterations(Integer.parseInt(maxIterationsString)); if(maxIterationsString != null) metaAlgorithm.setMaxIterations(Integer.parseInt(maxIterationsString));
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);
metaAlgorithm.getAlgorithmListeners().addListener(stateManager);
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(vehicleFleetManager));
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new ResetAndIniFleetManager(vehicleFleetManager));
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new VehicleSwitched(vehicleFleetManager));
//define prematureBreak //define prematureBreak
PrematureAlgorithmTermination prematureAlgorithmTermination = getPrematureTermination(config, algorithmListeners); PrematureAlgorithmTermination prematureAlgorithmTermination = getPrematureTermination(config, algorithmListeners);
if(prematureAlgorithmTermination != null) metaAlgorithm.setPrematureAlgorithmTermination(prematureAlgorithmTermination); if(prematureAlgorithmTermination != null) metaAlgorithm.setPrematureAlgorithmTermination(prematureAlgorithmTermination);
@ -623,12 +625,26 @@ public class VehicleRoutingAlgorithms {
} }
} }
RemoveEmptyVehicles removeEmptyVehicles = new RemoveEmptyVehicles(vehicleFleetManager);
//misc ResetAndIniFleetManager resetAndIniFleetManager = new ResetAndIniFleetManager(vehicleFleetManager);
// algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier())); VehicleSwitched vehicleSwitched = new VehicleSwitched(vehicleFleetManager);
//register listeners metaAlgorithm.addListener(stateManager);
registerListeners(metaAlgorithm,algorithmListeners); 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); registerInsertionListeners(definedClasses,insertionListeners);
return metaAlgorithm; return metaAlgorithm;
} }
@ -747,7 +763,7 @@ public class VehicleRoutingAlgorithms {
metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners); metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners);
} }
private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, final StateManager routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, final SolutionCostCalculator solutionCostCalculator, ConstraintManager constraintManager, boolean addDefaultCostCalculators) { private static InsertionStrategy createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, final StateManager routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, final SolutionCostCalculator solutionCostCalculator, ConstraintManager constraintManager, boolean addDefaultCostCalculators) {
List<HierarchicalConfiguration> modConfigs = config.configurationsAt("construction.insertion"); List<HierarchicalConfiguration> modConfigs = config.configurationsAt("construction.insertion");
if(modConfigs == null) return null; if(modConfigs == null) return null;
if(modConfigs.isEmpty()) return null; if(modConfigs.isEmpty()) return null;
@ -768,15 +784,7 @@ public class VehicleRoutingAlgorithms {
} }
final InsertionStrategy finalInsertionStrategy = insertionStrategy; final InsertionStrategy finalInsertionStrategy = insertionStrategy;
return new AlgorithmStartsListener() { return finalInsertionStrategy;
@Override
public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) {
InsertionInitialSolutionFactory insertionInitialSolutionFactory = new InsertionInitialSolutionFactory(finalInsertionStrategy, solutionCostCalculator);
VehicleRoutingProblemSolution vrpSol = insertionInitialSolutionFactory.createSolution(vrp);
solutions.add(vrpSol);
}
};
} }

View file

@ -0,0 +1,62 @@
/*******************************************************************************
* 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 <http://www.gnu.org/licenses/>.
******************************************************************************/
package jsprit.core.algorithm;
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.io.VrpXMLReader;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import junit.framework.Assert;
import org.junit.Test;
import java.util.Collection;
public class CVRPwithDeliveriesAndDifferentInsertionStrategies_IT {
@Test
public void whenWithTwoInsertionStrategiesWhereOnleOneIsInAlgo_itShouldWork(){
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(vrpBuilder).read("src/test/resources/vrpnc1-jsprit-with-deliveries.xml");
VehicleRoutingProblem vrp = vrpBuilder.build();
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "src/test/resources/algorithmConfig_greedyWithRegret.xml");
vra.setMaxIterations(10);
try {
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
Assert.assertTrue(true);
}
catch (Exception e){
Assert.assertTrue(false);
}
}
@Test
public void whenWithTwoInsertionStrategiesWhereBothAreInAlgo_itShouldWork(){
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(vrpBuilder).read("src/test/resources/vrpnc1-jsprit-with-deliveries.xml");
VehicleRoutingProblem vrp = vrpBuilder.build();
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "src/test/resources/algorithmConfig_greedyWithRegret_v2.xml");
vra.setMaxIterations(10);
try {
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
Assert.assertTrue(true);
}
catch (Exception e){
Assert.assertTrue(false);
}
}
}

View file

@ -0,0 +1,66 @@
<?xml version="1.0" ?>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ 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 <http://www.gnu.org/licenses/>.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<algorithm xmlns="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com algorithm_schema.xsd">
<iterations>2000</iterations>
<construction>
<insertion name="regretInsertion">
</insertion>
</construction>
<strategy>
<memory>1</memory>
<searchStrategies>
<searchStrategy name="randomRuinAndRecreate">
<selector name="selectBest"/>
<acceptor name="greedyAcceptance"/>
<modules>
<module name="ruin_and_recreate">
<ruin name="randomRuin">
<share>0.5</share>
</ruin>
<insertion name="bestInsertion"/>
</module>
</modules>
<probability>0.5</probability>
</searchStrategy>
<searchStrategy name="radialRuinAndRecreate">
<selector name="selectBest"/>
<acceptor name="greedyAcceptance"/>
<modules>
<module name="ruin_and_recreate">
<ruin name="radialRuin">
<share>0.3</share>
</ruin>
<insertion name="bestInsertion"/>
</module>
</modules>
<probability>0.5</probability>
</searchStrategy>
</searchStrategies>
</strategy>
</algorithm>

View file

@ -0,0 +1,66 @@
<?xml version="1.0" ?>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ 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 <http://www.gnu.org/licenses/>.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<algorithm xmlns="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com algorithm_schema.xsd">
<iterations>2000</iterations>
<construction>
<insertion name="regretInsertion">
</insertion>
</construction>
<strategy>
<memory>1</memory>
<searchStrategies>
<searchStrategy name="randomRuinAndRecreate">
<selector name="selectBest"/>
<acceptor name="greedyAcceptance"/>
<modules>
<module name="ruin_and_recreate">
<ruin name="randomRuin">
<share>0.5</share>
</ruin>
<insertion name="bestInsertion"/>
</module>
</modules>
<probability>0.5</probability>
</searchStrategy>
<searchStrategy name="radialRuinAndRecreate">
<selector name="selectBest"/>
<acceptor name="greedyAcceptance"/>
<modules>
<module name="ruin_and_recreate">
<ruin name="radialRuin">
<share>0.3</share>
</ruin>
<insertion name="regretInsertion"/>
</module>
</modules>
<probability>0.5</probability>
</searchStrategy>
</searchStrategies>
</strategy>
</algorithm>

View file

@ -40,7 +40,7 @@
<ruin name="randomRuin"> <ruin name="randomRuin">
<share>0.5</share> <share>0.5</share>
</ruin> </ruin>
<insertion name="regretInsertion"/> <insertion name="bestInsertion"/>
</module> </module>
</modules> </modules>
<probability>0.5</probability> <probability>0.5</probability>
@ -54,7 +54,7 @@
<ruin name="radialRuin"> <ruin name="radialRuin">
<share>0.3</share> <share>0.3</share>
</ruin> </ruin>
<insertion name="regretInsertion"/> <insertion name="bestInsertion"/>
</module> </module>
</modules> </modules>
<probability>0.5</probability> <probability>0.5</probability>

View file

@ -67,8 +67,8 @@ public class SolomonWithRegretInsertionExample {
* *
* The algorithm can be defined and configured in an xml-file. * The algorithm can be defined and configured in an xml-file.
*/ */
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, 2, "input/algorithmConfig_greedyWithRegret.xml"); VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig_greedyWithRegret.xml");
vra.setMaxIterations(50); vra.setMaxIterations(2);
AlgorithmEventsRecorder eventsRecorder = new AlgorithmEventsRecorder(vrp,new File("output/events.dgs.gz")); AlgorithmEventsRecorder eventsRecorder = new AlgorithmEventsRecorder(vrp,new File("output/events.dgs.gz"));
eventsRecorder.setRecordingRange(0,50); eventsRecorder.setRecordingRange(0,50);