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

Merge branch 'prepareV010' into PickupMergeRelaxAPI

Conflicts:
	jsprit-core/src/main/java/algorithms/BestInsertionBuilder.java
	jsprit-core/src/main/java/algorithms/BestInsertionConcurrent.java
This commit is contained in:
Stefan Schroeder 2013-11-21 11:39:28 +01:00
commit d1dac2d622
21 changed files with 11614 additions and 10997 deletions

View file

@ -37,6 +37,7 @@ import algorithms.VehicleRoutingAlgorithms;
import basics.VehicleRoutingAlgorithm; import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.algo.VehicleRoutingAlgorithmFactory;
import basics.algo.VehicleRoutingAlgorithmListeners.Priority; import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
public class ConcurrentBenchmarker { public class ConcurrentBenchmarker {
@ -47,7 +48,7 @@ public class ConcurrentBenchmarker {
private String algorithmConfig; private String algorithmConfig = null;
private List<BenchmarkInstance> benchmarkInstances = new ArrayList<BenchmarkInstance>(); private List<BenchmarkInstance> benchmarkInstances = new ArrayList<BenchmarkInstance>();
@ -65,6 +66,8 @@ public class ConcurrentBenchmarker {
} }
}; };
private VehicleRoutingAlgorithmFactory algorithmFactory;
public void setCost(Cost cost){ this.cost = cost; } public void setCost(Cost cost){ this.cost = cost; }
@ -74,6 +77,10 @@ public class ConcurrentBenchmarker {
Logger.getRootLogger().setLevel(Level.ERROR); Logger.getRootLogger().setLevel(Level.ERROR);
} }
public ConcurrentBenchmarker(VehicleRoutingAlgorithmFactory algorithmFactory){
this.algorithmFactory = algorithmFactory;
}
public void addBenchmarkWriter(BenchmarkWriter writer){ public void addBenchmarkWriter(BenchmarkWriter writer){
writers.add(writer); writers.add(writer);
} }
@ -94,6 +101,12 @@ public class ConcurrentBenchmarker {
benchmarkInstances.add(new BenchmarkInstance(name,problem,bestKnownResult,bestKnownVehicles)); benchmarkInstances.add(new BenchmarkInstance(name,problem,bestKnownResult,bestKnownVehicles));
} }
/**
* Sets nuOfRuns with same algorithm on same instance.
* <p>Default is 1
*
* @param runs
*/
public void setNuOfRuns(int runs){ public void setNuOfRuns(int runs){
this.runs = runs; this.runs = runs;
} }
@ -142,11 +155,11 @@ public class ConcurrentBenchmarker {
double[] times = new double[runs]; double[] times = new double[runs];
for(int run=0;run<runs;run++){ for(int run=0;run<runs;run++){
VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(p.vrp, algorithmConfig); VehicleRoutingAlgorithm vra = createAlgorithm(p);
StopWatch stopwatch = new StopWatch(); StopWatch stopwatch = new StopWatch();
vra.getAlgorithmListeners().addListener(stopwatch,Priority.HIGH); vra.getAlgorithmListeners().addListener(stopwatch,Priority.HIGH);
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions(); Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
VehicleRoutingProblemSolution best = Solutions.getBest(solutions); VehicleRoutingProblemSolution best = Solutions.bestOf(solutions);
vehicles[run] = best.getRoutes().size(); vehicles[run] = best.getRoutes().size();
results[run] = cost.getCost(best); results[run] = cost.getCost(best);
times[run] = stopwatch.getCompTimeInSeconds(); times[run] = stopwatch.getCompTimeInSeconds();
@ -155,6 +168,16 @@ public class ConcurrentBenchmarker {
return new BenchmarkResult(p, runs, results, times, vehicles); return new BenchmarkResult(p, runs, results, times, vehicles);
} }
private VehicleRoutingAlgorithm createAlgorithm(BenchmarkInstance p) {
if(algorithmConfig != null){
return VehicleRoutingAlgorithms.readAndCreateAlgorithm(p.vrp, algorithmConfig);
}
else{
return algorithmFactory.createAlgorithm(p.vrp);
}
}
private void print(Collection<BenchmarkResult> results) { private void print(Collection<BenchmarkResult> results) {
double sumTime=0.0; double sumTime=0.0;
double sumResult=0.0; double sumResult=0.0;

View file

@ -9,7 +9,7 @@ import basics.algo.InsertionListener;
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener; import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
import basics.route.VehicleFleetManager; import basics.route.VehicleFleetManager;
public class BestInsertionBuilder implements InsertionStrategyBuilder{ public class BestInsertionBuilder {
private VehicleRoutingProblem vrp; private VehicleRoutingProblem vrp;
@ -35,11 +35,11 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
private int nuOfThreads; private int nuOfThreads;
public BestInsertionBuilder(VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManager stateManager) { public BestInsertionBuilder(VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManager stateManager, ConstraintManager constraintManager) {
super(); super();
this.vrp = vrp; this.vrp = vrp;
this.stateManager = stateManager; this.stateManager = stateManager;
this.constraintManager = new ConstraintManager(vrp,stateManager); this.constraintManager = constraintManager;
this.fleetManager = vehicleFleetManager; this.fleetManager = vehicleFleetManager;
} }
@ -73,7 +73,7 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
return this; return this;
} }
@Override
public InsertionStrategy build() { public InsertionStrategy build() {
List<InsertionListener> iListeners = new ArrayList<InsertionListener>(); List<InsertionListener> iListeners = new ArrayList<InsertionListener>();
List<PrioritizedVRAListener> algorithmListeners = new ArrayList<PrioritizedVRAListener>(); List<PrioritizedVRAListener> algorithmListeners = new ArrayList<PrioritizedVRAListener>();
@ -99,14 +99,12 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
} }
else{ else{
bestInsertion = new BestInsertionConc(jobInsertions,executor,nuOfThreads);
bestInsertion = new BestInsertionConcurrent(jobInsertions,executor,nuOfThreads);
} }
for(InsertionListener l : iListeners) bestInsertion.addListener(l); for(InsertionListener l : iListeners) bestInsertion.addListener(l);
return bestInsertion; return bestInsertion;
} }
public void setConstraintManager(ConstraintManager constraintManager) {
this.constraintManager = constraintManager;
}
} }

View file

@ -45,7 +45,7 @@ import basics.route.VehicleRoute;
* *
*/ */
final class BestInsertionConc implements InsertionStrategy{ final class BestInsertionConcurrent implements InsertionStrategy{
static class Batch { static class Batch {
List<VehicleRoute> routes = new ArrayList<VehicleRoute>(); List<VehicleRoute> routes = new ArrayList<VehicleRoute>();
@ -74,7 +74,7 @@ final class BestInsertionConc implements InsertionStrategy{
} }
private static Logger logger = Logger.getLogger(BestInsertionConc.class); private static Logger logger = Logger.getLogger(BestInsertionConcurrent.class);
private Random random = RandomNumberGeneration.getRandom(); private Random random = RandomNumberGeneration.getRandom();
@ -102,7 +102,7 @@ final class BestInsertionConc implements InsertionStrategy{
this.random = random; this.random = random;
} }
public BestInsertionConc(JobInsertionCostsCalculator jobInsertionCalculator, ExecutorService executorService, int nuOfBatches) { public BestInsertionConcurrent(JobInsertionCostsCalculator jobInsertionCalculator, ExecutorService executorService, int nuOfBatches) {
super(); super();
this.insertionsListeners = new InsertionListeners(); this.insertionsListeners = new InsertionListeners();
this.executor = executorService; this.executor = executorService;

View file

@ -27,8 +27,10 @@ import basics.route.Driver;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator{ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator{
private static Logger log = Logger.getLogger(CalculatesServiceInsertionWithTimeScheduling.class); private static Logger log = Logger.getLogger(CalculatesServiceInsertionWithTimeScheduling.class);
private JobInsertionCostsCalculator jic; private JobInsertionCostsCalculator jic;
@ -67,9 +69,13 @@ class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsC
for(int i=0;i<nOfDepartureTimes;i++){ for(int i=0;i<nOfDepartureTimes;i++){
double neighborStartTime_earlier = currentStart - (i+1)*timeSlice; double neighborStartTime_earlier = currentStart - (i+1)*timeSlice;
if(neighborStartTime_earlier > earliestDeparture) vehicleDepartureTimes.add(neighborStartTime_earlier); // if(neighborStartTime_earlier > earliestDeparture) {
vehicleDepartureTimes.add(neighborStartTime_earlier);
// }
double neighborStartTime_later = currentStart + (i+1)*timeSlice; double neighborStartTime_later = currentStart + (i+1)*timeSlice;
if(neighborStartTime_later < latestEnd) vehicleDepartureTimes.add(neighborStartTime_later); // if(neighborStartTime_later < latestEnd) {
vehicleDepartureTimes.add(neighborStartTime_later);
// }
} }
InsertionData bestIData = null; InsertionData bestIData = null;

View file

@ -40,7 +40,7 @@ import basics.route.VehicleFleetManager;
import basics.route.TourActivity.JobActivity; import basics.route.TourActivity.JobActivity;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
final class Gendreau implements SearchStrategyModule{ public final class Gendreau implements SearchStrategyModule{
private final static Logger log = Logger.getLogger(Gendreau.class); private final static Logger log = Logger.getLogger(Gendreau.class);
@ -64,7 +64,7 @@ final class Gendreau implements SearchStrategyModule{
this.shareOfJobsToRuin = shareOfJobsToRuin; this.shareOfJobsToRuin = shareOfJobsToRuin;
} }
public Gendreau(VehicleRoutingProblem vrp, RuinStrategy ruin, InsertionStrategy insertionStrategy) { public Gendreau(VehicleRoutingProblem vrp, RuinStrategy ruin, InsertionStrategy insertionStrategy, VehicleFleetManager vehicleFleetManager) {
super(); super();
InsertionListeners insertionListeners = new InsertionListeners(); InsertionListeners insertionListeners = new InsertionListeners();
insertionListeners.addAllListeners(insertionStrategy.getListeners()); insertionListeners.addAllListeners(insertionStrategy.getListeners());
@ -72,6 +72,7 @@ final class Gendreau implements SearchStrategyModule{
this.ruin = ruin; this.ruin = ruin;
this.vrp = vrp; this.vrp = vrp;
this.insertionStrategy = insertionStrategy; this.insertionStrategy = insertionStrategy;
this.fleetManager = vehicleFleetManager;
} }
@Override @Override
@ -88,10 +89,10 @@ final class Gendreau implements SearchStrategyModule{
this.nOfIterations = nOfIterations; this.nOfIterations = nOfIterations;
} }
public void setFleetManager(VehicleFleetManager vehicleFleetManager) { // public void setFleetManager(VehicleFleetManager vehicleFleetManager) {
this.fleetManager = vehicleFleetManager; // this.fleetManager = vehicleFleetManager;
//
} // }
@Override @Override
public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) { public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) {
@ -119,14 +120,14 @@ final class Gendreau implements SearchStrategyModule{
VehicleRoute emptyRoute1 = VehicleRoute.emptyRoute(); VehicleRoute emptyRoute1 = VehicleRoute.emptyRoute();
copiedRoutes.add(emptyRoute1); copiedRoutes.add(emptyRoute1);
insertionStrategy.insertJobs(Arrays.asList(emptyRoute1), Arrays.asList(targetJob)); insertionStrategy.insertJobs(Arrays.asList(emptyRoute1), Arrays.asList(targetJob));
// routeAlgorithm.insertJob(targetJob, routeAlgorithm.calculateBestInsertion(emptyRoute1, targetJob, Double.MAX_VALUE), emptyRoute1);
unassignedJobs.remove(targetJob); unassignedJobs.remove(targetJob);
VehicleRoute emptyRoute2 = VehicleRoute.emptyRoute(); VehicleRoute emptyRoute2 = VehicleRoute.emptyRoute();
copiedRoutes.add(emptyRoute2); copiedRoutes.add(emptyRoute2);
Job job2 = jobsInRoute.get(1); Job job2 = jobsInRoute.get(1);
insertionStrategy.insertJobs(Arrays.asList(emptyRoute2), Arrays.asList(job2)); insertionStrategy.insertJobs(Arrays.asList(emptyRoute2), Arrays.asList(job2));
// routeAlgorithm.insertJob(job2, routeAlgorithm.calculateBestInsertion(emptyRoute2, job2, Double.MAX_VALUE), emptyRoute2);
unassignedJobs.remove(job2); unassignedJobs.remove(job2);
insertionStrategy.insertJobs(copiedRoutes, unassignedJobs); insertionStrategy.insertJobs(copiedRoutes, unassignedJobs);

View file

@ -1,7 +0,0 @@
package algorithms;
public interface InsertionStrategyBuilder {
public InsertionStrategy build();
}

View file

@ -18,7 +18,7 @@ package algorithms;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
interface InsertionStrategyFactory { public interface InsertionStrategyFactory {
public InsertionStrategy createStrategy(VehicleRoutingProblem vrp); public InsertionStrategy createStrategy(VehicleRoutingProblem vrp);

View file

@ -49,6 +49,194 @@ import basics.route.VehicleRoute;
*/ */
final class RuinRadial implements RuinStrategy { final class RuinRadial implements RuinStrategy {
static interface JobNeighborhoods {
public Iterator<Job> getNearestNeighborsIterator(int nNeighbors, Job neighborTo);
}
static class NeighborhoodIterator implements Iterator<Job>{
private static Logger log = Logger.getLogger(NeighborhoodIterator.class);
private Iterator<ReferencedJob> jobIter;
private int nJobs;
private int jobCount = 0;
public NeighborhoodIterator(Iterator<ReferencedJob> jobIter, int nJobs) {
super();
this.jobIter = jobIter;
this.nJobs = nJobs;
}
@Override
public boolean hasNext() {
if(jobCount < nJobs){
boolean hasNext = jobIter.hasNext();
if(!hasNext) log.warn("more jobs are requested then iterator can iterate over. probably the number of neighbors memorized in JobNeighborhoods is too small");
return hasNext;
}
return false;
}
@Override
public Job next() {
ReferencedJob next = jobIter.next();
jobCount++;
return next.getJob();
}
@Override
public void remove() {
jobIter.remove();
}
}
static class JobNeighborhoodsImpl implements JobNeighborhoods {
private static Logger logger = Logger.getLogger(JobNeighborhoodsImpl.class);
private VehicleRoutingProblem vrp;
private Map<String, TreeSet<ReferencedJob>> distanceNodeTree = new HashMap<String, TreeSet<ReferencedJob>>();
private JobDistance jobDistance;
public JobNeighborhoodsImpl(VehicleRoutingProblem vrp, JobDistance jobDistance) {
super();
this.vrp = vrp;
this.jobDistance = jobDistance;
logger.info("intialise " + this);
}
public Iterator<Job> getNearestNeighborsIterator(int nNeighbors, Job neighborTo){
TreeSet<ReferencedJob> tree = distanceNodeTree.get(neighborTo.getId());
Iterator<ReferencedJob> descendingIterator = tree.iterator();
return new NeighborhoodIterator(descendingIterator, nNeighbors);
}
public void initialise(){
logger.info("calculates and memorizes distances from EACH job to EACH job --> n^2 calculations");
calculateDistancesFromJob2Job();
}
private void calculateDistancesFromJob2Job() {
logger.info("preprocess distances between locations ...");
StopWatch stopWatch = new StopWatch();
stopWatch.start();
int nuOfDistancesStored = 0;
for (Job i : vrp.getJobs().values()) {
TreeSet<ReferencedJob> treeSet = new TreeSet<ReferencedJob>(
new Comparator<ReferencedJob>() {
@Override
public int compare(ReferencedJob o1, ReferencedJob o2) {
if (o1.getDistance() <= o2.getDistance()) {
return -1;
} else {
return 1;
}
}
});
distanceNodeTree.put(i.getId(), treeSet);
for (Job j : vrp.getJobs().values()) {
if(i==j) continue;
double distance = jobDistance.getDistance(i, j);
ReferencedJob refNode = new ReferencedJob(j, distance);
treeSet.add(refNode);
nuOfDistancesStored++;
}
}
stopWatch.stop();
logger.info("preprocessing comp-time: " + stopWatch + "; nuOfDistances stored: " + nuOfDistancesStored + "; estimated memory: " +
(distanceNodeTree.keySet().size()*64+nuOfDistancesStored*92) + " bytes");
}
}
static class JobNeighborhoodsImplWithCapRestriction implements JobNeighborhoods {
private static Logger logger = Logger.getLogger(JobNeighborhoodsImpl.class);
private VehicleRoutingProblem vrp;
private Map<String, TreeSet<ReferencedJob>> distanceNodeTree = new HashMap<String, TreeSet<ReferencedJob>>();
private JobDistance jobDistance;
private int capacity;
public JobNeighborhoodsImplWithCapRestriction(VehicleRoutingProblem vrp, JobDistance jobDistance, int capacity) {
super();
this.vrp = vrp;
this.jobDistance = jobDistance;
this.capacity = capacity;
logger.info("intialise " + this);
}
public Iterator<Job> getNearestNeighborsIterator(int nNeighbors, Job neighborTo){
TreeSet<ReferencedJob> tree = distanceNodeTree.get(neighborTo.getId());
Iterator<ReferencedJob> descendingIterator = tree.iterator();
return new NeighborhoodIterator(descendingIterator, nNeighbors);
}
public void initialise(){
logger.info("calculates distances from EACH job to EACH job --> n^2="+Math.pow(vrp.getJobs().values().size(), 2) + " calculations, but 'only' "+(vrp.getJobs().values().size()*capacity)+ " are cached.");
calculateDistancesFromJob2Job();
}
private void calculateDistancesFromJob2Job() {
logger.info("preprocess distances between locations ...");
StopWatch stopWatch = new StopWatch();
stopWatch.start();
int nuOfDistancesStored = 0;
for (Job i : vrp.getJobs().values()) {
TreeSet<ReferencedJob> treeSet = new TreeSet<ReferencedJob>(
new Comparator<ReferencedJob>() {
@Override
public int compare(ReferencedJob o1, ReferencedJob o2) {
if (o1.getDistance() <= o2.getDistance()) {
return -1;
} else {
return 1;
}
}
});
distanceNodeTree.put(i.getId(), treeSet);
for (Job j : vrp.getJobs().values()) {
if(i==j) continue;
double distance = jobDistance.getDistance(i, j);
ReferencedJob refNode = new ReferencedJob(j, distance);
if(treeSet.size() < capacity){
treeSet.add(refNode);
nuOfDistancesStored++;
}
else{
if(treeSet.last().getDistance() > distance){
treeSet.pollLast();
treeSet.add(refNode);
}
}
}
assert treeSet.size() <= capacity : "treeSet.size() is bigger than specified capacity";
}
stopWatch.stop();
logger.info("preprocessing comp-time: " + stopWatch + "; nuOfDistances stored: " + nuOfDistancesStored + "; estimated memory: " +
(distanceNodeTree.keySet().size()*64+nuOfDistancesStored*92) + " bytes");
}
@Override
public String toString() {
return "[name=neighborhoodWithCapRestriction][capacity="+capacity+"]";
}
}
static class ReferencedJob { static class ReferencedJob {
private Job job; private Job job;
private double distance; private double distance;
@ -74,14 +262,12 @@ final class RuinRadial implements RuinStrategy {
private double fractionOfAllNodes2beRuined; private double fractionOfAllNodes2beRuined;
private Map<String, TreeSet<ReferencedJob>> distanceNodeTree = new HashMap<String, TreeSet<ReferencedJob>>();
private Random random = RandomNumberGeneration.getRandom(); private Random random = RandomNumberGeneration.getRandom();
private JobDistance jobDistance;
private RuinListeners ruinListeners; private RuinListeners ruinListeners;
private JobNeighborhoods jobNeighborhoods;
public void setRandom(Random random) { public void setRandom(Random random) {
this.random = random; this.random = random;
} }
@ -96,41 +282,46 @@ final class RuinRadial implements RuinStrategy {
public RuinRadial(VehicleRoutingProblem vrp, double fraction2beRemoved, JobDistance jobDistance) { public RuinRadial(VehicleRoutingProblem vrp, double fraction2beRemoved, JobDistance jobDistance) {
super(); super();
this.vrp = vrp; this.vrp = vrp;
this.jobDistance = jobDistance;
this.fractionOfAllNodes2beRuined = fraction2beRemoved; this.fractionOfAllNodes2beRuined = fraction2beRemoved;
ruinListeners = new RuinListeners(); ruinListeners = new RuinListeners();
calculateDistancesFromJob2Job(); int nJobsToMemorize = (int) Math.ceil(vrp.getJobs().values().size()*fraction2beRemoved);
JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, nJobsToMemorize);
jobNeighborhoodsImpl.initialise();
jobNeighborhoods = jobNeighborhoodsImpl;
logger.info("intialise " + this); logger.info("intialise " + this);
} //<<<<<<< HEAD
// }
private void calculateDistancesFromJob2Job() { //
logger.info("preprocess distances between locations ..."); // private void calculateDistancesFromJob2Job() {
StopWatch stopWatch = new StopWatch(); // logger.info("preprocess distances between locations ...");
stopWatch.start(); // StopWatch stopWatch = new StopWatch();
int nuOfDistancesStored = 0; // stopWatch.start();
for (Job i : vrp.getJobs().values()) { // int nuOfDistancesStored = 0;
TreeSet<ReferencedJob> treeSet = new TreeSet<ReferencedJob>( // for (Job i : vrp.getJobs().values()) {
new Comparator<ReferencedJob>() { // TreeSet<ReferencedJob> treeSet = new TreeSet<ReferencedJob>(
@Override // new Comparator<ReferencedJob>() {
public int compare(ReferencedJob o1, ReferencedJob o2) { // @Override
if (o1.getDistance() <= o2.getDistance()) { // public int compare(ReferencedJob o1, ReferencedJob o2) {
return 1; // if (o1.getDistance() <= o2.getDistance()) {
} else { // return 1;
return -1; // } else {
} // return -1;
} // }
}); // }
distanceNodeTree.put(i.getId(), treeSet); // });
for (Job j : vrp.getJobs().values()) { // distanceNodeTree.put(i.getId(), treeSet);
double distance = jobDistance.getDistance(i, j); // for (Job j : vrp.getJobs().values()) {
ReferencedJob refNode = new ReferencedJob(j, distance); // double distance = jobDistance.getDistance(i, j);
treeSet.add(refNode); // ReferencedJob refNode = new ReferencedJob(j, distance);
nuOfDistancesStored++; // treeSet.add(refNode);
} // nuOfDistancesStored++;
} // }
stopWatch.stop(); // }
logger.info("preprocessing comp-time: " + stopWatch + "; nuOfDistances stored: " + nuOfDistancesStored + "; estimated memory: " + // stopWatch.stop();
(distanceNodeTree.keySet().size()*64+nuOfDistancesStored*92) + " bytes"); // logger.info("preprocessing comp-time: " + stopWatch + "; nuOfDistances stored: " + nuOfDistancesStored + "; estimated memory: " +
// (distanceNodeTree.keySet().size()*64+nuOfDistancesStored*92) + " bytes");
//=======
//>>>>>>> refs/heads/master
} }
@Override @Override
@ -145,11 +336,11 @@ final class RuinRadial implements RuinStrategy {
@Override @Override
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes) { public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes) {
if(vehicleRoutes.isEmpty()){ if(vehicleRoutes.isEmpty()){
return Collections.EMPTY_LIST; return Collections.emptyList();
} }
int nOfJobs2BeRemoved = getNuOfJobs2BeRemoved(); int nOfJobs2BeRemoved = getNuOfJobs2BeRemoved();
if (nOfJobs2BeRemoved == 0) { if (nOfJobs2BeRemoved == 0) {
return Collections.EMPTY_LIST; return Collections.emptyList();
} }
Job randomJob = pickRandomJob(); Job randomJob = pickRandomJob();
Collection<Job> unassignedJobs = ruin(vehicleRoutes,randomJob,nOfJobs2BeRemoved); Collection<Job> unassignedJobs = ruin(vehicleRoutes,randomJob,nOfJobs2BeRemoved);
@ -162,27 +353,30 @@ final class RuinRadial implements RuinStrategy {
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved){ public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved){
ruinListeners.ruinStarts(vehicleRoutes); ruinListeners.ruinStarts(vehicleRoutes);
List<Job> unassignedJobs = new ArrayList<Job>(); List<Job> unassignedJobs = new ArrayList<Job>();
TreeSet<ReferencedJob> tree = distanceNodeTree.get(targetJob.getId()); int nNeighbors = nOfJobs2BeRemoved - 1;
Iterator<ReferencedJob> descendingIterator = tree.descendingIterator(); removeJob(targetJob,vehicleRoutes);
int counter = 0; unassignedJobs.add(targetJob);
while (descendingIterator.hasNext() && counter < nOfJobs2BeRemoved) { Iterator<Job> neighborhoodIterator = jobNeighborhoods.getNearestNeighborsIterator(nNeighbors, targetJob);
ReferencedJob refJob = descendingIterator.next(); while(neighborhoodIterator.hasNext()){
Job job = refJob.getJob(); Job job = neighborhoodIterator.next();
removeJob(job,vehicleRoutes);
unassignedJobs.add(job); unassignedJobs.add(job);
counter++;
boolean removed = false;
for (VehicleRoute route : vehicleRoutes) {
removed = route.getTourActivities().removeJob(job);;
if (removed) {
ruinListeners.removed(job,route);
break;
}
}
} }
ruinListeners.ruinEnds(vehicleRoutes, unassignedJobs); ruinListeners.ruinEnds(vehicleRoutes, unassignedJobs);
return unassignedJobs; return unassignedJobs;
} }
private void removeJob(Job job, Collection<VehicleRoute> vehicleRoutes) {
boolean removed = false;
for (VehicleRoute route : vehicleRoutes) {
removed = route.getTourActivities().removeJob(job);;
if (removed) {
ruinListeners.removed(job,route);
break;
}
}
}
private Job pickRandomJob() { private Job pickRandomJob() {
int totNuOfJobs = vrp.getJobs().values().size(); int totNuOfJobs = vrp.getJobs().values().size();
int randomIndex = random.nextInt(totNuOfJobs); int randomIndex = random.nextInt(totNuOfJobs);

View file

@ -26,6 +26,7 @@ public class VehicleRoutingAlgorithmFactoryImpl implements VehicleRoutingAlgorit
public VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vrp) { public VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vrp) {
this.stateManager.addActivityVisitor(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), this.stateManager)); this.stateManager.addActivityVisitor(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), this.stateManager));
this.stateManager.addActivityVisitor(new UpdateMaxLoad(this.stateManager)); this.stateManager.addActivityVisitor(new UpdateMaxLoad(this.stateManager));
this.stateManager.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
VehicleRoutingAlgorithm algorithm = new VehicleRoutingAlgorithm(vrp, searchStrategyManager); VehicleRoutingAlgorithm algorithm = new VehicleRoutingAlgorithm(vrp, searchStrategyManager);
algorithm.getAlgorithmListeners().addListener(stateManager); algorithm.getAlgorithmListeners().addListener(stateManager);
algorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager); algorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);

View file

@ -814,10 +814,9 @@ public class VehicleRoutingAlgorithms {
insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager); insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager);
algorithmListeners.addAll(prioListeners); algorithmListeners.addAll(prioListeners);
} }
Gendreau gendreau = new Gendreau(vrp, ruin, insertion); Gendreau gendreau = new Gendreau(vrp, ruin, insertion, vehicleFleetManager);
gendreau.setShareOfJobsToRuin(share); gendreau.setShareOfJobsToRuin(share);
gendreau.setNuOfIterations(iterations); gendreau.setNuOfIterations(iterations);
gendreau.setFleetManager(vehicleFleetManager);
definedClasses.put(strategyModuleKey, gendreau); definedClasses.put(strategyModuleKey, gendreau);
return gendreau; return gendreau;
} }

View file

@ -25,6 +25,15 @@ import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.algo.SearchStrategy.DiscoveredSolution; import basics.algo.SearchStrategy.DiscoveredSolution;
/**
* Breaks algorithm prematurely based on specified time.
*
* <p>Note, TimeBreaker must be registered as AlgorithmListener <br>
* <code>agorithm.getAlgorithmListeners().addListener(this);</code>
*
* @author stefan
*
*/
public class TimeBreaker implements PrematureAlgorithmBreaker, AlgorithmStartsListener{ public class TimeBreaker implements PrematureAlgorithmBreaker, AlgorithmStartsListener{
private static Logger logger = Logger.getLogger(TimeBreaker.class); private static Logger logger = Logger.getLogger(TimeBreaker.class);
@ -33,9 +42,18 @@ public class TimeBreaker implements PrematureAlgorithmBreaker, AlgorithmStartsLi
private double startTime; private double startTime;
public TimeBreaker(double time) { /**
* Constructs TimeBreaker that breaks algorithm prematurely based on specified time.
*
* <p>Note, TimeBreaker must be registered as AlgorithmListener <br>
* <code>agorithm.getAlgorithmListeners().addListener(this);</code>
*
* @author stefan
*
*/
public TimeBreaker(double time_in_seconds) {
super(); super();
this.timeThreshold = time; this.timeThreshold = time_in_seconds;
logger.info("initialise " + this); logger.info("initialise " + this);
} }

View file

@ -28,6 +28,16 @@ import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.algo.SearchStrategy.DiscoveredSolution; import basics.algo.SearchStrategy.DiscoveredSolution;
/**
* Breaks algorithm prematurely based on variationCoefficient.
*
* <p>Note that this must be registered in algorithm<br>
* <code>algorithm.getAlgorithmListeners().addListener(this);</code>
*
*
* @author stefan
*
*/
public class VariationCoefficientBreaker implements PrematureAlgorithmBreaker, IterationStartsListener, AlgorithmStartsListener, IterationEndsListener{ public class VariationCoefficientBreaker implements PrematureAlgorithmBreaker, IterationStartsListener, AlgorithmStartsListener, IterationEndsListener{
private static Logger logger = Logger.getLogger(VariationCoefficientBreaker.class); private static Logger logger = Logger.getLogger(VariationCoefficientBreaker.class);
@ -42,6 +52,16 @@ public class VariationCoefficientBreaker implements PrematureAlgorithmBreaker, I
private VehicleRoutingProblemSolution lastAccepted = null; private VehicleRoutingProblemSolution lastAccepted = null;
/**
* Breaks algorithm prematurely based on variationCoefficient.
*
* <p>Note that this must be registered in algorithm<br>
* <code>algorithm.getAlgorithmListeners().addListener(this);</code>
*
*
* @author stefan
*
*/
public VariationCoefficientBreaker(int nuOfIterations, double variationCoefficientThreshold) { public VariationCoefficientBreaker(int nuOfIterations, double variationCoefficientThreshold) {
super(); super();
this.nuOfIterations = nuOfIterations; this.nuOfIterations = nuOfIterations;

View file

@ -62,6 +62,5 @@ public interface VehicleRoutingActivityCosts {
*/ */
public double getActivityCost(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle); public double getActivityCost(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle);
// public Parameter getParameter(TourActivity tourAct, Vehicle vehicle, Driver driver);
} }

View file

@ -22,6 +22,12 @@ import basics.VehicleRoutingProblemSolution;
public class Solutions { public class Solutions {
/**
*
* @deprecated use bestOf instead.
* @param solutions
* @return
*/
@Deprecated @Deprecated
public static VehicleRoutingProblemSolution getBest(Collection<VehicleRoutingProblemSolution> solutions){ public static VehicleRoutingProblemSolution getBest(Collection<VehicleRoutingProblemSolution> solutions){
VehicleRoutingProblemSolution best = null; VehicleRoutingProblemSolution best = null;

View file

@ -87,8 +87,7 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
int nuOfThreads = 10; int nuOfThreads = 10;
executorService = Executors.newFixedThreadPool(nuOfThreads); executorService = Executors.newFixedThreadPool(nuOfThreads);
BestInsertionBuilder bestIBuilder = new BestInsertionBuilder(vrp, fleetManager, stateManager); BestInsertionBuilder bestIBuilder = new BestInsertionBuilder(vrp, fleetManager, stateManager,constraintManager);
bestIBuilder.setConstraintManager(constraintManager);
bestIBuilder.setConcurrentMode(executorService, nuOfThreads); bestIBuilder.setConcurrentMode(executorService, nuOfThreads);
InsertionStrategy bestInsertion = bestIBuilder.build(); InsertionStrategy bestInsertion = bestIBuilder.build();
@ -187,7 +186,7 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size()); // System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
vra.addInitialSolution(iniSolution); vra.addInitialSolution(iniSolution);
vra.setNuOfIterations(100); vra.setNuOfIterations(10);
// vra.setPrematureBreak(500); // vra.setPrematureBreak(500);
} }

View file

@ -201,8 +201,7 @@ public class GendreauPostOptTest {
InsertionStrategy insertionStrategy = new BestInsertion(insertionCalc); InsertionStrategy insertionStrategy = new BestInsertion(insertionCalc);
insertionStrategy.addListener(stateUpdater); insertionStrategy.addListener(stateUpdater);
insertionStrategy.addListener(new VehicleSwitched(fleetManager)); insertionStrategy.addListener(new VehicleSwitched(fleetManager));
Gendreau postOpt = new Gendreau(vrp, radialRuin, insertionStrategy); Gendreau postOpt = new Gendreau(vrp, radialRuin, insertionStrategy, fleetManager);
postOpt.setFleetManager(fleetManager);
VehicleRoutingProblemSolution newSolution = postOpt.runAndGetSolution(sol); VehicleRoutingProblemSolution newSolution = postOpt.runAndGetSolution(sol);
newSolution.setCost(getCosts(newSolution,states)); newSolution.setCost(getCosts(newSolution,states));
@ -261,10 +260,10 @@ public class GendreauPostOptTest {
InsertionStrategy insertionStrategy = new BestInsertion(insertionCalc); InsertionStrategy insertionStrategy = new BestInsertion(insertionCalc);
insertionStrategy.addListener(stateUpdater); insertionStrategy.addListener(stateUpdater);
insertionStrategy.addListener(new VehicleSwitched(fleetManager)); insertionStrategy.addListener(new VehicleSwitched(fleetManager));
Gendreau postOpt = new Gendreau(vrp, radialRuin, insertionStrategy); Gendreau postOpt = new Gendreau(vrp, radialRuin, insertionStrategy, fleetManager);
postOpt.setShareOfJobsToRuin(1.0); postOpt.setShareOfJobsToRuin(1.0);
postOpt.setNuOfIterations(1); postOpt.setNuOfIterations(1);
postOpt.setFleetManager(fleetManager);
// postOpt.setWithFix(withFixCost); // postOpt.setWithFix(withFixCost);
VehicleRoutingProblemSolution newSolution = postOpt.runAndGetSolution(sol); VehicleRoutingProblemSolution newSolution = postOpt.runAndGetSolution(sol);
newSolution.setCost(getCosts(newSolution,states)); newSolution.setCost(getCosts(newSolution,states));

View file

@ -0,0 +1,110 @@
package algorithms;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import util.Coordinate;
import algorithms.RuinRadial.JobNeighborhoodsImpl;
import basics.Job;
import basics.Service;
import basics.VehicleRoutingProblem;
public class JobNeighborhoodsImplTest {
VehicleRoutingProblem vrp;
JobDistance jobDistance;
Service target;
Service s2;
Service s3;
Service s4;
Service s5;
Service s6;
Service s7;
@Before
public void doBefore(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
target = Service.Builder.newInstance("s1", 1).setCoord(Coordinate.newInstance(0, 5)).build();
s2 = Service.Builder.newInstance("s2", 1).setCoord(Coordinate.newInstance(0, 4)).build();
s3 = Service.Builder.newInstance("s3", 1).setCoord(Coordinate.newInstance(0, 3)).build();
s4 = Service.Builder.newInstance("s4", 1).setCoord(Coordinate.newInstance(0, 2)).build();
s5 = Service.Builder.newInstance("s5", 1).setCoord(Coordinate.newInstance(0, 6)).build();
s6 = Service.Builder.newInstance("s6", 1).setCoord(Coordinate.newInstance(0, 7)).build();
s7 = Service.Builder.newInstance("s7", 1).setCoord(Coordinate.newInstance(0, 8)).build();
vrp = builder.addJob(target).addJob(s2).addJob(s3).addJob(s4).addJob(s5).addJob(s6).addJob(s7).build();
jobDistance = new EuclideanServiceDistance();
}
@Test
public void whenRequestingNeighborhoodOfTargetJob_nNeighborsShouldBeTwo(){
JobNeighborhoodsImpl jn = new JobNeighborhoodsImpl(vrp, jobDistance);
jn.initialise();
Iterator<Job> iter = jn.getNearestNeighborsIterator(2, target);
List<Service> services = new ArrayList<Service>();
while(iter.hasNext()){
services.add((Service) iter.next());
}
assertEquals(2,services.size());
}
@Test
public void whenRequestingNeighborhoodOfTargetJob_s2ShouldBeNeighbor(){
JobNeighborhoodsImpl jn = new JobNeighborhoodsImpl(vrp, jobDistance);
jn.initialise();
Iterator<Job> iter = jn.getNearestNeighborsIterator(2, target);
List<Service> services = new ArrayList<Service>();
while(iter.hasNext()){
services.add((Service) iter.next());
}
assertTrue(services.contains(s2));
}
@Test
public void whenRequestingNeighborhoodOfTargetJob_s4ShouldBeNeighbor(){
JobNeighborhoodsImpl jn = new JobNeighborhoodsImpl(vrp, jobDistance);
jn.initialise();
Iterator<Job> iter = jn.getNearestNeighborsIterator(2, target);
List<Service> services = new ArrayList<Service>();
while(iter.hasNext()){
services.add((Service) iter.next());
}
assertTrue(services.contains(s5));
}
@Test
public void whenRequestingNeighborhoodOfTargetJob_sizeShouldBe4(){
JobNeighborhoodsImpl jn = new JobNeighborhoodsImpl(vrp, jobDistance);
jn.initialise();
Iterator<Job> iter = jn.getNearestNeighborsIterator(4, target);
List<Service> services = new ArrayList<Service>();
while(iter.hasNext()){
services.add((Service) iter.next());
}
assertEquals(4,services.size());
}
@Test
public void whenRequestingMoreNeighborsThanExisting_itShouldReturnMaxNeighbors(){
JobNeighborhoodsImpl jn = new JobNeighborhoodsImpl(vrp, jobDistance);
jn.initialise();
Iterator<Job> iter = jn.getNearestNeighborsIterator(100, target);
List<Service> services = new ArrayList<Service>();
while(iter.hasNext()){
services.add((Service) iter.next());
}
assertEquals(6,services.size());
}
}

View file

@ -0,0 +1,111 @@
package algorithms;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import util.Coordinate;
import algorithms.RuinRadial.JobNeighborhoodsImpl;
import algorithms.RuinRadial.JobNeighborhoodsImplWithCapRestriction;
import basics.Job;
import basics.Service;
import basics.VehicleRoutingProblem;
public class JobNeighborhoodsWithCapRestrictionImplTest {
VehicleRoutingProblem vrp;
JobDistance jobDistance;
Service target;
Service s2;
Service s3;
Service s4;
Service s5;
Service s6;
Service s7;
@Before
public void doBefore(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
target = Service.Builder.newInstance("s1", 1).setCoord(Coordinate.newInstance(0, 5)).build();
s2 = Service.Builder.newInstance("s2", 1).setCoord(Coordinate.newInstance(0, 4)).build();
s3 = Service.Builder.newInstance("s3", 1).setCoord(Coordinate.newInstance(0, 3)).build();
s4 = Service.Builder.newInstance("s4", 1).setCoord(Coordinate.newInstance(0, 2)).build();
s5 = Service.Builder.newInstance("s5", 1).setCoord(Coordinate.newInstance(0, 6)).build();
s6 = Service.Builder.newInstance("s6", 1).setCoord(Coordinate.newInstance(0, 7)).build();
s7 = Service.Builder.newInstance("s7", 1).setCoord(Coordinate.newInstance(0, 8)).build();
vrp = builder.addJob(target).addJob(s2).addJob(s3).addJob(s4).addJob(s5).addJob(s6).addJob(s7).build();
jobDistance = new EuclideanServiceDistance();
}
@Test
public void whenRequestingNeighborhoodOfTargetJob_nNeighborsShouldBeTwo(){
JobNeighborhoodsImplWithCapRestriction jn = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, 2);
jn.initialise();
Iterator<Job> iter = jn.getNearestNeighborsIterator(2, target);
List<Service> services = new ArrayList<Service>();
while(iter.hasNext()){
services.add((Service) iter.next());
}
assertEquals(2,services.size());
}
@Test
public void whenRequestingNeighborhoodOfTargetJob_s2ShouldBeNeighbor(){
JobNeighborhoodsImplWithCapRestriction jn = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, 2);
jn.initialise();
Iterator<Job> iter = jn.getNearestNeighborsIterator(2, target);
List<Service> services = new ArrayList<Service>();
while(iter.hasNext()){
services.add((Service) iter.next());
}
assertTrue(services.contains(s2));
}
@Test
public void whenRequestingNeighborhoodOfTargetJob_s4ShouldBeNeighbor(){
JobNeighborhoodsImplWithCapRestriction jn = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, 2);
jn.initialise();
Iterator<Job> iter = jn.getNearestNeighborsIterator(2, target);
List<Service> services = new ArrayList<Service>();
while(iter.hasNext()){
services.add((Service) iter.next());
}
assertTrue(services.contains(s5));
}
@Test
public void whenRequestingNeighborhoodOfTargetJob_sizeShouldBe4(){
JobNeighborhoodsImplWithCapRestriction jn = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, 4);
jn.initialise();
Iterator<Job> iter = jn.getNearestNeighborsIterator(4, target);
List<Service> services = new ArrayList<Service>();
while(iter.hasNext()){
services.add((Service) iter.next());
}
assertEquals(4,services.size());
}
@Test
public void whenRequestingMoreNeighborsThanExisting_itShouldReturnMaxNeighbors(){
JobNeighborhoodsImplWithCapRestriction jn = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, 2);
jn.initialise();
Iterator<Job> iter = jn.getNearestNeighborsIterator(100, target);
List<Service> services = new ArrayList<Service>();
while(iter.hasNext()){
services.add((Service) iter.next());
}
assertEquals(2,services.size());
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,140 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package examples;
import java.io.File;
import java.util.Collection;
import org.apache.commons.configuration.XMLConfiguration;
import util.Coordinate;
import util.Solutions;
import algorithms.VehicleRoutingAlgorithms;
import analysis.SolutionPlotter;
import analysis.SolutionPrinter;
import analysis.SolutionPrinter.Print;
import basics.Service;
import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution;
import basics.io.AlgorithmConfig;
import basics.io.VrpXMLWriter;
import basics.route.Vehicle;
import basics.route.VehicleImpl;
import basics.route.VehicleImpl.Builder;
import basics.route.VehicleType;
import basics.route.VehicleTypeImpl;
public class ConfigureAlgorithmInCodeInsteadOfPerXml {
public static void main(String[] args) {
/*
* some preparation - create output folder
*/
File dir = new File("output");
// if the directory does not exist, create it
if (!dir.exists()){
System.out.println("creating directory ./output");
boolean result = dir.mkdir();
if(result) System.out.println("./output created");
}
/*
* get a vehicle type-builder and build a type with the typeId "vehicleType" and a capacity of 2
*/
VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType", 2);
VehicleType vehicleType = vehicleTypeBuilder.build();
/*
* get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType"
*/
Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle");
vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10));
vehicleBuilder.setType(vehicleType);
Vehicle vehicle = vehicleBuilder.build();
/*
* build services at the required locations, each with a capacity-demand of 1.
*/
Service service1 = Service.Builder.newInstance("1", 1).setCoord(Coordinate.newInstance(5, 7)).build();
Service service2 = Service.Builder.newInstance("2", 1).setCoord(Coordinate.newInstance(5, 13)).build();
Service service3 = Service.Builder.newInstance("3", 1).setCoord(Coordinate.newInstance(15, 7)).build();
Service service4 = Service.Builder.newInstance("4", 1).setCoord(Coordinate.newInstance(15, 13)).build();
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
vrpBuilder.addVehicle(vehicle);
vrpBuilder.addService(service1).addService(service2).addService(service3).addService(service4);
VehicleRoutingProblem problem = vrpBuilder.build();
/*
* get the algorithm out-of-the-box.
*/
AlgorithmConfig algorithmConfig = getAlgorithmConfig();
VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.createAlgorithm(problem,algorithmConfig);
/*
* and search a solution
*/
Collection<VehicleRoutingProblemSolution> solutions = algorithm.searchSolutions();
/*
* get the best
*/
VehicleRoutingProblemSolution bestSolution = Solutions.getBest(solutions);
new VrpXMLWriter(problem, solutions).write("output/problem-with-solution.xml");
SolutionPrinter.print(bestSolution,Print.VERBOSE);
/*
* plot
*/
SolutionPlotter.plotSolutionAsPNG(problem, bestSolution, "output/solution.png", "solution");
}
private static AlgorithmConfig getAlgorithmConfig() {
AlgorithmConfig config = new AlgorithmConfig();
XMLConfiguration xmlConfig = config.getXMLConfiguration();
xmlConfig.setProperty("iterations", 2000);
xmlConfig.setProperty("construction.insertion[@name]","bestInsertion");
xmlConfig.setProperty("strategy.memory", 1);
String searchStrategy = "strategy.searchStrategies.searchStrategy";
xmlConfig.setProperty(searchStrategy + "(0).selector[@name]","selectBest");
xmlConfig.setProperty(searchStrategy + "(0).acceptor[@name]","acceptNewRemoveWorst");
xmlConfig.setProperty(searchStrategy + "(0).modules.module(0)[@name]","ruin_and_recreate");
xmlConfig.setProperty(searchStrategy + "(0).modules.module(0).ruin[@name]","randomRuin");
xmlConfig.setProperty(searchStrategy + "(0).modules.module(0).ruin.share","0.3");
xmlConfig.setProperty(searchStrategy + "(0).modules.module(0).insertion[@name]","bestInsertion");
xmlConfig.setProperty(searchStrategy + "(0).probability","0.5");
xmlConfig.setProperty(searchStrategy + "(1).selector[@name]","selectBest");
xmlConfig.setProperty(searchStrategy + "(1).acceptor[@name]","acceptNewRemoveWorst");
xmlConfig.setProperty(searchStrategy + "(1).modules.module(0)[@name]","ruin_and_recreate");
xmlConfig.setProperty(searchStrategy + "(1).modules.module(0).ruin[@name]","radialRuin");
xmlConfig.setProperty(searchStrategy + "(1).modules.module(0).ruin.share","0.15");
xmlConfig.setProperty(searchStrategy + "(1).modules.module(0).insertion[@name]","bestInsertion");
xmlConfig.setProperty(searchStrategy + "(1).probability","0.5");
return config;
}
}

View file

@ -34,8 +34,8 @@
<licenses> <licenses>
<license> <license>
<name>GNU General Public License, version 2 (GPL-2.0)</name> <name>GNU Lesser General Public Licence, version 3.0</name>
<url>http://opensource.org/licenses/GPL-2.0</url> <url>http://opensource.org/licenses/LGPL-3.0</url>
</license> </license>
</licenses> </licenses>