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;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import basics.Job;
|
||||
import basics.Service;
|
||||
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 {
|
||||
|
||||
private static Logger log = Logger.getLogger(JobDistanceAvgCosts.class);
|
||||
|
||||
private 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
|
||||
public double calculateDistance(Job i, Job j) {
|
||||
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.equals(j)) {
|
||||
avgCost = 0.0;
|
||||
} else {
|
||||
Service s_i = (Service) i;
|
||||
Service s_j = (Service) j;
|
||||
avgCost = calcDist(s_i.getLocationId(), s_j.getLocationId());
|
||||
avgCost = calcDist(s_i, s_j);
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedOperationException(
|
||||
|
|
@ -59,8 +62,18 @@ class JobDistanceAvgCosts implements JobDistance {
|
|||
return avgCost;
|
||||
}
|
||||
|
||||
private double calcDist(String from, String to) {
|
||||
return costs.getTransportCost(from, to, 0.0, null, null);
|
||||
private double calcDist(Service s_i, Service s_j) {
|
||||
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
|
||||
public double calculateDistance(Job i, Job j) {
|
||||
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.equals(j)) {
|
||||
avgCost = 0.0;
|
||||
|
|
|
|||
|
|
@ -359,6 +359,13 @@ public class 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){
|
||||
return createAlgo(vrp,algorithmConfig.getXMLConfiguration());
|
||||
}
|
||||
|
|
@ -368,6 +375,13 @@ public class VehicleRoutingAlgorithms {
|
|||
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){
|
||||
AlgorithmConfig algorithmConfig = new AlgorithmConfig();
|
||||
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
|
||||
|
|
@ -375,6 +389,13 @@ public class VehicleRoutingAlgorithms {
|
|||
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){
|
||||
AlgorithmConfig algorithmConfig = new AlgorithmConfig();
|
||||
AlgorithmConfigXmlReader xmlReader = new AlgorithmConfigXmlReader(algorithmConfig);
|
||||
|
|
@ -572,6 +593,7 @@ public class VehicleRoutingAlgorithms {
|
|||
StrategyModuleKey strategyModuleKey = new StrategyModuleKey(modKey);
|
||||
SearchStrategyModule definedModule = definedClasses.get(strategyModuleKey);
|
||||
if(definedModule != null) return definedModule;
|
||||
|
||||
if(moduleName.equals("ruin_and_recreate")){
|
||||
String ruin_name = moduleConfig.getString("ruin[@name]");
|
||||
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);
|
||||
}
|
||||
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.");
|
||||
|
||||
|
|
@ -643,15 +675,16 @@ public class VehicleRoutingAlgorithms {
|
|||
};
|
||||
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("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);
|
||||
|
|
@ -664,20 +697,30 @@ public class VehicleRoutingAlgorithms {
|
|||
// 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");
|
||||
RuinStrategy ruin = getRadialRuin(vrp, activityStates,definedClasses, modKey, shareToRuin);
|
||||
SearchStrategyModule module = getModule(moduleName, ruin);
|
||||
definedClasses.put(strategyModuleKey, module);
|
||||
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")){
|
||||
int iterations = moduleConfig.getInt("iterations");
|
||||
double share = moduleConfig.getDouble("share");
|
||||
|
|
@ -734,13 +777,11 @@ public class VehicleRoutingAlgorithms {
|
|||
return bestInsertion;
|
||||
}
|
||||
|
||||
private static RuinStrategy getRadialRuin(VehicleRoutingProblem vrp,
|
||||
RouteStates activityStates, TypedMap definedClasses,
|
||||
ModKey modKey, double shareToRuin) {
|
||||
private static RuinStrategy getRadialRuin(VehicleRoutingProblem vrp, RouteStates activityStates, TypedMap definedClasses, ModKey modKey, double shareToRuin, JobDistance jobDistance) {
|
||||
RuinStrategyKey stratKey = new RuinStrategyKey(modKey);
|
||||
RuinStrategy ruin = definedClasses.get(stratKey);
|
||||
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);
|
||||
}
|
||||
return ruin;
|
||||
|
|
@ -778,12 +819,6 @@ public class VehicleRoutingAlgorithms {
|
|||
double penalty = 0.0;
|
||||
if(jobsInSolution != 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());
|
||||
vrpSolution.setCost(totalCost + penalty);
|
||||
|
|
@ -841,37 +876,37 @@ public class VehicleRoutingAlgorithms {
|
|||
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
// 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
|
||||
//
|
||||
// }
|
||||
//
|
||||
// };
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -242,6 +242,12 @@ public class VehicleRoutingProblem {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the neighborhood.
|
||||
*
|
||||
* @param neighborhood
|
||||
* @return
|
||||
*/
|
||||
public Builder setNeighborhood(Neighborhood neighborhood){
|
||||
this.neighborhood = neighborhood;
|
||||
return this;
|
||||
|
|
@ -261,6 +267,13 @@ public class VehicleRoutingProblem {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link VehicleRoutingProblem}.
|
||||
*
|
||||
* <p>If {@link VehicleRoutingTransportCosts} are not set, {@link CrowFlyCosts} is used.
|
||||
*
|
||||
* @return {@link VehicleRoutingProblem}
|
||||
*/
|
||||
public VehicleRoutingProblem build() {
|
||||
log.info("build problem ...");
|
||||
if(transportCosts == null){
|
||||
|
|
@ -275,6 +288,12 @@ public class VehicleRoutingProblem {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a collection of jobs.
|
||||
*
|
||||
* @param jobs
|
||||
* @return
|
||||
*/
|
||||
public Builder addAllJobs(Collection<Job> jobs) {
|
||||
for(Job j : jobs){
|
||||
addJob(j);
|
||||
|
|
@ -282,6 +301,12 @@ public class VehicleRoutingProblem {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a collection of vehicles.
|
||||
*
|
||||
* @param vehicles
|
||||
* @return
|
||||
*/
|
||||
public Builder addAllVehicles(Collection<Vehicle> vehicles) {
|
||||
for(Vehicle v : vehicles){
|
||||
addVehicle(v);
|
||||
|
|
@ -289,11 +314,20 @@ public class VehicleRoutingProblem {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets an unmodifiable collection of already added vehicles.
|
||||
*
|
||||
* @return collection of vehicles
|
||||
*/
|
||||
public Collection<Vehicle> getAddedVehicles(){
|
||||
return Collections.unmodifiableCollection(vehicles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an unmodifiable collection of already added services.
|
||||
*
|
||||
* @return collection of services
|
||||
*/
|
||||
public Collection<Service> getAddedServices(){
|
||||
return Collections.unmodifiableCollection(services);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@
|
|||
|
||||
<xs:complexType name="ruinType">
|
||||
<xs:sequence>
|
||||
<xs:element name="share">
|
||||
<xs:element name="share" minOccurs="1" maxOccurs="1">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:double">
|
||||
<xs:minInclusive value="0.0"/>
|
||||
|
|
@ -143,6 +143,13 @@
|
|||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</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:attribute name="name" use="required">
|
||||
<xs:simpleType>
|
||||
|
|
|
|||
|
|
@ -230,43 +230,7 @@ public class TestAlgorithmReader {
|
|||
for(SearchStrategy strat : algo.getSearchStrategyManager().getStrategies()){
|
||||
nOfModules += strat.getSearchStrategyModules().size();
|
||||
}
|
||||
assertEquals(6, 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());
|
||||
assertEquals(3, nOfModules);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -34,10 +34,11 @@
|
|||
<selector name="selectBest"/>
|
||||
<acceptor name="acceptNewRemoveWorst"/>
|
||||
<modules>
|
||||
<module name="randomRuin">
|
||||
<share>0.5</share>
|
||||
</module>
|
||||
<module name="bestInsertion">
|
||||
<module name="ruin_and_recreate">
|
||||
<ruin name="randomRuin">
|
||||
<share>0.5</share>
|
||||
</ruin>
|
||||
<insertion name="bestInsertion"/>
|
||||
</module>
|
||||
</modules>
|
||||
<probability>0.4</probability>
|
||||
|
|
@ -47,10 +48,12 @@
|
|||
<selector name="selectBest"/>
|
||||
<acceptor name="acceptNewRemoveWorst"/>
|
||||
<modules>
|
||||
<module name="randomRuin">
|
||||
<share>0.1</share>
|
||||
<module name="ruin_and_recreate">
|
||||
<ruin name="randomRuin">
|
||||
<share>0.1</share>
|
||||
</ruin>
|
||||
<insertion name="bestInsertion"/>
|
||||
</module>
|
||||
<module name="bestInsertion"></module>
|
||||
</modules>
|
||||
<probability>0.4</probability>
|
||||
</searchStrategy>
|
||||
|
|
@ -59,11 +62,12 @@
|
|||
<selector name="selectBest"/>
|
||||
<acceptor name="acceptNewRemoveWorst"/>
|
||||
<modules>
|
||||
<module name="radialRuin">
|
||||
<share>0.3</share>
|
||||
<distanceMeasure>euclid</distanceMeasure>
|
||||
<module name="ruin_and_recreate">
|
||||
<ruin name="radialRuin">
|
||||
<share>0.3</share>
|
||||
</ruin>
|
||||
<insertion name="bestInsertion" id="1"/>
|
||||
</module>
|
||||
<module name="bestInsertion" id="1"></module>
|
||||
</modules>
|
||||
<probability>0.2</probability>
|
||||
</searchStrategy>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue