mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
add infrastructure to simplify the creation of new ruin strategies
This commit is contained in:
parent
369877e9fc
commit
a32a750bed
2 changed files with 33 additions and 108 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2013 Stefan Schroeder
|
* Copyright (C) 2014 Stefan Schroeder
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
@ -17,12 +17,9 @@
|
||||||
package jsprit.core.algorithm.ruin;
|
package jsprit.core.algorithm.ruin;
|
||||||
|
|
||||||
import jsprit.core.algorithm.ruin.distance.JobDistance;
|
import jsprit.core.algorithm.ruin.distance.JobDistance;
|
||||||
import jsprit.core.algorithm.ruin.listener.RuinListener;
|
|
||||||
import jsprit.core.algorithm.ruin.listener.RuinListeners;
|
|
||||||
import jsprit.core.problem.VehicleRoutingProblem;
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import jsprit.core.problem.job.Job;
|
import jsprit.core.problem.job.Job;
|
||||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
import jsprit.core.util.RandomNumberGeneration;
|
|
||||||
import jsprit.core.util.StopWatch;
|
import jsprit.core.util.StopWatch;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
@ -39,7 +36,7 @@ import java.util.*;
|
||||||
* @author stefan
|
* @author stefan
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
final class RuinRadial implements RuinStrategy {
|
final class RuinRadial extends AbstractRuinStrategy {
|
||||||
|
|
||||||
static interface JobNeighborhoods {
|
static interface JobNeighborhoods {
|
||||||
|
|
||||||
|
|
@ -255,15 +252,8 @@ final class RuinRadial implements RuinStrategy {
|
||||||
|
|
||||||
private double fractionOfAllNodes2beRuined;
|
private double fractionOfAllNodes2beRuined;
|
||||||
|
|
||||||
private Random random = RandomNumberGeneration.getRandom();
|
|
||||||
|
|
||||||
private RuinListeners ruinListeners;
|
|
||||||
|
|
||||||
private JobNeighborhoods jobNeighborhoods;
|
private JobNeighborhoods jobNeighborhoods;
|
||||||
|
|
||||||
public void setRandom(Random random) {
|
|
||||||
this.random = random;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs RuinRadial.
|
* Constructs RuinRadial.
|
||||||
|
|
@ -276,7 +266,6 @@ final class RuinRadial implements RuinStrategy {
|
||||||
super();
|
super();
|
||||||
this.vrp = vrp;
|
this.vrp = vrp;
|
||||||
this.fractionOfAllNodes2beRuined = fraction2beRemoved;
|
this.fractionOfAllNodes2beRuined = fraction2beRemoved;
|
||||||
ruinListeners = new RuinListeners();
|
|
||||||
int nJobsToMemorize = (int) Math.ceil(vrp.getJobs().values().size()*fraction2beRemoved);
|
int nJobsToMemorize = (int) Math.ceil(vrp.getJobs().values().size()*fraction2beRemoved);
|
||||||
JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, nJobsToMemorize);
|
JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, nJobsToMemorize);
|
||||||
jobNeighborhoodsImpl.initialise();
|
jobNeighborhoodsImpl.initialise();
|
||||||
|
|
@ -294,7 +283,7 @@ final class RuinRadial implements RuinStrategy {
|
||||||
* the neighborhood plus the randomly selected job from the number of vehicleRoutes. All removed jobs are then returned as a collection.
|
* the neighborhood plus the randomly selected job from the number of vehicleRoutes. All removed jobs are then returned as a collection.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes) {
|
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes) {
|
||||||
if(vehicleRoutes.isEmpty()){
|
if(vehicleRoutes.isEmpty()){
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
@ -303,16 +292,14 @@ final class RuinRadial implements RuinStrategy {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
Job randomJob = pickRandomJob();
|
Job randomJob = pickRandomJob();
|
||||||
Collection<Job> unassignedJobs = ruin(vehicleRoutes,randomJob,nOfJobs2BeRemoved);
|
return ruin(vehicleRoutes,randomJob,nOfJobs2BeRemoved);
|
||||||
return unassignedJobs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes targetJob and its neighborhood and returns the removed jobs.
|
* Removes targetJob and its neighborhood and returns the removed jobs.
|
||||||
*/
|
*/
|
||||||
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved){
|
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved){
|
||||||
ruinListeners.ruinStarts(vehicleRoutes);
|
List<Job> unassignedJobs = new ArrayList<Job>();
|
||||||
List<Job> unassignedJobs = new ArrayList<Job>();
|
|
||||||
int nNeighbors = nOfJobs2BeRemoved - 1;
|
int nNeighbors = nOfJobs2BeRemoved - 1;
|
||||||
removeJob(targetJob,vehicleRoutes);
|
removeJob(targetJob,vehicleRoutes);
|
||||||
unassignedJobs.add(targetJob);
|
unassignedJobs.add(targetJob);
|
||||||
|
|
@ -322,47 +309,19 @@ final class RuinRadial implements RuinStrategy {
|
||||||
removeJob(job,vehicleRoutes);
|
removeJob(job,vehicleRoutes);
|
||||||
unassignedJobs.add(job);
|
unassignedJobs.add(job);
|
||||||
}
|
}
|
||||||
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);
|
||||||
Job job = new ArrayList<Job>(vrp.getJobs().values()).get(randomIndex);
|
return new ArrayList<Job>(vrp.getJobs().values()).get(randomIndex);
|
||||||
return job;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private int getNuOfJobs2BeRemoved() {
|
private int getNuOfJobs2BeRemoved() {
|
||||||
return (int) Math.ceil(vrp.getJobs().values().size()
|
return (int) Math.ceil(vrp.getJobs().values().size()
|
||||||
* fractionOfAllNodes2beRuined);
|
* fractionOfAllNodes2beRuined);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addListener(RuinListener ruinListener) {
|
|
||||||
ruinListeners.addListener(ruinListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeListener(RuinListener ruinListener) {
|
|
||||||
ruinListeners.removeListener(ruinListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<RuinListener> getListeners() {
|
|
||||||
return ruinListeners.getListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2013 Stefan Schroeder
|
* Copyright (C) 2014 Stefan Schroeder
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
@ -16,16 +16,16 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package jsprit.core.algorithm.ruin;
|
package jsprit.core.algorithm.ruin;
|
||||||
|
|
||||||
import jsprit.core.algorithm.ruin.listener.RuinListener;
|
|
||||||
import jsprit.core.algorithm.ruin.listener.RuinListeners;
|
|
||||||
import jsprit.core.problem.VehicleRoutingProblem;
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import jsprit.core.problem.job.Job;
|
import jsprit.core.problem.job.Job;
|
||||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
import jsprit.core.util.RandomNumberGeneration;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -36,7 +36,7 @@ import java.util.*;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
final class RuinRandom implements RuinStrategy {
|
final class RuinRandom extends AbstractRuinStrategy {
|
||||||
|
|
||||||
private Logger logger = LogManager.getLogger(RuinRandom.class);
|
private Logger logger = LogManager.getLogger(RuinRandom.class);
|
||||||
|
|
||||||
|
|
@ -44,14 +44,6 @@ final class RuinRandom implements RuinStrategy {
|
||||||
|
|
||||||
private double fractionOfAllNodes2beRuined;
|
private double fractionOfAllNodes2beRuined;
|
||||||
|
|
||||||
private Random random = RandomNumberGeneration.getRandom();
|
|
||||||
|
|
||||||
private RuinListeners ruinListeners;
|
|
||||||
|
|
||||||
public void setRandom(Random random) {
|
|
||||||
this.random = random;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs ruinRandom.
|
* Constructs ruinRandom.
|
||||||
*
|
*
|
||||||
|
|
@ -62,8 +54,7 @@ final class RuinRandom implements RuinStrategy {
|
||||||
super();
|
super();
|
||||||
this.vrp = vrp;
|
this.vrp = vrp;
|
||||||
this.fractionOfAllNodes2beRuined = fraction;
|
this.fractionOfAllNodes2beRuined = fraction;
|
||||||
ruinListeners = new RuinListeners();
|
logger.info("initialise " + this);
|
||||||
logger.info("initialise " + this);
|
|
||||||
logger.info("done");
|
logger.info("done");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,37 +64,32 @@ final class RuinRandom implements RuinStrategy {
|
||||||
* <p>The number of jobs is calculated as follows: Math.ceil(vrp.getJobs().values().size() * fractionOfAllNodes2beRuined).
|
* <p>The number of jobs is calculated as follows: Math.ceil(vrp.getJobs().values().size() * fractionOfAllNodes2beRuined).
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes) {
|
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes) {
|
||||||
ruinListeners.ruinStarts(vehicleRoutes);
|
List<Job> unassignedJobs = new ArrayList<Job>();
|
||||||
List<Job> unassignedJobs = new ArrayList<Job>();
|
|
||||||
int nOfJobs2BeRemoved = selectNuOfJobs2BeRemoved();
|
int nOfJobs2BeRemoved = selectNuOfJobs2BeRemoved();
|
||||||
ruin(vehicleRoutes, nOfJobs2BeRemoved, unassignedJobs);
|
ruin(vehicleRoutes, nOfJobs2BeRemoved, unassignedJobs);
|
||||||
ruinListeners.ruinEnds(vehicleRoutes, unassignedJobs);
|
return unassignedJobs;
|
||||||
return unassignedJobs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes nOfJobs2BeRemoved from vehicleRoutes, including targetJob.
|
* Removes nOfJobs2BeRemoved from vehicleRoutes, including targetJob.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved) {
|
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved) {
|
||||||
ruinListeners.ruinStarts(vehicleRoutes);
|
List<Job> unassignedJobs = new ArrayList<Job>();
|
||||||
List<Job> unassignedJobs = new ArrayList<Job>();
|
|
||||||
if(targetJob != null){
|
if(targetJob != null){
|
||||||
boolean removed = false;
|
boolean removed = false;
|
||||||
for (VehicleRoute route : vehicleRoutes) {
|
for (VehicleRoute route : vehicleRoutes) {
|
||||||
removed = route.getTourActivities().removeJob(targetJob);
|
removed = removeJob(targetJob,route);
|
||||||
if (removed) {
|
if (removed) {
|
||||||
nOfJobs2BeRemoved--;
|
nOfJobs2BeRemoved--;
|
||||||
unassignedJobs.add(targetJob);
|
unassignedJobs.add(targetJob);
|
||||||
ruinListeners.removed(targetJob,route);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ruin(vehicleRoutes, nOfJobs2BeRemoved, unassignedJobs);
|
ruin(vehicleRoutes, nOfJobs2BeRemoved, unassignedJobs);
|
||||||
ruinListeners.ruinEnds(vehicleRoutes, unassignedJobs);
|
return unassignedJobs;
|
||||||
return unassignedJobs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRuinFraction(double fractionOfAllNodes2beRuined) {
|
public void setRuinFraction(double fractionOfAllNodes2beRuined) {
|
||||||
|
|
@ -117,13 +103,7 @@ final class RuinRandom implements RuinStrategy {
|
||||||
Job job = pickRandomJob(availableJobs);
|
Job job = pickRandomJob(availableJobs);
|
||||||
unassignedJobs.add(job);
|
unassignedJobs.add(job);
|
||||||
availableJobs.remove(job);
|
availableJobs.remove(job);
|
||||||
for (VehicleRoute route : vehicleRoutes) {
|
removeJob(job,vehicleRoutes);
|
||||||
boolean removed = route.getTourActivities().removeJob(job);
|
|
||||||
if (removed) {
|
|
||||||
ruinListeners.removed(job,route);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,19 +122,5 @@ final class RuinRandom implements RuinStrategy {
|
||||||
return (int) Math.ceil(vrp.getJobs().values().size() * fractionOfAllNodes2beRuined);
|
return (int) Math.ceil(vrp.getJobs().values().size() * fractionOfAllNodes2beRuined);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addListener(RuinListener ruinListener) {
|
|
||||||
ruinListeners.addListener(ruinListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeListener(RuinListener ruinListener) {
|
|
||||||
ruinListeners.removeListener(ruinListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<RuinListener> getListeners() {
|
|
||||||
return ruinListeners.getListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue