mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
add new and unique random instance to ensure reproducibility of several run within the same jvm
This commit is contained in:
parent
7016f3baa3
commit
4efbd1cd1e
8 changed files with 216 additions and 82 deletions
|
|
@ -33,10 +33,7 @@ import jsprit.core.problem.vehicle.VehicleFleetManager;
|
|||
import jsprit.core.problem.vehicle.VehicleTypeKey;
|
||||
import jsprit.core.util.ActivityTimeTracker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by schroeder on 10.12.14.
|
||||
|
|
@ -71,6 +68,11 @@ public class PrettyAlgorithmBuilder {
|
|||
this.searchStrategyManager = new SearchStrategyManager();
|
||||
}
|
||||
|
||||
public PrettyAlgorithmBuilder setRandom(Random random){
|
||||
searchStrategyManager.setRandom(random);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PrettyAlgorithmBuilder withStrategy(SearchStrategy strategy, double weight){
|
||||
searchStrategyManager.addStrategy(strategy,weight);
|
||||
return this;
|
||||
|
|
@ -164,4 +166,5 @@ public class PrettyAlgorithmBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import jsprit.core.util.RandomNumberGeneration;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Created by schroeder on 16/01/15.
|
||||
|
|
@ -31,6 +32,8 @@ class InsertionNoiseMaker implements SoftActivityConstraint, IterationStartsList
|
|||
|
||||
private double noiseLevel = 0.1;
|
||||
|
||||
private Random random = RandomNumberGeneration.getRandom();
|
||||
|
||||
public InsertionNoiseMaker(VehicleRoutingProblem vrp, double noiseLevel, double noiseProbability) {
|
||||
this.vrp = vrp;
|
||||
this.noiseLevel = noiseLevel;
|
||||
|
|
@ -70,7 +73,7 @@ class InsertionNoiseMaker implements SoftActivityConstraint, IterationStartsList
|
|||
|
||||
@Override
|
||||
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
if(RandomNumberGeneration.getRandom().nextDouble() < noiseProbability){
|
||||
if(random.nextDouble() < noiseProbability){
|
||||
makeNoise = true;
|
||||
}
|
||||
else makeNoise = false;
|
||||
|
|
@ -79,10 +82,13 @@ class InsertionNoiseMaker implements SoftActivityConstraint, IterationStartsList
|
|||
@Override
|
||||
public double getCosts(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
if(makeNoise) {
|
||||
return noiseLevel * maxCosts * RandomNumberGeneration.getRandom().nextDouble();
|
||||
return noiseLevel * maxCosts * random.nextDouble();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public void setRandom(Random random) {
|
||||
this.random = random;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import jsprit.core.util.Solutions;
|
|||
|
||||
import java.util.Collection;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
|
|
@ -129,6 +130,8 @@ public class Jsprit {
|
|||
|
||||
private boolean addConstraints = true;
|
||||
|
||||
private Random random = RandomNumberGeneration.newInstance();
|
||||
|
||||
public static Builder newInstance(VehicleRoutingProblem vrp){
|
||||
return new Builder(vrp);
|
||||
}
|
||||
|
|
@ -186,6 +189,11 @@ public class Jsprit {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setRandom(Random random){
|
||||
this.random = random;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setProperty(String key, String value){
|
||||
properties.put(key,value);
|
||||
return this;
|
||||
|
|
@ -231,15 +239,28 @@ public class Jsprit {
|
|||
|
||||
private int minShare;
|
||||
|
||||
private Random random = RandomNumberGeneration.getRandom();
|
||||
|
||||
public void setRandom(Random random) {
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public RuinShareFactoryImpl(int minShare, int maxShare, Random random) {
|
||||
if(maxShare < minShare) throw new IllegalArgumentException("maxShare must be equal or greater than minShare");
|
||||
this.minShare = minShare;
|
||||
this.maxShare = maxShare;
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int createNumberToBeRemoved() {
|
||||
return (int) (minShare + (maxShare - minShare) * RandomNumberGeneration.getRandom().nextDouble());
|
||||
return (int) (minShare + (maxShare - minShare) * random.nextDouble());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -260,6 +281,8 @@ public class Jsprit {
|
|||
|
||||
private Properties properties;
|
||||
|
||||
private Random random;
|
||||
|
||||
private Jsprit(Builder builder) {
|
||||
this.stateManager = builder.stateManager;
|
||||
this.constraintManager = builder.constraintManager;
|
||||
|
|
@ -268,6 +291,7 @@ public class Jsprit {
|
|||
this.addCoreConstraints = builder.addConstraints;
|
||||
this.properties = builder.properties;
|
||||
this.objectiveFunction = builder.objectiveFunction;
|
||||
this.random = builder.random;
|
||||
}
|
||||
|
||||
private VehicleRoutingAlgorithm create(final VehicleRoutingProblem vrp){
|
||||
|
|
@ -287,33 +311,42 @@ public class Jsprit {
|
|||
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);
|
||||
noiseMaker.setRandom(random);
|
||||
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.setRandom(random);
|
||||
radial.setRuinShareFactory(new RuinShareFactoryImpl(
|
||||
toInteger(properties.getProperty(Parameter.RADIAL_MIN_SHARE.toString())),
|
||||
toInteger(properties.getProperty(Parameter.RADIAL_MAX_SHARE.toString())))
|
||||
toInteger(properties.getProperty(Parameter.RADIAL_MAX_SHARE.toString())),
|
||||
random)
|
||||
);
|
||||
|
||||
final RuinRandom random_for_regret = new RuinRandom(vrp,0.5);
|
||||
random_for_regret.setRandom(random);
|
||||
random_for_regret.setRuinShareFactory(new RuinShareFactoryImpl(
|
||||
toInteger(properties.getProperty(Parameter.RANDOM_REGRET_MIN_SHARE.toString())),
|
||||
toInteger(properties.getProperty(Parameter.RANDOM_REGRET_MAX_SHARE.toString())))
|
||||
toInteger(properties.getProperty(Parameter.RANDOM_REGRET_MAX_SHARE.toString())),
|
||||
random)
|
||||
);
|
||||
|
||||
final RuinRandom random_for_best = new RuinRandom(vrp,0.5);
|
||||
random_for_best.setRandom(random);
|
||||
random_for_best.setRuinShareFactory(new RuinShareFactoryImpl(
|
||||
toInteger(properties.getProperty(Parameter.RANDOM_BEST_MIN_SHARE.toString())),
|
||||
toInteger(properties.getProperty(Parameter.RANDOM_BEST_MAX_SHARE.toString())))
|
||||
toInteger(properties.getProperty(Parameter.RANDOM_BEST_MAX_SHARE.toString())),
|
||||
random)
|
||||
);
|
||||
|
||||
final RuinWorst worst = new RuinWorst(vrp, (int) (vrp.getJobs().values().size()*0.5));
|
||||
worst.setRandom(random);
|
||||
worst.setRuinShareFactory(new RuinShareFactoryImpl(
|
||||
toInteger(properties.getProperty(Parameter.WORST_MIN_SHARE.toString())),
|
||||
toInteger(properties.getProperty(Parameter.WORST_MAX_SHARE.toString())))
|
||||
toInteger(properties.getProperty(Parameter.WORST_MAX_SHARE.toString())),
|
||||
random)
|
||||
);
|
||||
IterationStartsListener noise = new IterationStartsListener() {
|
||||
@Override
|
||||
|
|
@ -321,9 +354,9 @@ public class Jsprit {
|
|||
worst.setNoiseMaker(new NoiseMaker() {
|
||||
|
||||
public double makeNoise() {
|
||||
if(RandomNumberGeneration.getRandom().nextDouble() < toDouble(getProperty(Parameter.RUIN_WORST_NOISE_PROB.toString()))) {
|
||||
if(random.nextDouble() < toDouble(getProperty(Parameter.RUIN_WORST_NOISE_PROB.toString()))) {
|
||||
return toDouble(getProperty(Parameter.RUIN_WORST_NOISE_LEVEL.toString()))
|
||||
* noiseMaker.maxCosts * RandomNumberGeneration.getRandom().nextDouble();
|
||||
* noiseMaker.maxCosts * random.nextDouble();
|
||||
}
|
||||
else return 0.;
|
||||
}
|
||||
|
|
@ -332,12 +365,14 @@ public class Jsprit {
|
|||
};
|
||||
|
||||
final RuinClusters clusters = new RuinClusters(vrp,(int) (vrp.getJobs().values().size()*0.5),jobNeighborhoods);
|
||||
clusters.setRandom(random);
|
||||
clusters.setRuinShareFactory(new RuinShareFactoryImpl(
|
||||
toInteger(properties.getProperty(Parameter.WORST_MIN_SHARE.toString())),
|
||||
toInteger(properties.getProperty(Parameter.WORST_MAX_SHARE.toString())))
|
||||
toInteger(properties.getProperty(Parameter.WORST_MAX_SHARE.toString())),
|
||||
random)
|
||||
);
|
||||
|
||||
InsertionStrategy regret;
|
||||
AbstractInsertionStrategy regret;
|
||||
final RegretInsertion.DefaultScorer scorer;
|
||||
if(noThreads == null){
|
||||
noThreads = toInteger(getProperty(Parameter.THREADS.toString()));
|
||||
|
|
@ -369,8 +404,9 @@ public class Jsprit {
|
|||
regretInsertion.setScoringFunction(scorer);
|
||||
regret = regretInsertion;
|
||||
}
|
||||
regret.setRandom(random);
|
||||
|
||||
InsertionStrategy best;
|
||||
AbstractInsertionStrategy best;
|
||||
if(vrp.getJobs().size() < 250 || es == null) {
|
||||
BestInsertion bestInsertion = (BestInsertion) new InsertionBuilder(vrp, fm, stateManager, constraintManager)
|
||||
.setInsertionStrategy(InsertionBuilder.Strategy.BEST)
|
||||
|
|
@ -388,6 +424,7 @@ public class Jsprit {
|
|||
.build();
|
||||
best = bestInsertion;
|
||||
}
|
||||
best.setRandom(random);
|
||||
|
||||
final SchrimpfAcceptance schrimpfAcceptance = new SchrimpfAcceptance(1,toDouble(getProperty(Parameter.THRESHOLD_ALPHA.toString())));
|
||||
IterationStartsListener schrimpfThreshold = new IterationStartsListener() {
|
||||
|
|
@ -428,6 +465,7 @@ public class Jsprit {
|
|||
|
||||
|
||||
PrettyAlgorithmBuilder prettyBuilder = PrettyAlgorithmBuilder.newInstance(vrp, fm, stateManager, constraintManager);
|
||||
prettyBuilder.setRandom(random);
|
||||
if(addCoreConstraints){
|
||||
prettyBuilder.addCoreStateAndConstraintStuff();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,14 +17,12 @@
|
|||
package jsprit.core.algorithm.recreate;
|
||||
|
||||
import jsprit.core.algorithm.recreate.InsertionData.NoInsertionFound;
|
||||
import jsprit.core.algorithm.recreate.listener.InsertionListener;
|
||||
import jsprit.core.algorithm.recreate.listener.InsertionListeners;
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.driver.Driver;
|
||||
import jsprit.core.problem.job.Job;
|
||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
import jsprit.core.util.RandomNumberGeneration;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
|
@ -40,7 +38,7 @@ import java.util.concurrent.*;
|
|||
*
|
||||
*/
|
||||
|
||||
public final class BestInsertionConcurrent implements InsertionStrategy{
|
||||
public final class BestInsertionConcurrent extends AbstractInsertionStrategy{
|
||||
|
||||
static class Batch {
|
||||
List<VehicleRoute> routes = new ArrayList<VehicleRoute>();
|
||||
|
|
@ -70,8 +68,6 @@ public final class BestInsertionConcurrent implements InsertionStrategy{
|
|||
}
|
||||
|
||||
private static Logger logger = LogManager.getLogger(BestInsertionConcurrent.class);
|
||||
|
||||
private Random random = RandomNumberGeneration.getRandom();
|
||||
|
||||
private final static double NO_NEW_DEPARTURE_TIME_YET = -12345.12345;
|
||||
|
||||
|
|
@ -81,23 +77,21 @@ public final class BestInsertionConcurrent implements InsertionStrategy{
|
|||
|
||||
private InsertionListeners insertionsListeners;
|
||||
|
||||
private Inserter inserter;
|
||||
|
||||
private JobInsertionCostsCalculator bestInsertionCostCalculator;
|
||||
|
||||
private int nuOfBatches;
|
||||
|
||||
private ExecutorCompletionService<Insertion> completionService;
|
||||
|
||||
@Deprecated
|
||||
public void setRandom(Random random) {
|
||||
this.random = random;
|
||||
super.random = random;
|
||||
}
|
||||
|
||||
public BestInsertionConcurrent(JobInsertionCostsCalculator jobInsertionCalculator, ExecutorService executorService, int nuOfBatches, VehicleRoutingProblem vehicleRoutingProblem) {
|
||||
super();
|
||||
super(vehicleRoutingProblem);
|
||||
this.insertionsListeners = new InsertionListeners();
|
||||
this.nuOfBatches = nuOfBatches;
|
||||
inserter = new Inserter(insertionsListeners, vehicleRoutingProblem);
|
||||
bestInsertionCostCalculator = jobInsertionCalculator;
|
||||
completionService = new ExecutorCompletionService<Insertion>(executorService);
|
||||
logger.info("initialise " + this);
|
||||
|
|
@ -109,71 +103,53 @@ public final class BestInsertionConcurrent implements InsertionStrategy{
|
|||
}
|
||||
|
||||
@Override
|
||||
public Collection<Job> insertJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
insertionsListeners.informInsertionStarts(vehicleRoutes,unassignedJobs);
|
||||
List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size());
|
||||
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
|
||||
public Collection<Job> insertUnassignedJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size());
|
||||
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
|
||||
Collections.shuffle(unassignedJobList, random);
|
||||
List<Batch> batches = distributeRoutes(vehicleRoutes,nuOfBatches);
|
||||
for(final Job unassignedJob : unassignedJobList){
|
||||
Insertion bestInsertion = null;
|
||||
List<Batch> batches = distributeRoutes(vehicleRoutes,nuOfBatches);
|
||||
for(final Job unassignedJob : unassignedJobList){
|
||||
Insertion bestInsertion = null;
|
||||
double bestInsertionCost = Double.MAX_VALUE;
|
||||
for(final Batch batch : batches){
|
||||
for(final Batch batch : batches){
|
||||
completionService.submit(new Callable<Insertion>() {
|
||||
|
||||
|
||||
@Override
|
||||
public Insertion call() throws Exception {
|
||||
return getBestInsertion(batch,unassignedJob);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
try {
|
||||
for (int i = 0; i < batches.size(); i++) {
|
||||
Future<Insertion> futureIData = completionService.take();
|
||||
Insertion insertion = futureIData.get();
|
||||
if (insertion == null) continue;
|
||||
if (insertion.getInsertionData().getInsertionCost() < bestInsertionCost) {
|
||||
bestInsertion = insertion;
|
||||
bestInsertionCost = insertion.getInsertionData().getInsertionCost();
|
||||
}
|
||||
}
|
||||
} catch(InterruptedException e){
|
||||
}
|
||||
try {
|
||||
for (int i = 0; i < batches.size(); i++) {
|
||||
Future<Insertion> futureIData = completionService.take();
|
||||
Insertion insertion = futureIData.get();
|
||||
if (insertion == null) continue;
|
||||
if (insertion.getInsertionData().getInsertionCost() < bestInsertionCost) {
|
||||
bestInsertion = insertion;
|
||||
bestInsertionCost = insertion.getInsertionData().getInsertionCost();
|
||||
}
|
||||
}
|
||||
} catch(InterruptedException e){
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
logger.error(e.getCause().toString());
|
||||
System.exit(1);
|
||||
}
|
||||
VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
||||
InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
|
||||
if(newIData.getInsertionCost() < bestInsertionCost){
|
||||
bestInsertion = new Insertion(newRoute,newIData);
|
||||
vehicleRoutes.add(newRoute);
|
||||
batches.get(random.nextInt(batches.size())).routes.add(newRoute);
|
||||
}
|
||||
if(bestInsertion == null) badJobs.add(unassignedJob);
|
||||
else inserter.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
|
||||
VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
||||
InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
|
||||
if(newIData.getInsertionCost() < bestInsertionCost){
|
||||
bestInsertion = new Insertion(newRoute,newIData);
|
||||
vehicleRoutes.add(newRoute);
|
||||
batches.get(random.nextInt(batches.size())).routes.add(newRoute);
|
||||
}
|
||||
if(bestInsertion == null) badJobs.add(unassignedJob);
|
||||
else insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
|
||||
}
|
||||
insertionsListeners.informInsertionEndsListeners(vehicleRoutes);
|
||||
return badJobs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(InsertionListener insertionListener) {
|
||||
insertionsListeners.removeListener(insertionListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<InsertionListener> getListeners() {
|
||||
return Collections.unmodifiableCollection(insertionsListeners.getListeners());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(InsertionListener insertionListener) {
|
||||
insertionsListeners.addListener(insertionListener);
|
||||
|
||||
return badJobs;
|
||||
}
|
||||
|
||||
private Insertion getBestInsertion(Batch batch, Job unassignedJob) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import org.apache.logging.log4j.Logger;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator{
|
||||
|
|
@ -45,6 +46,12 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsC
|
|||
|
||||
private List<Double> departureTimeKnowledge = new ArrayList<Double>();
|
||||
|
||||
public void setRandom(Random random) {
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
private Random random = RandomNumberGeneration.getRandom();
|
||||
|
||||
CalculatesServiceInsertionWithTimeScheduling(JobInsertionCostsCalculator jic, double t, double f) {
|
||||
super();
|
||||
this.jic = jic;
|
||||
|
|
@ -61,7 +68,7 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsC
|
|||
double departureTime = newVehicleDepartureTime;
|
||||
if(currentRoute.isEmpty()){
|
||||
if(!departureTimeKnowledge.isEmpty()){
|
||||
departureTime = departureTimeKnowledge.get(RandomNumberGeneration.getRandom().nextInt(departureTimeKnowledge.size()));
|
||||
departureTime = departureTimeKnowledge.get(random.nextInt(departureTimeKnowledge.size()));
|
||||
}
|
||||
}
|
||||
else if(!currentRoute.getVehicle().getId().equals(newVehicle.getId())){
|
||||
|
|
|
|||
|
|
@ -103,6 +103,12 @@ public class DBSCANClusterer {
|
|||
|
||||
private Double epsDistance;
|
||||
|
||||
private Random random = RandomNumberGeneration.getRandom();
|
||||
|
||||
public void setRandom(Random random) {
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
public DBSCANClusterer(VehicleRoutingTransportCosts costs) {
|
||||
this.costs = costs;
|
||||
}
|
||||
|
|
@ -162,14 +168,13 @@ public class DBSCANClusterer {
|
|||
}
|
||||
List<Cluster<LocationWrapper>> clusterResults = getClusters(route,locations);
|
||||
if(clusterResults.isEmpty()) return Collections.emptyList();
|
||||
Cluster<LocationWrapper> randomCluster = RandomUtils.nextItem(clusterResults, RandomNumberGeneration.getRandom());
|
||||
Cluster<LocationWrapper> randomCluster = RandomUtils.nextItem(clusterResults, random);
|
||||
return getJobList(randomCluster);
|
||||
}
|
||||
|
||||
private double sample(VehicleRoutingTransportCosts costs, VehicleRoute r) {
|
||||
double min = Double.MAX_VALUE;
|
||||
double sum = 0;
|
||||
Random random = RandomNumberGeneration.getRandom();
|
||||
for(int i=0;i<noDistanceSamples;i++){
|
||||
TourActivity act1 = RandomUtils.nextItem(r.getActivities(), random);
|
||||
TourActivity act2 = RandomUtils.nextItem(r.getActivities(), random);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import jsprit.core.problem.job.Job;
|
|||
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||
import jsprit.core.util.RandomNumberGeneration;
|
||||
import jsprit.core.util.RandomUtils;
|
||||
import org.apache.commons.math3.ml.clustering.Clusterable;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
|
@ -43,8 +42,8 @@ public final class RuinClusters extends AbstractRuinStrategy implements Iteratio
|
|||
|
||||
@Override
|
||||
public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
minPts = 1 + RandomNumberGeneration.getRandom().nextInt(2);
|
||||
epsFactor = 0.5 + RandomNumberGeneration.getRandom().nextDouble();
|
||||
minPts = 1 + random.nextInt(2);
|
||||
epsFactor = 0.5 + random.nextDouble();
|
||||
}
|
||||
|
||||
public static class JobActivityWrapper implements Clusterable {
|
||||
|
|
@ -151,6 +150,7 @@ public final class RuinClusters extends AbstractRuinStrategy implements Iteratio
|
|||
break;
|
||||
}
|
||||
DBSCANClusterer dbscan = new DBSCANClusterer(vrp.getTransportCosts());
|
||||
dbscan.setRandom(random);
|
||||
dbscan.setMinPts(minPts);
|
||||
dbscan.setEpsFactor(epsFactor);
|
||||
List<Job> cluster = dbscan.getRandomCluster(targetRoute);
|
||||
|
|
|
|||
|
|
@ -511,6 +511,7 @@ public class JspritTest {
|
|||
Assert.assertEquals(Solutions.bestOf(firstSolutions).getCost(),Solutions.bestOf(secondSolutions).getCost());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void whenTerminatingWithVariationCoefficient_terminationShouldBeReproducible(){
|
||||
|
||||
|
|
@ -558,4 +559,102 @@ public class JspritTest {
|
|||
Assert.assertEquals(Solutions.bestOf(firstSolutions).getCost(),Solutions.bestOf(secondSolutions).getCost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenBiggerProblem_insertioPositionsShouldBeReproducibleWithoutResetingRNGExplicitly(){
|
||||
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrpXMLReader(vrpBuilder).read("src/test/resources/vrpnc1-jsprit-with-deliveries.xml");
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
|
||||
RandomNumberGeneration.reset();
|
||||
VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);
|
||||
vra.setMaxIterations(200);
|
||||
final List<Integer> firstRecord = new ArrayList<Integer>();
|
||||
vra.addListener(new BeforeJobInsertionListener() {
|
||||
@Override
|
||||
public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route) {
|
||||
firstRecord.add(data.getDeliveryInsertionIndex());
|
||||
}
|
||||
});
|
||||
Collection<VehicleRoutingProblemSolution> firstSolutions = vra.searchSolutions();
|
||||
|
||||
// RandomNumberGeneration.reset();
|
||||
VehicleRoutingAlgorithm second = Jsprit.createAlgorithm(vrp);
|
||||
second.setMaxIterations(200);
|
||||
final List<Integer> secondRecord = new ArrayList<Integer>();
|
||||
second.addListener(new BeforeJobInsertionListener() {
|
||||
@Override
|
||||
public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route) {
|
||||
secondRecord.add(data.getDeliveryInsertionIndex());
|
||||
}
|
||||
});
|
||||
Collection<VehicleRoutingProblemSolution> secondSolutions = second.searchSolutions();
|
||||
|
||||
Assert.assertEquals(secondRecord.size(),firstRecord.size());
|
||||
for(int i=0;i<firstRecord.size();i++){
|
||||
if(!firstRecord.get(i).equals(secondRecord.get(i))){
|
||||
Assert.assertFalse(true);
|
||||
}
|
||||
}
|
||||
Assert.assertTrue(true);
|
||||
Assert.assertEquals(Solutions.bestOf(firstSolutions).getCost(),Solutions.bestOf(secondSolutions).getCost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenBiggerProblem_ruinedJobsShouldBeReproducibleWithoutResetingRNGExplicitly(){
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrpXMLReader(vrpBuilder).read("src/test/resources/vrpnc1-jsprit-with-deliveries.xml");
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);
|
||||
vra.setMaxIterations(200);
|
||||
final List<String> firstRecord = new ArrayList<String>();
|
||||
vra.addListener(new RuinListener() {
|
||||
@Override
|
||||
public void ruinStarts(Collection<VehicleRoute> routes) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ruinEnds(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Job job, VehicleRoute fromRoute) {
|
||||
firstRecord.add(job.getId());
|
||||
}
|
||||
});
|
||||
vra.searchSolutions();
|
||||
|
||||
// RandomNumberGeneration.reset();
|
||||
VehicleRoutingAlgorithm second = Jsprit.createAlgorithm(vrp);
|
||||
second.setMaxIterations(200);
|
||||
final List<String> secondRecord = new ArrayList<String>();
|
||||
second.addListener(new RuinListener() {
|
||||
@Override
|
||||
public void ruinStarts(Collection<VehicleRoute> routes) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ruinEnds(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Job job, VehicleRoute fromRoute) {
|
||||
secondRecord.add(job.getId());
|
||||
}
|
||||
});
|
||||
second.searchSolutions();
|
||||
|
||||
Assert.assertEquals(secondRecord.size(),firstRecord.size());
|
||||
for(int i=0;i<firstRecord.size();i++){
|
||||
if(!firstRecord.get(i).equals(secondRecord.get(i))){
|
||||
Assert.assertFalse(true);
|
||||
}
|
||||
}
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue