mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
add and test new (ready-to-use) algorithm
This commit is contained in:
parent
6f1d65e2e9
commit
1a63178e05
3 changed files with 805 additions and 0 deletions
|
|
@ -0,0 +1,88 @@
|
||||||
|
package jsprit.core.algorithm.box;
|
||||||
|
|
||||||
|
import jsprit.core.algorithm.listener.IterationStartsListener;
|
||||||
|
import jsprit.core.problem.Location;
|
||||||
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import jsprit.core.problem.constraint.SoftActivityConstraint;
|
||||||
|
import jsprit.core.problem.job.Job;
|
||||||
|
import jsprit.core.problem.job.Service;
|
||||||
|
import jsprit.core.problem.job.Shipment;
|
||||||
|
import jsprit.core.problem.misc.JobInsertionContext;
|
||||||
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||||
|
import jsprit.core.util.RandomNumberGeneration;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 16/01/15.
|
||||||
|
*/
|
||||||
|
class InsertionNoiseMaker implements SoftActivityConstraint, IterationStartsListener {
|
||||||
|
|
||||||
|
private final double noiseProbability;
|
||||||
|
|
||||||
|
private boolean makeNoise = false;
|
||||||
|
|
||||||
|
private VehicleRoutingProblem vrp;
|
||||||
|
|
||||||
|
double maxCosts = 0.;
|
||||||
|
|
||||||
|
private double noiseLevel = 0.1;
|
||||||
|
|
||||||
|
|
||||||
|
public InsertionNoiseMaker(VehicleRoutingProblem vrp, double noiseLevel, double noiseProbability) {
|
||||||
|
this.vrp = vrp;
|
||||||
|
this.noiseLevel = noiseLevel;
|
||||||
|
this.noiseProbability = noiseProbability;
|
||||||
|
determineMaxCosts(vrp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void determineMaxCosts(VehicleRoutingProblem vrp) {
|
||||||
|
double max = 0.;
|
||||||
|
for(Job i : vrp.getJobs().values()){
|
||||||
|
List<Location> fromLocations = getLocations(i);
|
||||||
|
for(Job j : vrp.getJobs().values()){
|
||||||
|
List<Location> toLocations = getLocations(j);
|
||||||
|
for(Location iLoc : fromLocations){
|
||||||
|
for(Location jLoc : toLocations) {
|
||||||
|
max = Math.max(max, vrp.getTransportCosts().getTransportCost(iLoc, jLoc, 0, null, vrp.getVehicles().iterator().next()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maxCosts = max;
|
||||||
|
System.out.println("maxNoise="+maxCosts);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Location> getLocations(Job j) {
|
||||||
|
List<Location> locs = new ArrayList<Location>();
|
||||||
|
if(j instanceof Service) {
|
||||||
|
locs.add(((Service) j).getLocation());
|
||||||
|
}
|
||||||
|
else if(j instanceof Shipment){
|
||||||
|
locs.add(((Shipment) j).getPickupLocation());
|
||||||
|
locs.add(((Shipment) j).getDeliveryLocation());
|
||||||
|
}
|
||||||
|
return locs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||||
|
if(RandomNumberGeneration.getRandom().nextDouble() < noiseProbability){
|
||||||
|
makeNoise = true;
|
||||||
|
}
|
||||||
|
else makeNoise = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getCosts(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||||
|
if(makeNoise) {
|
||||||
|
return noiseLevel * maxCosts * RandomNumberGeneration.getRandom().nextDouble();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
504
jsprit-core/src/main/java/jsprit/core/algorithm/box/Jsprit.java
Normal file
504
jsprit-core/src/main/java/jsprit/core/algorithm/box/Jsprit.java
Normal file
|
|
@ -0,0 +1,504 @@
|
||||||
|
package jsprit.core.algorithm.box;
|
||||||
|
|
||||||
|
import jsprit.core.algorithm.PrettyAlgorithmBuilder;
|
||||||
|
import jsprit.core.algorithm.SearchStrategy;
|
||||||
|
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||||
|
import jsprit.core.algorithm.acceptor.SchrimpfAcceptance;
|
||||||
|
import jsprit.core.algorithm.listener.AlgorithmEndsListener;
|
||||||
|
import jsprit.core.algorithm.listener.IterationStartsListener;
|
||||||
|
import jsprit.core.algorithm.module.RuinAndRecreateModule;
|
||||||
|
import jsprit.core.algorithm.recreate.*;
|
||||||
|
import jsprit.core.algorithm.ruin.*;
|
||||||
|
import jsprit.core.algorithm.ruin.distance.AvgServiceAndShipmentDistance;
|
||||||
|
import jsprit.core.algorithm.selector.SelectBest;
|
||||||
|
import jsprit.core.algorithm.state.StateManager;
|
||||||
|
import jsprit.core.analysis.SolutionAnalyser;
|
||||||
|
import jsprit.core.problem.Location;
|
||||||
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import jsprit.core.problem.constraint.ConstraintManager;
|
||||||
|
import jsprit.core.problem.cost.TransportDistance;
|
||||||
|
import jsprit.core.problem.solution.SolutionCostCalculator;
|
||||||
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
import jsprit.core.problem.vehicle.FiniteFleetManagerFactory;
|
||||||
|
import jsprit.core.problem.vehicle.InfiniteFleetManagerFactory;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleFleetManager;
|
||||||
|
import jsprit.core.util.NoiseMaker;
|
||||||
|
import jsprit.core.util.RandomNumberGeneration;
|
||||||
|
import jsprit.core.util.Solutions;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 06/01/15.
|
||||||
|
*/
|
||||||
|
public class Jsprit {
|
||||||
|
|
||||||
|
public enum Strategy {
|
||||||
|
|
||||||
|
RADIAL_BEST("radial_best"),
|
||||||
|
RADIAL_REGRET("radial_regret"),
|
||||||
|
RANDOM_BEST("random_best"),
|
||||||
|
RANDOM_REGRET("random_regret"),
|
||||||
|
WORST_BEST("worst_best"),
|
||||||
|
WORST_REGRET("worst_regret"),
|
||||||
|
CLUSTER_BEST("cluster_best"),
|
||||||
|
CLUSTER_REGRET("cluster_regret");
|
||||||
|
|
||||||
|
String strategyName;
|
||||||
|
|
||||||
|
Strategy(String strategyName){
|
||||||
|
this.strategyName = strategyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(){
|
||||||
|
return strategyName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Parameter {
|
||||||
|
|
||||||
|
FIXED_COST_PARAM("fixed_cost_param"), VEHICLE_SWITCH("vehicle_switch"), REGRET_TIME_WINDOW_SCORER("regret.tw_scorer"),
|
||||||
|
REGRET_DISTANCE_SCORER("regret.distance_scorer"), INITIAL_THRESHOLD("initial_threshold"), ITERATIONS("iterations"),
|
||||||
|
THREADS("threads"),
|
||||||
|
RANDOM_REGRET_MIN_SHARE("random_regret.min_share"),
|
||||||
|
RANDOM_REGRET_MAX_SHARE("random_regret.max_share"),
|
||||||
|
RANDOM_BEST_MIN_SHARE("random_best.min_share"),
|
||||||
|
RANDOM_BEST_MAX_SHARE("random_best.max_share"),
|
||||||
|
RADIAL_MIN_SHARE("radial.min_share"),
|
||||||
|
RADIAL_MAX_SHARE("radial.max_share"),
|
||||||
|
CLUSTER_MIN_SHARE("cluster.min_share"),
|
||||||
|
CLUSTER_MAX_SHARE("cluster.max_share"),
|
||||||
|
WORST_MIN_SHARE("worst.min_share"),
|
||||||
|
WORST_MAX_SHARE("worst.max_share"),
|
||||||
|
THRESHOLD_ALPHA("threshold.alpha"),
|
||||||
|
THRESHOLD_INI("threshold.ini"),
|
||||||
|
INSERTION_NOISE_LEVEL("insertion.noise_level"),
|
||||||
|
INSERTION_NOISE_PROB("insertion.noise_prob"),
|
||||||
|
RUIN_WORST_NOISE_LEVEL("worst.noise_level"),
|
||||||
|
RUIN_WORST_NOISE_PROB("worst.noise_prob");
|
||||||
|
|
||||||
|
String paraName;
|
||||||
|
|
||||||
|
Parameter(String name){
|
||||||
|
this.paraName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(){
|
||||||
|
return paraName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vehicleRoutingProblem){
|
||||||
|
return Jsprit.Builder.newInstance(vehicleRoutingProblem).buildAlgorithm();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
private VehicleRoutingProblem vrp;
|
||||||
|
|
||||||
|
private ExecutorService es;
|
||||||
|
|
||||||
|
private Integer noThreads;
|
||||||
|
|
||||||
|
private StateManager stateManager = null;
|
||||||
|
|
||||||
|
private ConstraintManager constraintManager = null;
|
||||||
|
|
||||||
|
private SolutionCostCalculator objectiveFunction = null;
|
||||||
|
|
||||||
|
private Properties properties;
|
||||||
|
|
||||||
|
private boolean addConstraints = true;
|
||||||
|
|
||||||
|
public static Builder newInstance(VehicleRoutingProblem vrp){
|
||||||
|
return new Builder(vrp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(VehicleRoutingProblem vrp){
|
||||||
|
this.vrp = vrp;
|
||||||
|
properties = new Properties(createDefaultProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties createDefaultProperties() {
|
||||||
|
Properties defaults = new Properties();
|
||||||
|
defaults.put(Strategy.RADIAL_BEST.toString(),"0.");
|
||||||
|
defaults.put(Strategy.RADIAL_REGRET.toString(),".5");
|
||||||
|
defaults.put(Strategy.RANDOM_BEST.toString(),".5");
|
||||||
|
defaults.put(Strategy.RANDOM_REGRET.toString(),".5");
|
||||||
|
defaults.put(Strategy.WORST_BEST.toString(),"0.");
|
||||||
|
defaults.put(Strategy.WORST_REGRET.toString(),"1.");
|
||||||
|
defaults.put(Strategy.CLUSTER_BEST.toString(),"0.");
|
||||||
|
defaults.put(Strategy.CLUSTER_REGRET.toString(),"1.");
|
||||||
|
defaults.put(Parameter.FIXED_COST_PARAM.toString(),"0.");
|
||||||
|
defaults.put(Parameter.VEHICLE_SWITCH.toString(),"true");
|
||||||
|
defaults.put(Parameter.ITERATIONS.toString(),"2000");
|
||||||
|
defaults.put(Parameter.REGRET_DISTANCE_SCORER.toString(),".05");
|
||||||
|
defaults.put(Parameter.REGRET_TIME_WINDOW_SCORER.toString(),"-.1");
|
||||||
|
defaults.put(Parameter.THREADS.toString(),"1");
|
||||||
|
int minShare = (int)Math.min(20, Math.max(3,vrp.getJobs().size() * 0.05));
|
||||||
|
int maxShare = (int)Math.min(50, Math.max(5,vrp.getJobs().size() * 0.3));
|
||||||
|
defaults.put(Parameter.RADIAL_MIN_SHARE.toString(),String.valueOf(minShare));
|
||||||
|
defaults.put(Parameter.RADIAL_MAX_SHARE.toString(),String.valueOf(maxShare));
|
||||||
|
defaults.put(Parameter.WORST_MIN_SHARE.toString(),String.valueOf(minShare));
|
||||||
|
defaults.put(Parameter.WORST_MAX_SHARE.toString(),String.valueOf(maxShare));
|
||||||
|
defaults.put(Parameter.CLUSTER_MIN_SHARE.toString(),String.valueOf(minShare));
|
||||||
|
defaults.put(Parameter.CLUSTER_MAX_SHARE.toString(),String.valueOf(maxShare));
|
||||||
|
int minShare_ = (int)Math.min(70, Math.max(5,vrp.getJobs().size() * 0.5));
|
||||||
|
int maxShare_ = (int)Math.min(70, Math.max(5,vrp.getJobs().size() * 0.5));
|
||||||
|
defaults.put(Parameter.RANDOM_REGRET_MIN_SHARE.toString(),String.valueOf(minShare_));
|
||||||
|
defaults.put(Parameter.RANDOM_REGRET_MAX_SHARE.toString(),String.valueOf(maxShare_));
|
||||||
|
defaults.put(Parameter.RANDOM_BEST_MIN_SHARE.toString(),String.valueOf(minShare_));
|
||||||
|
defaults.put(Parameter.RANDOM_BEST_MAX_SHARE.toString(),String.valueOf(maxShare_));
|
||||||
|
defaults.put(Parameter.THRESHOLD_ALPHA.toString(),String.valueOf(0.15));
|
||||||
|
defaults.put(Parameter.THRESHOLD_INI.toString(),String.valueOf(0.03));
|
||||||
|
defaults.put(Parameter.INSERTION_NOISE_LEVEL.toString(),String.valueOf(0.15));
|
||||||
|
defaults.put(Parameter.INSERTION_NOISE_PROB.toString(),String.valueOf(0.2));
|
||||||
|
defaults.put(Parameter.RUIN_WORST_NOISE_LEVEL.toString(),String.valueOf(0.15));
|
||||||
|
defaults.put(Parameter.RUIN_WORST_NOISE_PROB.toString(),String.valueOf(0.2));
|
||||||
|
defaults.put(Parameter.VEHICLE_SWITCH.toString(),String.valueOf(true));
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Builder setExecutorService(ExecutorService es, int noThreads) {
|
||||||
|
this.es = es;
|
||||||
|
this.noThreads = noThreads;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setProperty(String key, String value){
|
||||||
|
properties.put(key,value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setProperty(Parameter parameter, String value){
|
||||||
|
setProperty(parameter.toString(),value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setProperty(Strategy strategy, String value){
|
||||||
|
setProperty(strategy.toString(),value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setStateAndConstraintManager(StateManager stateManager, ConstraintManager constraintManager) {
|
||||||
|
this.stateManager = stateManager;
|
||||||
|
this.constraintManager = constraintManager;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setObjectiveFunction(SolutionCostCalculator objectiveFunction) {
|
||||||
|
this.objectiveFunction = objectiveFunction;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder addCoreStateAndConstraintStuff(boolean addConstraints) {
|
||||||
|
this.addConstraints = addConstraints;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VehicleRoutingAlgorithm buildAlgorithm(){
|
||||||
|
return new Jsprit(this).create(vrp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class RuinShareFactoryImpl implements RuinShareFactory
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
private int maxShare;
|
||||||
|
|
||||||
|
private int minShare;
|
||||||
|
|
||||||
|
public RuinShareFactoryImpl(int minShare, int maxShare) {
|
||||||
|
if(maxShare < minShare) throw new IllegalArgumentException("maxShare must be equal or greater than minShare");
|
||||||
|
this.minShare = minShare;
|
||||||
|
this.maxShare = maxShare;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int createNumberToBeRemoved() {
|
||||||
|
return (int) (minShare + (maxShare - minShare) * RandomNumberGeneration.getRandom().nextDouble());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private StateManager stateManager = null;
|
||||||
|
|
||||||
|
private ConstraintManager constraintManager = null;
|
||||||
|
|
||||||
|
private ExecutorService es = null;
|
||||||
|
|
||||||
|
private Integer noThreads;
|
||||||
|
|
||||||
|
private boolean setupExecutorInternally = false;
|
||||||
|
|
||||||
|
private boolean addCoreConstraints;
|
||||||
|
|
||||||
|
private Properties properties;
|
||||||
|
|
||||||
|
private Jsprit(Builder builder) {
|
||||||
|
this.stateManager = builder.stateManager;
|
||||||
|
this.constraintManager = builder.constraintManager;
|
||||||
|
this.es = builder.es;
|
||||||
|
this.noThreads = builder.noThreads;
|
||||||
|
this.addCoreConstraints = builder.addConstraints;
|
||||||
|
this.properties = builder.properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private VehicleRoutingAlgorithm create(final VehicleRoutingProblem vrp){
|
||||||
|
VehicleFleetManager fm;
|
||||||
|
if(vrp.getFleetSize().equals(VehicleRoutingProblem.FleetSize.INFINITE)){
|
||||||
|
fm = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||||
|
}
|
||||||
|
else fm = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||||
|
|
||||||
|
if(stateManager == null){
|
||||||
|
stateManager = new StateManager(vrp);
|
||||||
|
}
|
||||||
|
if(constraintManager == null){
|
||||||
|
constraintManager = new ConstraintManager(vrp,stateManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
double noiseLevel = toDouble(getProperty(Parameter.INSERTION_NOISE_LEVEL.toString()));
|
||||||
|
double noiseProbability = toDouble(getProperty(Parameter.INSERTION_NOISE_PROB.toString()));
|
||||||
|
final InsertionNoiseMaker noiseMaker = new InsertionNoiseMaker(vrp, noiseLevel, noiseProbability);
|
||||||
|
constraintManager.addConstraint(noiseMaker);
|
||||||
|
|
||||||
|
JobNeighborhoods jobNeighborhoods = new JobNeighborhoodsFactory().createNeighborhoods(vrp, new AvgServiceAndShipmentDistance(vrp.getTransportCosts()), (int) (vrp.getJobs().values().size() * 0.5));
|
||||||
|
jobNeighborhoods.initialise();
|
||||||
|
|
||||||
|
RuinRadial radial = new RuinRadial(vrp,vrp.getJobs().size(),jobNeighborhoods);
|
||||||
|
radial.setRuinShareFactory(new RuinShareFactoryImpl(
|
||||||
|
toInteger(properties.getProperty(Parameter.RADIAL_MIN_SHARE.toString())),
|
||||||
|
toInteger(properties.getProperty(Parameter.RADIAL_MAX_SHARE.toString())))
|
||||||
|
);
|
||||||
|
|
||||||
|
final RuinRandom random_for_regret = new RuinRandom(vrp,0.5);
|
||||||
|
random_for_regret.setRuinShareFactory(new RuinShareFactoryImpl(
|
||||||
|
toInteger(properties.getProperty(Parameter.RANDOM_REGRET_MIN_SHARE.toString())),
|
||||||
|
toInteger(properties.getProperty(Parameter.RANDOM_REGRET_MAX_SHARE.toString())))
|
||||||
|
);
|
||||||
|
|
||||||
|
final RuinRandom random_for_best = new RuinRandom(vrp,0.5);
|
||||||
|
random_for_best.setRuinShareFactory(new RuinShareFactoryImpl(
|
||||||
|
toInteger(properties.getProperty(Parameter.RANDOM_BEST_MIN_SHARE.toString())),
|
||||||
|
toInteger(properties.getProperty(Parameter.RANDOM_BEST_MAX_SHARE.toString())))
|
||||||
|
);
|
||||||
|
|
||||||
|
final RuinWorst worst = new RuinWorst(vrp, (int) (vrp.getJobs().values().size()*0.5));
|
||||||
|
worst.setRuinShareFactory(new RuinShareFactoryImpl(
|
||||||
|
toInteger(properties.getProperty(Parameter.WORST_MIN_SHARE.toString())),
|
||||||
|
toInteger(properties.getProperty(Parameter.WORST_MAX_SHARE.toString())))
|
||||||
|
);
|
||||||
|
IterationStartsListener noise = new IterationStartsListener() {
|
||||||
|
@Override
|
||||||
|
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||||
|
worst.setNoiseMaker(new NoiseMaker() {
|
||||||
|
|
||||||
|
public double makeNoise() {
|
||||||
|
if(RandomNumberGeneration.getRandom().nextDouble() < toDouble(getProperty(Parameter.RUIN_WORST_NOISE_PROB.toString()))) {
|
||||||
|
return toDouble(getProperty(Parameter.RUIN_WORST_NOISE_LEVEL.toString()))
|
||||||
|
* noiseMaker.maxCosts * RandomNumberGeneration.getRandom().nextDouble();
|
||||||
|
}
|
||||||
|
else return 0.;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final RuinClusters clusters = new RuinClusters(vrp,(int) (vrp.getJobs().values().size()*0.5),jobNeighborhoods);
|
||||||
|
clusters.setRuinShareFactory(new RuinShareFactoryImpl(
|
||||||
|
toInteger(properties.getProperty(Parameter.WORST_MIN_SHARE.toString())),
|
||||||
|
toInteger(properties.getProperty(Parameter.WORST_MAX_SHARE.toString())))
|
||||||
|
);
|
||||||
|
|
||||||
|
InsertionStrategy regret;
|
||||||
|
final RegretInsertion.DefaultScorer scorer;
|
||||||
|
if(noThreads == null){
|
||||||
|
noThreads = toInteger(getProperty(Parameter.THREADS.toString()));
|
||||||
|
}
|
||||||
|
if(noThreads > 1){
|
||||||
|
if(es == null){
|
||||||
|
setupExecutorInternally = true;
|
||||||
|
es = Executors.newFixedThreadPool(noThreads);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(es != null) {
|
||||||
|
RegretInsertionConcurrent regretInsertion = (RegretInsertionConcurrent) new InsertionBuilder(vrp, fm, stateManager, constraintManager)
|
||||||
|
.setInsertionStrategy(InsertionBuilder.Strategy.REGRET)
|
||||||
|
.setConcurrentMode(es, noThreads)
|
||||||
|
.considerFixedCosts(toDouble(getProperty(Parameter.FIXED_COST_PARAM.toString())))
|
||||||
|
.setAllowVehicleSwitch(toBoolean(getProperty(Parameter.VEHICLE_SWITCH.toString())))
|
||||||
|
.build();
|
||||||
|
scorer = getRegretScorer(vrp);
|
||||||
|
regretInsertion.setScoringFunction(scorer);
|
||||||
|
regret = regretInsertion;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
RegretInsertion regretInsertion = (RegretInsertion) new InsertionBuilder(vrp, fm, stateManager, constraintManager)
|
||||||
|
.setInsertionStrategy(InsertionBuilder.Strategy.REGRET)
|
||||||
|
.setAllowVehicleSwitch(toBoolean(getProperty(Parameter.VEHICLE_SWITCH.toString())))
|
||||||
|
.considerFixedCosts(toDouble(getProperty(Parameter.FIXED_COST_PARAM.toString())))
|
||||||
|
.build();
|
||||||
|
scorer = getRegretScorer(vrp);
|
||||||
|
regretInsertion.setScoringFunction(scorer);
|
||||||
|
regret = regretInsertion;
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertionStrategy best;
|
||||||
|
if(vrp.getJobs().size() < 250 || es == null) {
|
||||||
|
BestInsertion bestInsertion = (BestInsertion) new InsertionBuilder(vrp, fm, stateManager, constraintManager)
|
||||||
|
.setInsertionStrategy(InsertionBuilder.Strategy.BEST)
|
||||||
|
.considerFixedCosts(Double.valueOf(properties.getProperty(Parameter.FIXED_COST_PARAM.toString())))
|
||||||
|
.setAllowVehicleSwitch(toBoolean(getProperty(Parameter.VEHICLE_SWITCH.toString())))
|
||||||
|
.build();
|
||||||
|
best = bestInsertion;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
BestInsertionConcurrent bestInsertion = (BestInsertionConcurrent) new InsertionBuilder(vrp, fm, stateManager, constraintManager)
|
||||||
|
.setInsertionStrategy(InsertionBuilder.Strategy.BEST)
|
||||||
|
.considerFixedCosts(Double.valueOf(properties.getProperty(Parameter.FIXED_COST_PARAM.toString())))
|
||||||
|
.setAllowVehicleSwitch(toBoolean(getProperty(Parameter.VEHICLE_SWITCH.toString())))
|
||||||
|
.setConcurrentMode(es, noThreads)
|
||||||
|
.build();
|
||||||
|
best = bestInsertion;
|
||||||
|
}
|
||||||
|
|
||||||
|
final SchrimpfAcceptance schrimpfAcceptance = new SchrimpfAcceptance(1,toDouble(getProperty(Parameter.THRESHOLD_ALPHA.toString())));
|
||||||
|
IterationStartsListener schrimpfThreshold = new IterationStartsListener() {
|
||||||
|
@Override
|
||||||
|
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||||
|
if(i == 1){
|
||||||
|
double initialThreshold = Solutions.bestOf(solutions).getCost() * toDouble(getProperty(Parameter.THRESHOLD_INI.toString()));
|
||||||
|
schrimpfAcceptance.setInitialThreshold(initialThreshold);
|
||||||
|
System.out.println("threshold: " + initialThreshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SolutionCostCalculator objectiveFunction = getObjectiveFunction(vrp, noiseMaker.maxCosts);
|
||||||
|
SearchStrategy radial_regret = new SearchStrategy(Strategy.RADIAL_REGRET.toString(),new SelectBest(),schrimpfAcceptance, objectiveFunction);
|
||||||
|
radial_regret.addModule(new RuinAndRecreateModule(Strategy.RADIAL_REGRET.toString(), regret, radial));
|
||||||
|
|
||||||
|
SearchStrategy radial_best = new SearchStrategy(Strategy.RADIAL_BEST.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction);
|
||||||
|
radial_best.addModule(new RuinAndRecreateModule(Strategy.RADIAL_BEST.toString(),best,radial));
|
||||||
|
|
||||||
|
SearchStrategy random_best = new SearchStrategy(Strategy.RANDOM_BEST.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction);
|
||||||
|
random_best.addModule(new RuinAndRecreateModule(Strategy.RANDOM_BEST.toString(),best,random_for_best));
|
||||||
|
|
||||||
|
SearchStrategy random_regret = new SearchStrategy(Strategy.RANDOM_REGRET.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction);
|
||||||
|
random_regret.addModule(new RuinAndRecreateModule(Strategy.RANDOM_REGRET.toString(),regret,random_for_regret));
|
||||||
|
|
||||||
|
SearchStrategy worst_regret = new SearchStrategy(Strategy.WORST_REGRET.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction);
|
||||||
|
worst_regret.addModule(new RuinAndRecreateModule(Strategy.WORST_REGRET.toString(),regret,worst));
|
||||||
|
|
||||||
|
SearchStrategy worst_best = new SearchStrategy(Strategy.WORST_BEST.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction);
|
||||||
|
worst_best.addModule(new RuinAndRecreateModule(Strategy.WORST_BEST.toString(),best,worst));
|
||||||
|
|
||||||
|
final SearchStrategy clusters_regret = new SearchStrategy(Strategy.CLUSTER_REGRET.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction);
|
||||||
|
clusters_regret.addModule(new RuinAndRecreateModule(Strategy.CLUSTER_REGRET.toString(),regret,clusters));
|
||||||
|
|
||||||
|
final SearchStrategy clusters_best = new SearchStrategy(Strategy.CLUSTER_BEST.toString(),new SelectBest(),schrimpfAcceptance,objectiveFunction);
|
||||||
|
clusters_best.addModule(new RuinAndRecreateModule(Strategy.CLUSTER_BEST.toString(),best,clusters));
|
||||||
|
|
||||||
|
|
||||||
|
PrettyAlgorithmBuilder prettyBuilder = PrettyAlgorithmBuilder.newInstance(vrp, fm, stateManager, constraintManager);
|
||||||
|
if(addCoreConstraints){
|
||||||
|
prettyBuilder.addCoreStateAndConstraintStuff();
|
||||||
|
}
|
||||||
|
prettyBuilder.withStrategy(radial_regret, toDouble(getProperty(Strategy.RADIAL_REGRET.toString())))
|
||||||
|
.withStrategy(radial_best, toDouble(getProperty(Strategy.RADIAL_BEST.toString())))
|
||||||
|
.withStrategy(random_best, toDouble(getProperty(Strategy.RANDOM_BEST.toString())))
|
||||||
|
.withStrategy(random_regret, toDouble(getProperty(Strategy.RANDOM_REGRET.toString())))
|
||||||
|
.withStrategy(worst_best, toDouble(getProperty(Strategy.WORST_BEST.toString())))
|
||||||
|
.withStrategy(worst_regret, toDouble(getProperty(Strategy.WORST_REGRET.toString())))
|
||||||
|
.withStrategy(clusters_regret,toDouble(getProperty(Strategy.CLUSTER_REGRET.toString())))
|
||||||
|
.withStrategy(clusters_best,toDouble(getProperty(Strategy.CLUSTER_BEST.toString())))
|
||||||
|
.constructInitialSolutionWith(regret, objectiveFunction);
|
||||||
|
|
||||||
|
VehicleRoutingAlgorithm vra = prettyBuilder.build();
|
||||||
|
vra.addListener(schrimpfThreshold);
|
||||||
|
vra.addListener(noiseMaker);
|
||||||
|
vra.addListener(noise);
|
||||||
|
vra.addListener(clusters);
|
||||||
|
handleExecutorShutdown(vra);
|
||||||
|
vra.setMaxIterations(Integer.valueOf(properties.getProperty(Parameter.ITERATIONS.toString())));
|
||||||
|
return vra;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private RegretInsertion.DefaultScorer getRegretScorer(VehicleRoutingProblem vrp) {
|
||||||
|
RegretInsertion.DefaultScorer scorer;
|
||||||
|
scorer = new RegretInsertion.DefaultScorer(vrp);
|
||||||
|
scorer.setTimeWindowParam(Double.valueOf(properties.getProperty(Parameter.REGRET_TIME_WINDOW_SCORER.toString())));
|
||||||
|
scorer.setDepotDistanceParam(Double.valueOf(properties.getProperty(Parameter.REGRET_TIME_WINDOW_SCORER.toString())));
|
||||||
|
return scorer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void handleExecutorShutdown(VehicleRoutingAlgorithm vra) {
|
||||||
|
if(setupExecutorInternally){
|
||||||
|
vra.addListener(new AlgorithmEndsListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||||
|
es.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(es != null) {
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||||
|
public void run() {
|
||||||
|
if (!es.isShutdown()) {
|
||||||
|
System.err.println("shutdowHook shuts down executorService");
|
||||||
|
es.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getProperty(String key){
|
||||||
|
return properties.getProperty(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean toBoolean(String property) {
|
||||||
|
return Boolean.valueOf(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int toInteger(String string) {
|
||||||
|
return Integer.valueOf(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double toDouble(String string) {
|
||||||
|
return Double.valueOf(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SolutionCostCalculator getObjectiveFunction(final VehicleRoutingProblem vrp, final double maxCosts) {
|
||||||
|
return new SolutionCostCalculator() {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getCosts(VehicleRoutingProblemSolution solution) {
|
||||||
|
SolutionAnalyser analyser = new SolutionAnalyser(vrp,solution,new TransportDistance() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDistance(Location from, Location to) {
|
||||||
|
return vrp.getTransportCosts().getTransportCost(from, to,0.,null,null);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
return analyser.getVariableTransportCosts() + analyser.getFixedCosts() + solution.getUnassignedJobs().size() * maxCosts * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
package jsprit.core.algorithm.box;
|
||||||
|
|
||||||
|
import jsprit.core.algorithm.SearchStrategy;
|
||||||
|
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||||
|
import jsprit.core.algorithm.listener.StrategySelectedListener;
|
||||||
|
import jsprit.core.problem.Location;
|
||||||
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
import jsprit.core.problem.job.Service;
|
||||||
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
|
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 06/03/15.
|
||||||
|
*/
|
||||||
|
public class JspritTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRunningJspritWithSingleCustomer_itShouldWork(){
|
||||||
|
Service s = Service.Builder.newInstance("s1").setLocation(Location.newInstance(1,1)).build();
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v).addJob(s).build();
|
||||||
|
VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);
|
||||||
|
vra.setMaxIterations(10000);
|
||||||
|
final Map<String,Integer> counts = new HashMap<String,Integer>();
|
||||||
|
vra.addListener(new StrategySelectedListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informSelectedStrategy(SearchStrategy.DiscoveredSolution discoveredSolution, VehicleRoutingProblem vehicleRoutingProblem, Collection<VehicleRoutingProblemSolution> vehicleRoutingProblemSolutions) {
|
||||||
|
count(discoveredSolution.getStrategyId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void count(String strategyId) {
|
||||||
|
if(!counts.containsKey(strategyId)) counts.put(strategyId,1);
|
||||||
|
counts.put(strategyId,counts.get(strategyId)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
vra.searchSolutions();
|
||||||
|
Assert.assertTrue(true);
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
Assert.assertTrue(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void defaultStrategyProbabilitiesShouldWork_(){
|
||||||
|
Service s = Service.Builder.newInstance("s1").setLocation(Location.newInstance(1,1)).build();
|
||||||
|
Service s2 = Service.Builder.newInstance("s2").setLocation(Location.newInstance(1,2)).build();
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v).addJob(s2).addJob(s).build();
|
||||||
|
VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);
|
||||||
|
vra.setMaxIterations(5000);
|
||||||
|
final Map<String,Integer> counts = new HashMap<String,Integer>();
|
||||||
|
vra.addListener(new StrategySelectedListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informSelectedStrategy(SearchStrategy.DiscoveredSolution discoveredSolution, VehicleRoutingProblem vehicleRoutingProblem, Collection<VehicleRoutingProblemSolution> vehicleRoutingProblemSolutions) {
|
||||||
|
count(discoveredSolution.getStrategyId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void count(String strategyId) {
|
||||||
|
if(!counts.containsKey(strategyId)) counts.put(strategyId,1);
|
||||||
|
Integer integer = counts.get(strategyId);
|
||||||
|
counts.put(strategyId, integer +1);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
vra.searchSolutions();
|
||||||
|
Assert.assertTrue(!counts.containsKey(Jsprit.Strategy.RADIAL_BEST.toString()));
|
||||||
|
Assert.assertTrue(!counts.containsKey(Jsprit.Strategy.WORST_BEST.toString()));
|
||||||
|
Assert.assertTrue(!counts.containsKey(Jsprit.Strategy.CLUSTER_BEST.toString()));
|
||||||
|
Integer randomBestCounts = counts.get(Jsprit.Strategy.RANDOM_BEST.toString());
|
||||||
|
Assert.assertEquals(5000.*0.5/3.5,(double) randomBestCounts,100);
|
||||||
|
Assert.assertEquals(5000.*0.5/3.5,(double) counts.get(Jsprit.Strategy.RANDOM_REGRET.toString()),100);
|
||||||
|
Assert.assertEquals(5000.*0.5/3.5,(double) counts.get(Jsprit.Strategy.RADIAL_REGRET.toString()),100);
|
||||||
|
Assert.assertEquals(5000.*1./3.5,(double) counts.get(Jsprit.Strategy.WORST_REGRET.toString()),100);
|
||||||
|
Assert.assertEquals(5000.*1./3.5,(double) counts.get(Jsprit.Strategy.CLUSTER_REGRET.toString()),100);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenChangingStratProb_itShouldBeReflected(){
|
||||||
|
Service s = Service.Builder.newInstance("s1").setLocation(Location.newInstance(1,1)).build();
|
||||||
|
Service s2 = Service.Builder.newInstance("s2").setLocation(Location.newInstance(1,2)).build();
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v).addJob(s2).addJob(s).build();
|
||||||
|
VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp)
|
||||||
|
.setProperty(Jsprit.Strategy.RANDOM_BEST,"100.").buildAlgorithm();
|
||||||
|
vra.setMaxIterations(5000);
|
||||||
|
final Map<String,Integer> counts = new HashMap<String,Integer>();
|
||||||
|
vra.addListener(new StrategySelectedListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informSelectedStrategy(SearchStrategy.DiscoveredSolution discoveredSolution, VehicleRoutingProblem vehicleRoutingProblem, Collection<VehicleRoutingProblemSolution> vehicleRoutingProblemSolutions) {
|
||||||
|
count(discoveredSolution.getStrategyId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void count(String strategyId) {
|
||||||
|
if(!counts.containsKey(strategyId)) counts.put(strategyId,1);
|
||||||
|
Integer integer = counts.get(strategyId);
|
||||||
|
counts.put(strategyId, integer +1);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
vra.searchSolutions();
|
||||||
|
Assert.assertTrue(!counts.containsKey(Jsprit.Strategy.RADIAL_BEST.toString()));
|
||||||
|
Assert.assertTrue(!counts.containsKey(Jsprit.Strategy.WORST_BEST.toString()));
|
||||||
|
Assert.assertTrue(!counts.containsKey(Jsprit.Strategy.CLUSTER_BEST.toString()));
|
||||||
|
Integer randomBestCounts = counts.get(Jsprit.Strategy.RANDOM_BEST.toString());
|
||||||
|
Assert.assertEquals(5000.*100./103.,(double) randomBestCounts,100);
|
||||||
|
Assert.assertEquals(5000.*0.5/103.,(double) counts.get(Jsprit.Strategy.RANDOM_REGRET.toString()),100);
|
||||||
|
Assert.assertEquals(5000.*0.5/103.,(double) counts.get(Jsprit.Strategy.RADIAL_REGRET.toString()),100);
|
||||||
|
Assert.assertEquals(5000.*1./103.,(double) counts.get(Jsprit.Strategy.WORST_REGRET.toString()),100);
|
||||||
|
Assert.assertEquals(5000.*1./103.,(double) counts.get(Jsprit.Strategy.CLUSTER_REGRET.toString()),100);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenActivatingStrat_itShouldBeReflected(){
|
||||||
|
Service s = Service.Builder.newInstance("s1").setLocation(Location.newInstance(1,1)).build();
|
||||||
|
Service s2 = Service.Builder.newInstance("s2").setLocation(Location.newInstance(1,2)).build();
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addVehicle(v).addJob(s2).addJob(s).build();
|
||||||
|
VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp)
|
||||||
|
.setProperty(Jsprit.Strategy.RADIAL_BEST,"100.").buildAlgorithm();
|
||||||
|
vra.setMaxIterations(5000);
|
||||||
|
final Map<String,Integer> counts = new HashMap<String,Integer>();
|
||||||
|
vra.addListener(new StrategySelectedListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informSelectedStrategy(SearchStrategy.DiscoveredSolution discoveredSolution, VehicleRoutingProblem vehicleRoutingProblem, Collection<VehicleRoutingProblemSolution> vehicleRoutingProblemSolutions) {
|
||||||
|
count(discoveredSolution.getStrategyId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void count(String strategyId) {
|
||||||
|
if(!counts.containsKey(strategyId)) counts.put(strategyId,1);
|
||||||
|
Integer integer = counts.get(strategyId);
|
||||||
|
counts.put(strategyId, integer +1);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
vra.searchSolutions();
|
||||||
|
Assert.assertTrue(counts.containsKey(Jsprit.Strategy.RADIAL_BEST.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_v3(){
|
||||||
|
Service s = Service.Builder.newInstance("s1").setLocation(Location.newInstance(1,1)).build();
|
||||||
|
Service s2 = Service.Builder.newInstance("s2").setLocation(Location.newInstance(1,2)).build();
|
||||||
|
Service s3 = Service.Builder.newInstance("s3").setLocation(Location.newInstance(1,2)).build();
|
||||||
|
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(s3).addVehicle(v).addJob(s2).addJob(s).build();
|
||||||
|
VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);
|
||||||
|
vra.setMaxIterations(5000);
|
||||||
|
final Map<String,Integer> counts = new HashMap<String,Integer>();
|
||||||
|
vra.addListener(new StrategySelectedListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informSelectedStrategy(SearchStrategy.DiscoveredSolution discoveredSolution, VehicleRoutingProblem vehicleRoutingProblem, Collection<VehicleRoutingProblemSolution> vehicleRoutingProblemSolutions) {
|
||||||
|
count(discoveredSolution.getStrategyId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void count(String strategyId) {
|
||||||
|
if(!counts.containsKey(strategyId)) counts.put(strategyId,1);
|
||||||
|
counts.put(strategyId,counts.get(strategyId)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
vra.searchSolutions();
|
||||||
|
Assert.assertTrue(!counts.containsKey(Jsprit.Strategy.RADIAL_BEST));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_v4(){
|
||||||
|
Service s = Service.Builder.newInstance("s1").setLocation(Location.newInstance(1,1)).build();
|
||||||
|
Service s2 = Service.Builder.newInstance("s2").setLocation(Location.newInstance(1,2)).build();
|
||||||
|
Service s3 = Service.Builder.newInstance("s3").setLocation(Location.newInstance(1,2)).build();
|
||||||
|
Service s4 = Service.Builder.newInstance("s4").setLocation(Location.newInstance(1,2)).build();
|
||||||
|
|
||||||
|
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0,0)).build();
|
||||||
|
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(s4).addJob(s3).addVehicle(v).addJob(s2).addJob(s).build();
|
||||||
|
VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);
|
||||||
|
vra.setMaxIterations(5000);
|
||||||
|
final Map<String,Integer> counts = new HashMap<String,Integer>();
|
||||||
|
vra.addListener(new StrategySelectedListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informSelectedStrategy(SearchStrategy.DiscoveredSolution discoveredSolution, VehicleRoutingProblem vehicleRoutingProblem, Collection<VehicleRoutingProblemSolution> vehicleRoutingProblemSolutions) {
|
||||||
|
count(discoveredSolution.getStrategyId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void count(String strategyId) {
|
||||||
|
if(!counts.containsKey(strategyId)) counts.put(strategyId,1);
|
||||||
|
counts.put(strategyId,counts.get(strategyId)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
vra.searchSolutions();
|
||||||
|
Assert.assertTrue(!counts.containsKey(Jsprit.Strategy.RADIAL_BEST));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue