mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
make RuinRadial more memory efficient and make NeighborhoodCreation
independent from RuinRadial
This commit is contained in:
parent
db888e5c1e
commit
8f4f4b6c48
3 changed files with 435 additions and 53 deletions
|
|
@ -47,6 +47,194 @@ import basics.route.VehicleRoute;
|
|||
*/
|
||||
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.calculateDistance(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.calculateDistance(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 {
|
||||
private Job job;
|
||||
private double distance;
|
||||
|
|
@ -72,14 +260,12 @@ final class RuinRadial implements RuinStrategy {
|
|||
|
||||
private double fractionOfAllNodes2beRuined;
|
||||
|
||||
private Map<String, TreeSet<ReferencedJob>> distanceNodeTree = new HashMap<String, TreeSet<ReferencedJob>>();
|
||||
|
||||
private Random random = RandomNumberGeneration.getRandom();
|
||||
|
||||
private JobDistance jobDistance;
|
||||
|
||||
private RuinListeners ruinListeners;
|
||||
|
||||
private JobNeighborhoods jobNeighborhoods;
|
||||
|
||||
public void setRandom(Random random) {
|
||||
this.random = random;
|
||||
}
|
||||
|
|
@ -94,42 +280,14 @@ final class RuinRadial implements RuinStrategy {
|
|||
public RuinRadial(VehicleRoutingProblem vrp, double fraction2beRemoved, JobDistance jobDistance) {
|
||||
super();
|
||||
this.vrp = vrp;
|
||||
this.jobDistance = jobDistance;
|
||||
this.fractionOfAllNodes2beRuined = fraction2beRemoved;
|
||||
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);
|
||||
}
|
||||
|
||||
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()) {
|
||||
double distance = jobDistance.calculateDistance(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");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
|
@ -143,11 +301,11 @@ final class RuinRadial implements RuinStrategy {
|
|||
@Override
|
||||
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes) {
|
||||
if(vehicleRoutes.isEmpty()){
|
||||
return Collections.EMPTY_LIST;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
int nOfJobs2BeRemoved = getNuOfJobs2BeRemoved();
|
||||
if (nOfJobs2BeRemoved == 0) {
|
||||
return Collections.EMPTY_LIST;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Job randomJob = pickRandomJob();
|
||||
Collection<Job> unassignedJobs = ruin(vehicleRoutes,randomJob,nOfJobs2BeRemoved);
|
||||
|
|
@ -160,27 +318,30 @@ final class RuinRadial implements RuinStrategy {
|
|||
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved){
|
||||
ruinListeners.ruinStarts(vehicleRoutes);
|
||||
List<Job> unassignedJobs = new ArrayList<Job>();
|
||||
TreeSet<ReferencedJob> tree = distanceNodeTree.get(targetJob.getId());
|
||||
Iterator<ReferencedJob> descendingIterator = tree.descendingIterator();
|
||||
int counter = 0;
|
||||
while (descendingIterator.hasNext() && counter < nOfJobs2BeRemoved) {
|
||||
ReferencedJob refJob = descendingIterator.next();
|
||||
Job job = refJob.getJob();
|
||||
int nNeighbors = nOfJobs2BeRemoved - 1;
|
||||
removeJob(targetJob,vehicleRoutes);
|
||||
unassignedJobs.add(targetJob);
|
||||
Iterator<Job> neighborhoodIterator = jobNeighborhoods.getNearestNeighborsIterator(nNeighbors, targetJob);
|
||||
while(neighborhoodIterator.hasNext()){
|
||||
Job job = neighborhoodIterator.next();
|
||||
removeJob(job,vehicleRoutes);
|
||||
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);
|
||||
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() {
|
||||
int totNuOfJobs = vrp.getJobs().values().size();
|
||||
int randomIndex = random.nextInt(totNuOfJobs);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue