mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
improve JobDistance for RadialRuin
This commit is contained in:
parent
b0de3eef86
commit
3587c7fe94
8 changed files with 233 additions and 145 deletions
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2011 Stefan Schroeder.
|
||||||
|
* eMail: stefan.schroeder@kit.edu
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the GNU Public License v2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Stefan Schroeder - initial API and implementation
|
||||||
|
******************************************************************************/
|
||||||
|
package algorithms;
|
||||||
|
|
||||||
|
import util.EuclideanDistanceCalculator;
|
||||||
|
import basics.Job;
|
||||||
|
import basics.Service;
|
||||||
|
|
||||||
|
class EuclideanServiceDistance implements JobDistance {
|
||||||
|
|
||||||
|
public EuclideanServiceDistance() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double calculateDistance(Job i, Job j) {
|
||||||
|
double avgCost = 0.0;
|
||||||
|
if (i instanceof Service && j instanceof Service) {
|
||||||
|
if (i.equals(j)) {
|
||||||
|
avgCost = 0.0;
|
||||||
|
} else {
|
||||||
|
Service s_i = (Service) i;
|
||||||
|
Service s_j = (Service) j;
|
||||||
|
if(s_i.getCoord() == null || s_j.getCoord() == null) throw new IllegalStateException("cannot calculate euclidean distance. since service coords are missing");
|
||||||
|
avgCost = EuclideanDistanceCalculator.calculateDistance(s_i.getCoord(), s_j.getCoord());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"currently, this class just works with shipments and services.");
|
||||||
|
}
|
||||||
|
return avgCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -12,14 +12,25 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import basics.Job;
|
import basics.Job;
|
||||||
import basics.Service;
|
import basics.Service;
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
import basics.costs.VehicleRoutingTransportCosts;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculator that calculates average distance between two jobs based on the input-transport costs.
|
||||||
|
*
|
||||||
|
* <p>If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs.
|
||||||
|
*
|
||||||
|
* @author stefan schroeder
|
||||||
|
*
|
||||||
|
*/
|
||||||
class JobDistanceAvgCosts implements JobDistance {
|
class JobDistanceAvgCosts implements JobDistance {
|
||||||
|
|
||||||
|
private static Logger log = Logger.getLogger(JobDistanceAvgCosts.class);
|
||||||
|
|
||||||
private VehicleRoutingTransportCosts costs;
|
private VehicleRoutingTransportCosts costs;
|
||||||
|
|
||||||
public JobDistanceAvgCosts(VehicleRoutingTransportCosts costs) {
|
public JobDistanceAvgCosts(VehicleRoutingTransportCosts costs) {
|
||||||
|
|
@ -28,29 +39,21 @@ class JobDistanceAvgCosts implements JobDistance {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates and returns the average distance between two jobs based on the input-transport costs.
|
||||||
|
*
|
||||||
|
* <p>If the distance between two jobs cannot be calculated with input-transport costs, it tries the euclidean distance between these jobs.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public double calculateDistance(Job i, Job j) {
|
public double calculateDistance(Job i, Job j) {
|
||||||
double avgCost = 0.0;
|
double avgCost = 0.0;
|
||||||
// if (i instanceof Shipment && j instanceof Shipment) {
|
|
||||||
// if (i.equals(j)) {
|
|
||||||
// avgCost = 0.0;
|
|
||||||
// } else {
|
|
||||||
// Shipment s_i = (Shipment) i;
|
|
||||||
// Shipment s_j = (Shipment) j;
|
|
||||||
// double cost_i1_j1 = calcDist(s_i.getFromId(), s_j.getFromId());
|
|
||||||
// double cost_i1_j2 = calcDist(s_i.getFromId(), s_j.getToId());
|
|
||||||
// double cost_i2_j1 = calcDist(s_i.getToId(), s_j.getFromId());
|
|
||||||
// double cost_i2_j2 = calcDist(s_i.getToId(), s_j.getToId());
|
|
||||||
// avgCost = (cost_i1_j1 + cost_i1_j2 + cost_i2_j1 + cost_i2_j2) / 4;
|
|
||||||
// }
|
|
||||||
// } else
|
|
||||||
if (i instanceof Service && j instanceof Service) {
|
if (i instanceof Service && j instanceof Service) {
|
||||||
if (i.equals(j)) {
|
if (i.equals(j)) {
|
||||||
avgCost = 0.0;
|
avgCost = 0.0;
|
||||||
} else {
|
} else {
|
||||||
Service s_i = (Service) i;
|
Service s_i = (Service) i;
|
||||||
Service s_j = (Service) j;
|
Service s_j = (Service) j;
|
||||||
avgCost = calcDist(s_i.getLocationId(), s_j.getLocationId());
|
avgCost = calcDist(s_i, s_j);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
|
|
@ -59,8 +62,18 @@ class JobDistanceAvgCosts implements JobDistance {
|
||||||
return avgCost;
|
return avgCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double calcDist(String from, String to) {
|
private double calcDist(Service s_i, Service s_j) {
|
||||||
return costs.getTransportCost(from, to, 0.0, null, null);
|
double distance;
|
||||||
|
try{
|
||||||
|
distance = costs.getTransportCost(s_i.getLocationId(), s_j.getLocationId(), 0.0, null, null);
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
catch(IllegalStateException e){
|
||||||
|
// now try the euclidean distance between these two services
|
||||||
|
}
|
||||||
|
EuclideanServiceDistance euclidean = new EuclideanServiceDistance();
|
||||||
|
distance = euclidean.calculateDistance(s_i, s_j);
|
||||||
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,19 +31,6 @@ class JobDistanceBeeline implements JobDistance {
|
||||||
@Override
|
@Override
|
||||||
public double calculateDistance(Job i, Job j) {
|
public double calculateDistance(Job i, Job j) {
|
||||||
double avgCost = 0.0;
|
double avgCost = 0.0;
|
||||||
// if (i instanceof Shipment && j instanceof Shipment) {
|
|
||||||
// if (i.equals(j)) {
|
|
||||||
// avgCost = 0.0;
|
|
||||||
// } else {
|
|
||||||
// Shipment s_i = (Shipment) i;
|
|
||||||
// Shipment s_j = (Shipment) j;
|
|
||||||
// double cost_i1_j1 = calcDist(s_i.getFromId(), s_j.getFromId());
|
|
||||||
// double cost_i1_j2 = calcDist(s_i.getFromId(), s_j.getToId());
|
|
||||||
// double cost_i2_j1 = calcDist(s_i.getToId(), s_j.getFromId());
|
|
||||||
// double cost_i2_j2 = calcDist(s_i.getToId(), s_j.getToId());
|
|
||||||
// avgCost = (cost_i1_j1 + cost_i1_j2 + cost_i2_j1 + cost_i2_j2) / 4;
|
|
||||||
// }
|
|
||||||
// } else
|
|
||||||
if (i instanceof Service && j instanceof Service) {
|
if (i instanceof Service && j instanceof Service) {
|
||||||
if (i.equals(j)) {
|
if (i.equals(j)) {
|
||||||
avgCost = 0.0;
|
avgCost = 0.0;
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,13 @@ public class VehicleRoutingAlgorithms {
|
||||||
|
|
||||||
private VehicleRoutingAlgorithms(){}
|
private VehicleRoutingAlgorithms(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link VehicleRoutingAlgorithm} from a AlgorithConfig based on the input vrp.
|
||||||
|
*
|
||||||
|
* @param vrp
|
||||||
|
* @param algorithmConfig
|
||||||
|
* @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());
|
||||||
}
|
}
|
||||||
|
|
@ -368,6 +375,13 @@ public class VehicleRoutingAlgorithms {
|
||||||
return createAlgo(vrp,config);
|
return createAlgo(vrp,config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read and creates a {@link VehicleRoutingAlgorithm} from an url.
|
||||||
|
*
|
||||||
|
* @param vrp
|
||||||
|
* @param configURL
|
||||||
|
* @return {@link VehicleRoutingProblem}
|
||||||
|
*/
|
||||||
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final URL configURL){
|
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final URL configURL){
|
||||||
AlgorithmConfig algorithmConfig = new AlgorithmConfig();
|
AlgorithmConfig algorithmConfig = new AlgorithmConfig();
|
||||||
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
|
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
|
||||||
|
|
@ -375,6 +389,13 @@ public class VehicleRoutingAlgorithms {
|
||||||
return createAlgo(vrp,algorithmConfig.getXMLConfiguration());
|
return createAlgo(vrp,algorithmConfig.getXMLConfiguration());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read and creates {@link VehicleRoutingAlgorithm} from config-file.
|
||||||
|
*
|
||||||
|
* @param vrp
|
||||||
|
* @param configFileName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final String configFileName){
|
public static VehicleRoutingAlgorithm readAndCreateAlgorithm(final VehicleRoutingProblem vrp, final String configFileName){
|
||||||
AlgorithmConfig algorithmConfig = new AlgorithmConfig();
|
AlgorithmConfig algorithmConfig = new AlgorithmConfig();
|
||||||
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
|
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
|
||||||
|
|
@ -572,6 +593,7 @@ public class VehicleRoutingAlgorithms {
|
||||||
StrategyModuleKey strategyModuleKey = new StrategyModuleKey(modKey);
|
StrategyModuleKey strategyModuleKey = new StrategyModuleKey(modKey);
|
||||||
SearchStrategyModule definedModule = definedClasses.get(strategyModuleKey);
|
SearchStrategyModule definedModule = definedClasses.get(strategyModuleKey);
|
||||||
if(definedModule != null) return definedModule;
|
if(definedModule != null) return definedModule;
|
||||||
|
|
||||||
if(moduleName.equals("ruin_and_recreate")){
|
if(moduleName.equals("ruin_and_recreate")){
|
||||||
String ruin_name = moduleConfig.getString("ruin[@name]");
|
String ruin_name = moduleConfig.getString("ruin[@name]");
|
||||||
if(ruin_name == null) throw new IllegalStateException("module.ruin[@name] is missing.");
|
if(ruin_name == null) throw new IllegalStateException("module.ruin[@name] is missing.");
|
||||||
|
|
@ -586,7 +608,17 @@ public class VehicleRoutingAlgorithms {
|
||||||
ruin = getRandomRuin(vrp, activityStates, definedClasses, ruinKey, shareToRuin);
|
ruin = getRandomRuin(vrp, activityStates, definedClasses, ruinKey, shareToRuin);
|
||||||
}
|
}
|
||||||
else if(ruin_name.equals("radialRuin")){
|
else if(ruin_name.equals("radialRuin")){
|
||||||
ruin = getRadialRuin(vrp, activityStates, definedClasses, ruinKey, shareToRuin);
|
String ruin_distance = moduleConfig.getString("ruin.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'");
|
||||||
|
}
|
||||||
|
ruin = getRadialRuin(vrp, activityStates, definedClasses, ruinKey, shareToRuin, jobDistance);
|
||||||
}
|
}
|
||||||
else throw new IllegalStateException("ruin[@name] " + ruin_name + " is not known. Use either randomRuin or radialRuin.");
|
else throw new IllegalStateException("ruin[@name] " + ruin_name + " is not known. Use either randomRuin or radialRuin.");
|
||||||
|
|
||||||
|
|
@ -643,15 +675,16 @@ public class VehicleRoutingAlgorithms {
|
||||||
};
|
};
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
if(moduleName.equals("bestInsertion") || moduleName.equals("regretInsertion")){
|
|
||||||
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
// if(moduleName.equals("bestInsertion") || moduleName.equals("regretInsertion")){
|
||||||
AbstractInsertionStrategy insertion = getInsertionStrategy(moduleConfig, vrp, vehicleFleetManager, activityStates,
|
// List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||||
definedClasses, modKey, prioListeners);
|
// AbstractInsertionStrategy insertion = getInsertionStrategy(moduleConfig, vrp, vehicleFleetManager, activityStates,
|
||||||
SearchStrategyModule module = getModule(moduleName, insertion, vrp);
|
// definedClasses, modKey, prioListeners);
|
||||||
definedClasses.put(strategyModuleKey, module);
|
// SearchStrategyModule module = getModule(moduleName, insertion, vrp);
|
||||||
algorithmListeners.addAll(prioListeners);
|
// definedClasses.put(strategyModuleKey, module);
|
||||||
return module;
|
// algorithmListeners.addAll(prioListeners);
|
||||||
}
|
// return module;
|
||||||
|
// }
|
||||||
// if(moduleName.equals("regretInsertion")){
|
// if(moduleName.equals("regretInsertion")){
|
||||||
// List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
// List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||||
// AbstractInsertionKey insertionKey = new AbstractInsertionKey(modKey);
|
// AbstractInsertionKey insertionKey = new AbstractInsertionKey(modKey);
|
||||||
|
|
@ -664,20 +697,30 @@ public class VehicleRoutingAlgorithms {
|
||||||
// algorithmListeners.addAll(prioListeners);
|
// algorithmListeners.addAll(prioListeners);
|
||||||
// return module;
|
// return module;
|
||||||
// }
|
// }
|
||||||
if(moduleName.equals("randomRuin")){
|
// if(moduleName.equals("randomRuin")){
|
||||||
double shareToRuin = moduleConfig.getDouble("share");
|
// double shareToRuin = moduleConfig.getDouble("share");
|
||||||
RuinStrategy ruin = getRandomRuin(vrp, activityStates,definedClasses, modKey, shareToRuin);
|
// RuinStrategy ruin = getRandomRuin(vrp, activityStates,definedClasses, modKey, shareToRuin);
|
||||||
SearchStrategyModule module = getModule(moduleName, ruin);
|
// SearchStrategyModule module = getModule(moduleName, ruin);
|
||||||
definedClasses.put(strategyModuleKey, module);
|
// definedClasses.put(strategyModuleKey, module);
|
||||||
return module;
|
// return module;
|
||||||
}
|
// }
|
||||||
if(moduleName.equals("radialRuin")){
|
// if(moduleName.equals("radialRuin")){
|
||||||
double shareToRuin = moduleConfig.getDouble("share");
|
// double shareToRuin = moduleConfig.getDouble("share");
|
||||||
RuinStrategy ruin = getRadialRuin(vrp, activityStates,definedClasses, modKey, shareToRuin);
|
// String ruin_distance = moduleConfig.getString("distance");
|
||||||
SearchStrategyModule module = getModule(moduleName, ruin);
|
// JobDistance jobDistance;
|
||||||
definedClasses.put(strategyModuleKey, module);
|
// if(ruin_distance == null) jobDistance = new JobDistanceAvgCosts(vrp.getTransportCosts());
|
||||||
return module;
|
// 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");
|
||||||
|
|
@ -734,13 +777,11 @@ public class VehicleRoutingAlgorithms {
|
||||||
return bestInsertion;
|
return bestInsertion;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RuinStrategy getRadialRuin(VehicleRoutingProblem vrp,
|
private static RuinStrategy getRadialRuin(VehicleRoutingProblem vrp, RouteStates activityStates, TypedMap definedClasses, ModKey modKey, double shareToRuin, JobDistance jobDistance) {
|
||||||
RouteStates activityStates, TypedMap definedClasses,
|
|
||||||
ModKey modKey, double shareToRuin) {
|
|
||||||
RuinStrategyKey stratKey = new RuinStrategyKey(modKey);
|
RuinStrategyKey stratKey = new RuinStrategyKey(modKey);
|
||||||
RuinStrategy ruin = definedClasses.get(stratKey);
|
RuinStrategy ruin = definedClasses.get(stratKey);
|
||||||
if(ruin == null){
|
if(ruin == null){
|
||||||
ruin = RuinRadial.newInstance(vrp, shareToRuin, new JobDistanceAvgCosts(vrp.getTransportCosts()), new JobRemoverImpl(), new TourStateUpdater(activityStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
ruin = RuinRadial.newInstance(vrp, shareToRuin, jobDistance, new JobRemoverImpl(), new TourStateUpdater(activityStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
|
||||||
definedClasses.put(stratKey, ruin);
|
definedClasses.put(stratKey, ruin);
|
||||||
}
|
}
|
||||||
return ruin;
|
return ruin;
|
||||||
|
|
@ -778,12 +819,6 @@ public class VehicleRoutingAlgorithms {
|
||||||
double penalty = 0.0;
|
double penalty = 0.0;
|
||||||
if(jobsInSolution != vrp.getJobs().values().size()){
|
if(jobsInSolution != vrp.getJobs().values().size()){
|
||||||
throw new IllegalStateException("solution not valid\n" + "#jobsInSolution=" + jobsInSolution + " #jobsInVrp=" + vrp.getJobs().values().size());
|
throw new IllegalStateException("solution not valid\n" + "#jobsInSolution=" + jobsInSolution + " #jobsInVrp=" + vrp.getJobs().values().size());
|
||||||
// logger.warn("solution not valid\n" + "#jobsInSolution=" + jobsInSolution + " #jobsInVrp=" + vrp.getJobs().values().size());
|
|
||||||
//// throw new IllegalStateException("solution not valid\n" +
|
|
||||||
//// "#jobsInSolution=" + jobsInSolution + " #jobsInVrp=" + vrp.getJobs().values().size());
|
|
||||||
// logger.warn("a penalty of 1000 is added for each unassigned customer");
|
|
||||||
// penalty = (vrp.getJobs().values().size() - jobsInSolution)*1000.0;
|
|
||||||
// logger.warn("penalty = " + penalty);
|
|
||||||
}
|
}
|
||||||
double totalCost = RouteUtils.getTotalCost(vrpSolution.getRoutes());
|
double totalCost = RouteUtils.getTotalCost(vrpSolution.getRoutes());
|
||||||
vrpSolution.setCost(totalCost + penalty);
|
vrpSolution.setCost(totalCost + penalty);
|
||||||
|
|
@ -841,37 +876,37 @@ public class VehicleRoutingAlgorithms {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SearchStrategyModule getModule(final String moduleName, final RuinStrategy ruin) {
|
// private static SearchStrategyModule getModule(final String moduleName, final RuinStrategy ruin) {
|
||||||
|
//
|
||||||
|
//
|
||||||
return new SearchStrategyModule() {
|
// return new SearchStrategyModule() {
|
||||||
|
//
|
||||||
private Logger logger = Logger.getLogger(SearchStrategyModule.class);
|
// private Logger logger = Logger.getLogger(SearchStrategyModule.class);
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) {
|
// public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) {
|
||||||
ruin.ruin(vrpSolution.getRoutes());
|
// ruin.ruin(vrpSolution.getRoutes());
|
||||||
return vrpSolution;
|
// return vrpSolution;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public String toString() {
|
// public String toString() {
|
||||||
return "[name="+ruin+"]";
|
// return "[name="+ruin+"]";
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public String getName() {
|
// public String getName() {
|
||||||
return moduleName;
|
// return moduleName;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void addModuleListener(SearchStrategyModuleListener moduleListener) {
|
// public void addModuleListener(SearchStrategyModuleListener moduleListener) {
|
||||||
// TODO Auto-generated method stub
|
// // TODO Auto-generated method stub
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -242,6 +242,12 @@ public class VehicleRoutingProblem {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the neighborhood.
|
||||||
|
*
|
||||||
|
* @param neighborhood
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public Builder setNeighborhood(Neighborhood neighborhood){
|
public Builder setNeighborhood(Neighborhood neighborhood){
|
||||||
this.neighborhood = neighborhood;
|
this.neighborhood = neighborhood;
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -261,6 +267,13 @@ public class VehicleRoutingProblem {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the {@link VehicleRoutingProblem}.
|
||||||
|
*
|
||||||
|
* <p>If {@link VehicleRoutingTransportCosts} are not set, {@link CrowFlyCosts} is used.
|
||||||
|
*
|
||||||
|
* @return {@link VehicleRoutingProblem}
|
||||||
|
*/
|
||||||
public VehicleRoutingProblem build() {
|
public VehicleRoutingProblem build() {
|
||||||
log.info("build problem ...");
|
log.info("build problem ...");
|
||||||
if(transportCosts == null){
|
if(transportCosts == null){
|
||||||
|
|
@ -275,6 +288,12 @@ public class VehicleRoutingProblem {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a collection of jobs.
|
||||||
|
*
|
||||||
|
* @param jobs
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public Builder addAllJobs(Collection<Job> jobs) {
|
public Builder addAllJobs(Collection<Job> jobs) {
|
||||||
for(Job j : jobs){
|
for(Job j : jobs){
|
||||||
addJob(j);
|
addJob(j);
|
||||||
|
|
@ -282,6 +301,12 @@ public class VehicleRoutingProblem {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a collection of vehicles.
|
||||||
|
*
|
||||||
|
* @param vehicles
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public Builder addAllVehicles(Collection<Vehicle> vehicles) {
|
public Builder addAllVehicles(Collection<Vehicle> vehicles) {
|
||||||
for(Vehicle v : vehicles){
|
for(Vehicle v : vehicles){
|
||||||
addVehicle(v);
|
addVehicle(v);
|
||||||
|
|
@ -289,11 +314,20 @@ public class VehicleRoutingProblem {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an unmodifiable collection of already added vehicles.
|
||||||
|
*
|
||||||
|
* @return collection of vehicles
|
||||||
|
*/
|
||||||
public Collection<Vehicle> getAddedVehicles(){
|
public Collection<Vehicle> getAddedVehicles(){
|
||||||
return Collections.unmodifiableCollection(vehicles);
|
return Collections.unmodifiableCollection(vehicles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an unmodifiable collection of already added services.
|
||||||
|
*
|
||||||
|
* @return collection of services
|
||||||
|
*/
|
||||||
public Collection<Service> getAddedServices(){
|
public Collection<Service> getAddedServices(){
|
||||||
return Collections.unmodifiableCollection(services);
|
return Collections.unmodifiableCollection(services);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@
|
||||||
|
|
||||||
<xs:complexType name="ruinType">
|
<xs:complexType name="ruinType">
|
||||||
<xs:sequence>
|
<xs:sequence>
|
||||||
<xs:element name="share">
|
<xs:element name="share" minOccurs="1" maxOccurs="1">
|
||||||
<xs:simpleType>
|
<xs:simpleType>
|
||||||
<xs:restriction base="xs:double">
|
<xs:restriction base="xs:double">
|
||||||
<xs:minInclusive value="0.0"/>
|
<xs:minInclusive value="0.0"/>
|
||||||
|
|
@ -143,6 +143,13 @@
|
||||||
</xs:restriction>
|
</xs:restriction>
|
||||||
</xs:simpleType>
|
</xs:simpleType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element name="distance" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:simpleType>
|
||||||
|
<xs:restriction base="xs:string">
|
||||||
|
<xs:enumeration value="euclidean"/>
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
</xs:element>
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
<xs:attribute name="name" use="required">
|
<xs:attribute name="name" use="required">
|
||||||
<xs:simpleType>
|
<xs:simpleType>
|
||||||
|
|
|
||||||
|
|
@ -230,43 +230,7 @@ public class TestAlgorithmReader {
|
||||||
for(SearchStrategy strat : algo.getSearchStrategyManager().getStrategies()){
|
for(SearchStrategy strat : algo.getSearchStrategyManager().getStrategies()){
|
||||||
nOfModules += strat.getSearchStrategyModules().size();
|
nOfModules += strat.getSearchStrategyModules().size();
|
||||||
}
|
}
|
||||||
assertEquals(6, nOfModules);
|
assertEquals(3, nOfModules);
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenCreatingAlgorithm_nOfUniqueInstancesOfInsertionModulesIsCorrect(){
|
|
||||||
VehicleRoutingAlgorithm algo = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, config);
|
|
||||||
int nOfBestInsertions = 0;
|
|
||||||
Set<SearchStrategyModule> uniqueStrategies = new HashSet<SearchStrategyModule>();
|
|
||||||
for(SearchStrategy strat : algo.getSearchStrategyManager().getStrategies()){
|
|
||||||
for(SearchStrategyModule module : strat.getSearchStrategyModules()){
|
|
||||||
if(module.getName().equals("bestInsertion")){
|
|
||||||
nOfBestInsertions++;
|
|
||||||
uniqueStrategies.add(module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
assertEquals(3, nOfBestInsertions);
|
|
||||||
assertEquals(2, uniqueStrategies.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenCreatingAlgorithm_nOfUniqueInstancesOfRuinModulesIsCorrect(){
|
|
||||||
VehicleRoutingAlgorithm algo = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, config);
|
|
||||||
int nOfRuinModules = 0;
|
|
||||||
Set<SearchStrategyModule> uniqueStrategies = new HashSet<SearchStrategyModule>();
|
|
||||||
for(SearchStrategy strat : algo.getSearchStrategyManager().getStrategies()){
|
|
||||||
for(SearchStrategyModule module : strat.getSearchStrategyModules()){
|
|
||||||
if(module.getName().endsWith("Ruin")){
|
|
||||||
nOfRuinModules++;
|
|
||||||
uniqueStrategies.add(module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
assertEquals(3, nOfRuinModules);
|
|
||||||
assertEquals(2, uniqueStrategies.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,11 @@
|
||||||
<selector name="selectBest"/>
|
<selector name="selectBest"/>
|
||||||
<acceptor name="acceptNewRemoveWorst"/>
|
<acceptor name="acceptNewRemoveWorst"/>
|
||||||
<modules>
|
<modules>
|
||||||
<module name="randomRuin">
|
<module name="ruin_and_recreate">
|
||||||
|
<ruin name="randomRuin">
|
||||||
<share>0.5</share>
|
<share>0.5</share>
|
||||||
</module>
|
</ruin>
|
||||||
<module name="bestInsertion">
|
<insertion name="bestInsertion"/>
|
||||||
</module>
|
</module>
|
||||||
</modules>
|
</modules>
|
||||||
<probability>0.4</probability>
|
<probability>0.4</probability>
|
||||||
|
|
@ -47,10 +48,12 @@
|
||||||
<selector name="selectBest"/>
|
<selector name="selectBest"/>
|
||||||
<acceptor name="acceptNewRemoveWorst"/>
|
<acceptor name="acceptNewRemoveWorst"/>
|
||||||
<modules>
|
<modules>
|
||||||
<module name="randomRuin">
|
<module name="ruin_and_recreate">
|
||||||
|
<ruin name="randomRuin">
|
||||||
<share>0.1</share>
|
<share>0.1</share>
|
||||||
|
</ruin>
|
||||||
|
<insertion name="bestInsertion"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="bestInsertion"></module>
|
|
||||||
</modules>
|
</modules>
|
||||||
<probability>0.4</probability>
|
<probability>0.4</probability>
|
||||||
</searchStrategy>
|
</searchStrategy>
|
||||||
|
|
@ -59,11 +62,12 @@
|
||||||
<selector name="selectBest"/>
|
<selector name="selectBest"/>
|
||||||
<acceptor name="acceptNewRemoveWorst"/>
|
<acceptor name="acceptNewRemoveWorst"/>
|
||||||
<modules>
|
<modules>
|
||||||
<module name="radialRuin">
|
<module name="ruin_and_recreate">
|
||||||
|
<ruin name="radialRuin">
|
||||||
<share>0.3</share>
|
<share>0.3</share>
|
||||||
<distanceMeasure>euclid</distanceMeasure>
|
</ruin>
|
||||||
|
<insertion name="bestInsertion" id="1"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="bestInsertion" id="1"></module>
|
|
||||||
</modules>
|
</modules>
|
||||||
<probability>0.2</probability>
|
<probability>0.2</probability>
|
||||||
</searchStrategy>
|
</searchStrategy>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue