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

change algorithmReader to allow concurrency

This commit is contained in:
oblonski 2013-06-20 16:58:39 +02:00
parent cdf4878bf9
commit 277ffdb51a
9 changed files with 317 additions and 208 deletions

View file

@ -30,10 +30,6 @@ import basics.route.VehicleRoute;
/** /**
* Simplest recreation strategy. All removed customers are inserted where
* insertion costs are minimal. I.e. each tour-agent is asked for minimal
* marginal insertion costs. The tour-agent offering the lowest marginal
* insertion costs gets the customer/shipment.
* *
* @author stefan schroeder * @author stefan schroeder
* *

View file

@ -35,10 +35,6 @@ import basics.route.VehicleRoute;
/** /**
* Simplest recreation strategy. All removed customers are inserted where
* insertion costs are minimal. I.e. each tour-agent is asked for minimal
* marginal insertion costs. The tour-agent offering the lowest marginal
* insertion costs gets the customer/shipment.
* *
* @author stefan schroeder * @author stefan schroeder
* *
@ -46,6 +42,9 @@ import basics.route.VehicleRoute;
final class BestInsertionConcurrent extends AbstractInsertionStrategy{ final class BestInsertionConcurrent extends AbstractInsertionStrategy{
public static BestInsertionConcurrent newInstance(RouteAlgorithm routeAlgorithm, ExecutorService executor, int nuOfThreads){
return new BestInsertionConcurrent(routeAlgorithm, executor, nuOfThreads);
}
static class Batch { static class Batch {
List<VehicleRoute> routes = new ArrayList<VehicleRoute>(); List<VehicleRoute> routes = new ArrayList<VehicleRoute>();
@ -68,7 +67,7 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{
this.random = random; this.random = random;
} }
public BestInsertionConcurrent(RouteAlgorithm routeAlgorithm, ExecutorService executor, int nuOfThreads) { private BestInsertionConcurrent(RouteAlgorithm routeAlgorithm, ExecutorService executor, int nuOfThreads) {
super(); super();
this.routeAlgorithm = routeAlgorithm; this.routeAlgorithm = routeAlgorithm;
// this.executor = executor; // this.executor = executor;
@ -87,7 +86,6 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs); List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
Collections.shuffle(unassignedJobList, random); Collections.shuffle(unassignedJobList, random);
informInsertionStarts(vehicleRoutes,unassignedJobs.size()); informInsertionStarts(vehicleRoutes,unassignedJobs.size());
int inserted = 0; int inserted = 0;
for(final Job unassignedJob : unassignedJobList){ for(final Job unassignedJob : unassignedJobList){
VehicleRoute insertIn = null; VehicleRoute insertIn = null;
@ -135,20 +133,20 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{
routeAlgorithm.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); routeAlgorithm.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
} }
else { else {
VehicleRoute newRoute = VehicleRoute.emptyRoute(); // VehicleRoute newRoute = VehicleRoute.emptyRoute();
InsertionData bestI = routeAlgorithm.calculateBestInsertion(newRoute, unassignedJob, Double.MAX_VALUE); // InsertionData bestI = routeAlgorithm.calculateBestInsertion(newRoute, unassignedJob, Double.MAX_VALUE);
if(bestI instanceof InsertionData.NoInsertionFound) // if(bestI instanceof InsertionData.NoInsertionFound)
throw new IllegalStateException("given the vehicles, could not create a valid solution.\n\tthe reason might be" + throw new IllegalStateException("given the vehicles, could not create a valid solution.\n\tthe reason might be" +
" inappropriate vehicle capacity.\n\tthe job that does not fit in any vehicle anymore is \n\t" + unassignedJob); " inappropriate vehicle capacity.\n\tthe job that does not fit in any vehicle anymore is \n\t" + unassignedJob);
insertIn = newRoute; // insertIn = newRoute;
informBeforeJobInsertion(unassignedJob,bestI,newRoute); // informBeforeJobInsertion(unassignedJob,bestI,newRoute);
routeAlgorithm.insertJob(unassignedJob,bestI,newRoute); // routeAlgorithm.insertJob(unassignedJob,bestI,newRoute);
vehicleRoutes.add(newRoute); // vehicleRoutes.add(newRoute);
} }
inserted++; inserted++;
informJobInserted((unassignedJobList.size()-inserted), unassignedJob, insertIn); informJobInserted((unassignedJobList.size()-inserted), unassignedJob, insertIn);
} }
informInsertionEndsListeners(vehicleRoutes);
} }
private Insertion getBestInsertion(Batch batch, Job unassignedJob) { private Insertion getBestInsertion(Batch batch, Job unassignedJob) {
@ -168,12 +166,22 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{
private List<Batch> distributeRoutes(Collection<VehicleRoute> vehicleRoutes, int nuOfBatches) { private List<Batch> distributeRoutes(Collection<VehicleRoute> vehicleRoutes, int nuOfBatches) {
List<Batch> batches = new ArrayList<Batch>(); List<Batch> batches = new ArrayList<Batch>();
for(int i=0;i<nuOfBatches;i++) batches.add(new Batch()); for(int i=0;i<nuOfBatches;i++) batches.add(new Batch());
if(vehicleRoutes.size()<nuOfBatches){ /*
int nOfNewRoutes = nuOfBatches-vehicleRoutes.size(); * if route.size < nuOfBatches add as much routes as empty batches are available
for(int i=0;i<nOfNewRoutes;i++){ * else add one empty route anyway
vehicleRoutes.add(VehicleRoute.emptyRoute()); */
} // if(vehicleRoutes.size()<nuOfBatches){
} // int nOfNewRoutes = nuOfBatches-vehicleRoutes.size();
// for(int i=0;i<nOfNewRoutes;i++){
// vehicleRoutes.add(VehicleRoute.emptyRoute());
// }
// }
// else{
vehicleRoutes.add(VehicleRoute.emptyRoute());
// }
/*
* distribute routes to batches equally
*/
int count = 0; int count = 0;
for(VehicleRoute route : vehicleRoutes){ for(VehicleRoute route : vehicleRoutes){
if(count == nuOfBatches) count=0; if(count == nuOfBatches) count=0;

View file

@ -22,6 +22,7 @@ package algorithms;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService;
import org.apache.commons.configuration.HierarchicalConfiguration; import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.configuration.XMLConfiguration;
@ -37,8 +38,9 @@ class InsertionFactory {
private static Logger log = Logger.getLogger(InsertionFactory.class); private static Logger log = Logger.getLogger(InsertionFactory.class);
public static AbstractInsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config, public static AbstractInsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config,
VehicleFleetManager vehicleFleetManager, RouteStates activityStates, List<PrioritizedVRAListener> algorithmListeners){ VehicleFleetManager vehicleFleetManager, RouteStates activityStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads){
boolean concurrentInsertion = false;
if(executorService != null) concurrentInsertion = true;
if(config.containsKey("[@name]")){ if(config.containsKey("[@name]")){
String insertionName = config.getString("[@name]"); String insertionName = config.getString("[@name]");
if(!insertionName.equals("bestInsertion") && !insertionName.equals("regretInsertion")){ if(!insertionName.equals("bestInsertion") && !insertionName.equals("regretInsertion")){
@ -98,7 +100,12 @@ class InsertionFactory {
((RouteAlgorithmImpl) routeAlgorithm).setActivityStates(activityStates); ((RouteAlgorithmImpl) routeAlgorithm).setActivityStates(activityStates);
if(insertionName.equals("bestInsertion")){ if(insertionName.equals("bestInsertion")){
insertionStrategy = BestInsertion.newInstance(routeAlgorithm); if(concurrentInsertion){
insertionStrategy = BestInsertionConcurrent.newInstance(routeAlgorithm,executorService,nuOfThreads);
}
else{
insertionStrategy = BestInsertion.newInstance(routeAlgorithm);
}
} }
else if(insertionName.equals("regretInsertion")){ else if(insertionName.equals("regretInsertion")){
insertionStrategy = RegretInsertion.newInstance(routeAlgorithm); insertionStrategy = RegretInsertion.newInstance(routeAlgorithm);

View file

@ -29,6 +29,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutorService;
import org.apache.commons.configuration.HierarchicalConfiguration; import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.configuration.XMLConfiguration;
@ -63,7 +64,6 @@ import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
import basics.algo.VehicleRoutingAlgorithmListeners.Priority; import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
import basics.io.AlgorithmConfig; import basics.io.AlgorithmConfig;
import basics.io.AlgorithmConfigXmlReader; import basics.io.AlgorithmConfigXmlReader;
import basics.route.VehicleRoute;
@ -367,12 +367,12 @@ public class VehicleRoutingAlgorithms {
* @return {@link VehicleRoutingAlgorithm} * @return {@link VehicleRoutingAlgorithm}
*/ */
public static VehicleRoutingAlgorithm createAlgorithm(final VehicleRoutingProblem vrp, final AlgorithmConfig algorithmConfig){ public static VehicleRoutingAlgorithm createAlgorithm(final VehicleRoutingProblem vrp, final AlgorithmConfig algorithmConfig){
return createAlgo(vrp,algorithmConfig.getXMLConfiguration()); return createAlgo(vrp,algorithmConfig.getXMLConfiguration(),null,0);
} }
@Deprecated @Deprecated
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final XMLConfiguration config){ public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final XMLConfiguration config){
return createAlgo(vrp,config); return createAlgo(vrp,config,null,0);
} }
/** /**
@ -386,7 +386,7 @@ public class VehicleRoutingAlgorithms {
AlgorithmConfig algorithmConfig = new AlgorithmConfig(); AlgorithmConfig algorithmConfig = new AlgorithmConfig();
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig); AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
xmlReader.read(configURL); xmlReader.read(configURL);
return createAlgo(vrp,algorithmConfig.getXMLConfiguration()); return createAlgo(vrp,algorithmConfig.getXMLConfiguration(),null,0);
} }
/** /**
@ -400,10 +400,26 @@ public class VehicleRoutingAlgorithms {
AlgorithmConfig algorithmConfig = new AlgorithmConfig(); AlgorithmConfig algorithmConfig = new AlgorithmConfig();
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig); AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
xmlReader.read(configFileName); xmlReader.read(configFileName);
return createAlgo(vrp,algorithmConfig.getXMLConfiguration()); return createAlgo(vrp,algorithmConfig.getXMLConfiguration(),null, 0);
} }
private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config){ /**
* Read and creates {@link VehicleRoutingAlgorithm} from config-file.
*
* @param vrp
* @param configFileName
* @param nuOfThreads TODO
* @param {@link ExecutorService}
* @return {@link VehicleRoutingAlgorithm}
*/
public static VehicleRoutingAlgorithm readAndCreateConcurrentAlgorithm(final VehicleRoutingProblem vrp, final String configFileName, final ExecutorService executorService, int nuOfThreads){
AlgorithmConfig algorithmConfig = new AlgorithmConfig();
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
xmlReader.read(configFileName);
return createAlgo(vrp,algorithmConfig.getXMLConfiguration(), executorService, nuOfThreads);
}
private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config, ExecutorService executorService, int nuOfThreads){
//fleetmanager //fleetmanager
final VehicleFleetManager vehicleFleetManager; final VehicleFleetManager vehicleFleetManager;
@ -433,7 +449,7 @@ public class VehicleRoutingAlgorithms {
/* /*
* initial solution - construction * initial solution - construction
*/ */
AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,routeStates,algorithmListeners,definedClasses); AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,routeStates,algorithmListeners,definedClasses,executorService,nuOfThreads);
if(createInitialSolution != null) algorithmListeners.add(new PrioritizedVRAListener(Priority.MEDIUM, createInitialSolution)); if(createInitialSolution != null) algorithmListeners.add(new PrioritizedVRAListener(Priority.MEDIUM, createInitialSolution));
int solutionMemory = config.getInt("strategy.memory"); int solutionMemory = config.getInt("strategy.memory");
@ -447,7 +463,7 @@ public class VehicleRoutingAlgorithms {
strategy.setName(name); strategy.setName(name);
List<HierarchicalConfiguration> modulesConfig = strategyConfig.configurationsAt("modules.module"); List<HierarchicalConfiguration> modulesConfig = strategyConfig.configurationsAt("modules.module");
for(HierarchicalConfiguration moduleConfig : modulesConfig){ for(HierarchicalConfiguration moduleConfig : modulesConfig){
SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,routeStates,algorithmListeners,definedClasses); SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,routeStates,algorithmListeners,definedClasses,executorService,nuOfThreads);
strategy.addModule(module); strategy.addModule(module);
} }
searchStratManager.addStrategy(strategy, strategyConfig.getDouble("probability")); searchStratManager.addStrategy(strategy, strategyConfig.getDouble("probability"));
@ -487,7 +503,7 @@ public class VehicleRoutingAlgorithms {
metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners); metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners);
} }
private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, RouteStates activityStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses) { private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, RouteStates activityStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads) {
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;
@ -502,7 +518,7 @@ public class VehicleRoutingAlgorithms {
AbstractInsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey); AbstractInsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey);
if(insertionStrategy == null){ if(insertionStrategy == null){
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>(); List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, activityStates, prioListeners); insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, activityStates, prioListeners, executorService, nuOfThreads);
algorithmListeners.addAll(prioListeners); algorithmListeners.addAll(prioListeners);
definedClasses.put(insertionStrategyKey,insertionStrategy); definedClasses.put(insertionStrategyKey,insertionStrategy);
} }
@ -584,7 +600,7 @@ public class VehicleRoutingAlgorithms {
} }
private static SearchStrategyModule buildModule(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, private static SearchStrategyModule buildModule(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager,
RouteStates activityStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses) { RouteStates activityStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads) {
String moduleName = moduleConfig.getString("[@name]"); String moduleName = moduleConfig.getString("[@name]");
if(moduleName == null) throw new IllegalStateException("module(-name) is missing."); if(moduleName == null) throw new IllegalStateException("module(-name) is missing.");
String moduleId = moduleConfig.getString("[@id]"); String moduleId = moduleConfig.getString("[@id]");
@ -633,7 +649,7 @@ public class VehicleRoutingAlgorithms {
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion"); List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>(); List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, activityStates, prioListeners); insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, activityStates, prioListeners, executorService, nuOfThreads);
algorithmListeners.addAll(prioListeners); algorithmListeners.addAll(prioListeners);
} }
final AbstractInsertionStrategy final_insertion = insertion; final AbstractInsertionStrategy final_insertion = insertion;
@ -676,51 +692,6 @@ public class VehicleRoutingAlgorithms {
return module; return module;
} }
// if(moduleName.equals("bestInsertion") || moduleName.equals("regretInsertion")){
// List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
// AbstractInsertionStrategy insertion = getInsertionStrategy(moduleConfig, vrp, vehicleFleetManager, activityStates,
// definedClasses, modKey, prioListeners);
// SearchStrategyModule module = getModule(moduleName, insertion, vrp);
// definedClasses.put(strategyModuleKey, module);
// algorithmListeners.addAll(prioListeners);
// return module;
// }
// if(moduleName.equals("regretInsertion")){
// List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
// AbstractInsertionKey insertionKey = new AbstractInsertionKey(modKey);
// AbstractInsertionStrategy regretInsertion = definedClasses.get(insertionKey);
// if(regretInsertion == null){
// regretInsertion = createInsertionStrategy(moduleConfig,vrp,vehicleFleetManager,activityStates,prioListeners);
// }
// SearchStrategyModule module = getModule(moduleName, regretInsertion, vrp);
// definedClasses.put(strategyModuleKey, module);
// algorithmListeners.addAll(prioListeners);
// return module;
// }
// if(moduleName.equals("randomRuin")){
// double shareToRuin = moduleConfig.getDouble("share");
// RuinStrategy ruin = getRandomRuin(vrp, activityStates,definedClasses, modKey, shareToRuin);
// SearchStrategyModule module = getModule(moduleName, ruin);
// definedClasses.put(strategyModuleKey, module);
// return module;
// }
// if(moduleName.equals("radialRuin")){
// double shareToRuin = moduleConfig.getDouble("share");
// String ruin_distance = moduleConfig.getString("distance");
// JobDistance jobDistance;
// if(ruin_distance == null) jobDistance = new JobDistanceAvgCosts(vrp.getTransportCosts());
// else {
// if(ruin_distance.equals("euclidean")){
// jobDistance = new EuclideanServiceDistance();
// }
// else throw new IllegalStateException("does not know ruin.distance " + ruin_distance + ". either ommit ruin.distance then the "
// + "default is used or use 'euclidean'");
// }
// RuinStrategy ruin = getRadialRuin(vrp, activityStates,definedClasses, modKey, shareToRuin, jobDistance);
// SearchStrategyModule module = getModule(moduleName, ruin);
// definedClasses.put(strategyModuleKey, module);
// return module;
// }
if(moduleName.equals("gendreauPostOpt")){ if(moduleName.equals("gendreauPostOpt")){
int iterations = moduleConfig.getInt("iterations"); int iterations = moduleConfig.getInt("iterations");
double share = moduleConfig.getDouble("share"); double share = moduleConfig.getDouble("share");
@ -747,7 +718,7 @@ public class VehicleRoutingAlgorithms {
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion"); List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>(); List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, activityStates, prioListeners); insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, activityStates, prioListeners, executorService, nuOfThreads);
algorithmListeners.addAll(prioListeners); algorithmListeners.addAll(prioListeners);
} }
GendreauPostOpt postOpt = new GendreauPostOpt(vrp, ruin, insertion); GendreauPostOpt postOpt = new GendreauPostOpt(vrp, ruin, insertion);
@ -766,17 +737,6 @@ public class VehicleRoutingAlgorithms {
"\n\tgendreauPostOpt"); "\n\tgendreauPostOpt");
} }
private static AbstractInsertionStrategy getInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager,
RouteStates activityStates, TypedMap definedClasses,
ModKey modKey, List<PrioritizedVRAListener> prioListeners) {
AbstractInsertionKey insertionKey = new AbstractInsertionKey(modKey);
AbstractInsertionStrategy bestInsertion = definedClasses.get(insertionKey);
if(bestInsertion == null){
bestInsertion = createInsertionStrategy(moduleConfig,vrp,vehicleFleetManager,activityStates,prioListeners);
}
return bestInsertion;
}
private static RuinStrategy getRadialRuin(VehicleRoutingProblem vrp, RouteStates activityStates, TypedMap definedClasses, ModKey modKey, double shareToRuin, JobDistance jobDistance) { private static RuinStrategy getRadialRuin(VehicleRoutingProblem vrp, RouteStates activityStates, TypedMap definedClasses, ModKey modKey, double shareToRuin, JobDistance jobDistance) {
RuinStrategyKey stratKey = new RuinStrategyKey(modKey); RuinStrategyKey stratKey = new RuinStrategyKey(modKey);
RuinStrategy ruin = definedClasses.get(stratKey); RuinStrategy ruin = definedClasses.get(stratKey);
@ -799,115 +759,10 @@ public class VehicleRoutingAlgorithms {
return ruin; return ruin;
} }
private static AbstractInsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, RouteStates activityStates, List<PrioritizedVRAListener> algorithmListeners) { private static AbstractInsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, RouteStates activityStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads) {
AbstractInsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, activityStates, algorithmListeners); AbstractInsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, activityStates, algorithmListeners, executorService, nuOfThreads);
return insertion; return insertion;
} }
private static SearchStrategyModule getModule(final String moduleName, final AbstractInsertionStrategy insertion, final VehicleRoutingProblem vrp){
return new SearchStrategyModule() {
private Logger logger = Logger.getLogger(SearchStrategyModule.class);
@Override
public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) {
List<Job> unassignedJobs = getUnassignedJobs(vrpSolution,vrp);
// logger.info("unassigned: " + unassignedJobs.size());
insertion.run(vrpSolution.getRoutes(), unassignedJobs, Double.MAX_VALUE);
int jobsInSolution = countJobs(vrpSolution);
double penalty = 0.0;
if(jobsInSolution != vrp.getJobs().values().size()){
throw new IllegalStateException("solution not valid\n" + "#jobsInSolution=" + jobsInSolution + " #jobsInVrp=" + vrp.getJobs().values().size());
}
double totalCost = RouteUtils.getTotalCost(vrpSolution.getRoutes());
vrpSolution.setCost(totalCost + penalty);
return vrpSolution;
}
@Override
public String toString() {
return "[name="+insertion+"]";
}
private int countJobs(VehicleRoutingProblemSolution vrpSolution) {
int counter = 0;
for(VehicleRoute route : vrpSolution.getRoutes()){
counter += route.getTourActivities().jobSize();
}
return counter;
}
private List<Job> getUnassignedJobs(VehicleRoutingProblemSolution vrpSolution,VehicleRoutingProblem vrp) {
List<Job> unassignedJobs = new ArrayList<Job>();
for(Job j : vrp.getJobs().values()){
boolean notAssigned = true;
for(VehicleRoute r : vrpSolution.getRoutes()){
if(r.getTourActivities().servesJob(j)){
notAssigned = false;
break;
}
}
if(notAssigned){
unassignedJobs.add(j);
}
}
return unassignedJobs;
}
@Override
public String getName() {
return moduleName;
}
@Override
public void addModuleListener(SearchStrategyModuleListener moduleListener) {
if(moduleListener instanceof InsertionListener){
InsertionListener iListener = (InsertionListener) moduleListener;
if(!insertion.getListener().contains(iListener)){
logger.info("register moduleListener " + moduleListener);
insertion.addListener(iListener);
}
}
}
};
}
// private static SearchStrategyModule getModule(final String moduleName, final RuinStrategy ruin) {
//
//
// return new SearchStrategyModule() {
//
// private Logger logger = Logger.getLogger(SearchStrategyModule.class);
//
// @Override
// public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) {
// ruin.ruin(vrpSolution.getRoutes());
// return vrpSolution;
// }
//
// @Override
// public String toString() {
// return "[name="+ruin+"]";
// }
//
// @Override
// public String getName() {
// return moduleName;
// }
//
// @Override
// public void addModuleListener(SearchStrategyModuleListener moduleListener) {
// // TODO Auto-generated method stub
//
// }
//
// };
// }
} }

View file

@ -34,7 +34,7 @@
<searchStrategy name="randomRuinAndRecreate"> <searchStrategy name="randomRuinAndRecreate">
<selector name="selectBest"/> <selector name="selectBest"/>
<acceptor name="schrimpfAcceptance"> <acceptor name="schrimpfAcceptance">
<alpha>0.05</alpha> <alpha>0.15</alpha>
<warmup>100</warmup> <warmup>100</warmup>
</acceptor> </acceptor>
<modules> <modules>

View file

@ -0,0 +1,107 @@
package examples;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import util.Coordinate;
import util.Solutions;
import algorithms.VehicleRoutingAlgorithms;
import analysis.AlgorithmSearchProgressChartListener;
import analysis.SolutionPlotter;
import analysis.SolutionPrinter;
import analysis.StopWatch;
import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblem.FleetSize;
import basics.VehicleRoutingProblemSolution;
import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
import basics.io.VrpXMLReader;
import basics.route.Vehicle;
import basics.route.VehicleImpl;
import basics.route.VehicleImpl.VehicleType;
public class ConcurrentMultipleDepotExample {
/**
* @param args
*/
public static void main(String[] args) {
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
/*
* Read cordeau-instance p01, BUT only its services without any vehicles
*/
new VrpXMLReader(vrpBuilder).read("input/vrp_cordeau_01.xml");
/*
* add vehicles with its depots
* 4 depots:
* (20,20)
* (30,40)
* (50,30)
* (60,50)
*
* each with 4 vehicles each with a capacity of 80
*/
int nuOfVehicles = 4;
int capacity = 80;
Coordinate firstDepotCoord = Coordinate.newInstance(20, 20);
Coordinate second = Coordinate.newInstance(30, 40);
Coordinate third = Coordinate.newInstance(50, 30);
Coordinate fourth = Coordinate.newInstance(60, 50);
int depotCounter = 1;
for(Coordinate depotCoord : Arrays.asList(firstDepotCoord,second,third,fourth)){
for(int i=0;i<nuOfVehicles;i++){
VehicleType vehicleType = VehicleType.Builder.newInstance(depotCounter + "_" + (i+1) + "_type", capacity).setCostPerDistance(1.0).build();
Vehicle vehicle = VehicleImpl.VehicleBuilder.newInstance(depotCounter + "_" + (i+1) + "_vehicle").setLocationCoord(depotCoord).setType(vehicleType).build();
vrpBuilder.addVehicle(vehicle);
}
depotCounter++;
}
/*
* define problem with finite fleet
*/
vrpBuilder.setFleetSize(FleetSize.FINITE);
/*
* build the problem
*/
VehicleRoutingProblem vrp = vrpBuilder.build();
/*
* plot to see how the problem looks like
*/
// SolutionPlotter.plotVrpAsPNG(vrp, "output/problem01.png", "p01");
/*
* Def. executorService and nuOfThreads
*/
int nuOfThreads = Runtime.getRuntime().availableProcessors() + 2;
ExecutorService executor = Executors.newFixedThreadPool(nuOfThreads);
/*
* solve the problem
*/
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateConcurrentAlgorithm(vrp, "input/algorithmConfig.xml", executor, nuOfThreads);
vra.setNuOfIterations(20000);
vra.getAlgorithmListeners().addListener(new StopWatch(),Priority.HIGH);
vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/progress.png"));
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
SolutionPrinter.print(Solutions.getBest(solutions));
SolutionPlotter.plotSolutionAsPNG(vrp, Solutions.getBest(solutions), "output/p01_solution.png", "p01");
}
}

View file

@ -0,0 +1,126 @@
package examples;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import util.Coordinate;
import util.Solutions;
import algorithms.VehicleRoutingAlgorithms;
import analysis.AlgorithmSearchProgressChartListener;
import analysis.SolutionPlotter;
import analysis.SolutionPrinter;
import analysis.StopWatch;
import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblem.FleetSize;
import basics.VehicleRoutingProblemSolution;
import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
import basics.io.VrpXMLReader;
import basics.route.Vehicle;
import basics.route.VehicleImpl;
import basics.route.VehicleImpl.VehicleType;
public class ConcurrentMultipleDepotExampleWithPenaltyVehicles {
/**
* @param args
*/
public static void main(String[] args) {
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
/*
* Read cordeau-instance p01, BUT only its services without any vehicles
*/
new VrpXMLReader(vrpBuilder).read("input/vrp_cordeau_08.xml");
/*
* add vehicles with its depots
* 2 depots:
* (-33,33)
* (33,-33)
*
* each with 14 vehicles each with a capacity of 500 and a maximum duration of 310
*/
int nuOfVehicles = 14;
int capacity = 500;
double maxDuration = 310;
Coordinate firstDepotCoord = Coordinate.newInstance(-33, 33);
Coordinate second = Coordinate.newInstance(33, -33);
/*
* number of penalty vehicles
*/
int nuOfPenaltyVehicles = 4;
int depotCounter = 1;
for(Coordinate depotCoord : Arrays.asList(firstDepotCoord,second)){
for(int i=0;i<nuOfVehicles;i++){
VehicleType vehicleType = VehicleType.Builder.newInstance(depotCounter + "_" + (i+1) + "_type", capacity).setCostPerDistance(1.0).build();
String vehicleId = depotCounter + "_" + (i+1) + "_vehicle";
VehicleImpl.VehicleBuilder vehicleBuilder = VehicleImpl.VehicleBuilder.newInstance(vehicleId);
vehicleBuilder.setLocationCoord(depotCoord);
vehicleBuilder.setType(vehicleType);
vehicleBuilder.setLatestArrival(maxDuration);
Vehicle vehicle = vehicleBuilder.build();
vrpBuilder.addVehicle(vehicle);
}
for(int i=0;i<nuOfPenaltyVehicles;i++){
VehicleType penaltyType = VehicleType.Builder.newInstance(depotCounter + "_" + (i+1) + "_penaltyType", capacity).setFixedCost(50).setCostPerDistance(3.0).build();
String vehicleId = depotCounter + "_" + (i+1) + "_penaltyVehicle";
VehicleImpl.VehicleBuilder vehicleBuilder = VehicleImpl.VehicleBuilder.newInstance(vehicleId);
vehicleBuilder.setLocationCoord(depotCoord);
vehicleBuilder.setType(penaltyType);
vehicleBuilder.setLatestArrival(maxDuration);
Vehicle penaltyVehicle = vehicleBuilder.build();
vrpBuilder.addVehicle(penaltyVehicle);
}
depotCounter++;
}
/*
* define problem with finite fleet
*/
vrpBuilder.setFleetSize(FleetSize.FINITE);
/*
* build the problem
*/
VehicleRoutingProblem vrp = vrpBuilder.build();
/*
* plot to see how the problem looks like
*/
// SolutionPlotter.plotVrpAsPNG(vrp, "output/problem08.png", "p08");
/*
* Def. executorService and nuOfThreads
*/
int nuOfThreads = Runtime.getRuntime().availableProcessors() + 2;
ExecutorService executor = Executors.newFixedThreadPool(nuOfThreads);
/*
* solve the problem
*/
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateConcurrentAlgorithm(vrp, "input/algorithmConfig.xml",executor,nuOfThreads);
vra.setNuOfIterations(5000);
vra.getAlgorithmListeners().addListener(new StopWatch(),Priority.HIGH);
vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/progress.png"));
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
SolutionPrinter.print(Solutions.getBest(solutions));
SolutionPlotter.plotSolutionAsPNG(vrp, Solutions.getBest(solutions), "output/p08_solution.png", "p08");
}
}

View file

@ -9,10 +9,12 @@ import algorithms.VehicleRoutingAlgorithms;
import analysis.AlgorithmSearchProgressChartListener; import analysis.AlgorithmSearchProgressChartListener;
import analysis.SolutionPlotter; import analysis.SolutionPlotter;
import analysis.SolutionPrinter; import analysis.SolutionPrinter;
import analysis.StopWatch;
import basics.VehicleRoutingAlgorithm; import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblem.FleetSize; import basics.VehicleRoutingProblem.FleetSize;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
import basics.io.VrpXMLReader; import basics.io.VrpXMLReader;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleImpl; import basics.route.VehicleImpl;
@ -77,6 +79,9 @@ public class MultipleDepotExample {
* solve the problem * solve the problem
*/ */
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig.xml"); VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig.xml");
vra.setNuOfIterations(5000);
vra.getAlgorithmListeners().addListener(new StopWatch(),Priority.HIGH);
vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/progress.png"));
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions(); Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
SolutionPrinter.print(Solutions.getBest(solutions)); SolutionPrinter.print(Solutions.getBest(solutions));

View file

@ -9,10 +9,12 @@ import algorithms.VehicleRoutingAlgorithms;
import analysis.AlgorithmSearchProgressChartListener; import analysis.AlgorithmSearchProgressChartListener;
import analysis.SolutionPlotter; import analysis.SolutionPlotter;
import analysis.SolutionPrinter; import analysis.SolutionPrinter;
import analysis.StopWatch;
import basics.VehicleRoutingAlgorithm; import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblem.FleetSize; import basics.VehicleRoutingProblem.FleetSize;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
import basics.io.VrpXMLReader; import basics.io.VrpXMLReader;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleImpl; import basics.route.VehicleImpl;
@ -62,8 +64,8 @@ public class MultipleDepotExampleWithPenaltyVehicles {
vrpBuilder.addVehicle(vehicle); vrpBuilder.addVehicle(vehicle);
} }
for(int i=0;i<nuOfPenaltyVehicles;i++){ for(int i=0;i<nuOfPenaltyVehicles;i++){
VehicleType penaltyType = VehicleType.Builder.newInstance(depotCounter + "_" + (i+1) + "_penaltyType", capacity).setFixedCost(50).setCostPerDistance(3.0).build(); VehicleType penaltyType = VehicleType.Builder.newInstance(depotCounter + "_" + (i+1) + "_type#penalty", capacity).setFixedCost(50).setCostPerDistance(3.0).build();
String vehicleId = depotCounter + "_" + (i+1) + "_penaltyVehicle"; String vehicleId = depotCounter + "_" + (i+1) + "_vehicle#penalty";
VehicleImpl.VehicleBuilder vehicleBuilder = VehicleImpl.VehicleBuilder.newInstance(vehicleId); VehicleImpl.VehicleBuilder vehicleBuilder = VehicleImpl.VehicleBuilder.newInstance(vehicleId);
vehicleBuilder.setLocationCoord(depotCoord); vehicleBuilder.setLocationCoord(depotCoord);
vehicleBuilder.setType(penaltyType); vehicleBuilder.setType(penaltyType);
@ -95,6 +97,9 @@ public class MultipleDepotExampleWithPenaltyVehicles {
* solve the problem * solve the problem
*/ */
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig.xml"); VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig.xml");
vra.setNuOfIterations(5000);
vra.getAlgorithmListeners().addListener(new StopWatch(),Priority.HIGH);
vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/progress.png"));
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions(); Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
SolutionPrinter.print(Solutions.getBest(solutions)); SolutionPrinter.print(Solutions.getBest(solutions));