1
0
Fork 0
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:
oblonski 2014-11-22 12:36:09 +01:00
parent 369877e9fc
commit a32a750bed
2 changed files with 33 additions and 108 deletions

View file

@ -1,28 +1,25 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* Copyright (C) 2014 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
* 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 jsprit.core.algorithm.ruin;
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.job.Job;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.util.RandomNumberGeneration;
import jsprit.core.util.StopWatch;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -39,7 +36,7 @@ import java.util.*;
* @author stefan
*
*/
final class RuinRadial implements RuinStrategy {
final class RuinRadial extends AbstractRuinStrategy {
static interface JobNeighborhoods {
@ -255,15 +252,8 @@ final class RuinRadial implements RuinStrategy {
private double fractionOfAllNodes2beRuined;
private Random random = RandomNumberGeneration.getRandom();
private RuinListeners ruinListeners;
private JobNeighborhoods jobNeighborhoods;
public void setRandom(Random random) {
this.random = random;
}
/**
* Constructs RuinRadial.
@ -276,7 +266,6 @@ final class RuinRadial implements RuinStrategy {
super();
this.vrp = vrp;
this.fractionOfAllNodes2beRuined = fraction2beRemoved;
ruinListeners = new RuinListeners();
int nJobsToMemorize = (int) Math.ceil(vrp.getJobs().values().size()*fraction2beRemoved);
JobNeighborhoodsImplWithCapRestriction jobNeighborhoodsImpl = new JobNeighborhoodsImplWithCapRestriction(vrp, jobDistance, nJobsToMemorize);
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.
*/
@Override
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes) {
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes) {
if(vehicleRoutes.isEmpty()){
return Collections.emptyList();
}
@ -303,16 +292,14 @@ final class RuinRadial implements RuinStrategy {
return Collections.emptyList();
}
Job randomJob = pickRandomJob();
Collection<Job> unassignedJobs = ruin(vehicleRoutes,randomJob,nOfJobs2BeRemoved);
return unassignedJobs;
return ruin(vehicleRoutes,randomJob,nOfJobs2BeRemoved);
}
/**
* Removes targetJob and its neighborhood and returns the removed jobs.
*/
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved){
ruinListeners.ruinStarts(vehicleRoutes);
List<Job> unassignedJobs = new ArrayList<Job>();
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved){
List<Job> unassignedJobs = new ArrayList<Job>();
int nNeighbors = nOfJobs2BeRemoved - 1;
removeJob(targetJob,vehicleRoutes);
unassignedJobs.add(targetJob);
@ -322,47 +309,19 @@ final class RuinRadial implements RuinStrategy {
removeJob(job,vehicleRoutes);
unassignedJobs.add(job);
}
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;
}
}
return unassignedJobs;
}
private Job pickRandomJob() {
int totNuOfJobs = vrp.getJobs().values().size();
int randomIndex = random.nextInt(totNuOfJobs);
Job job = new ArrayList<Job>(vrp.getJobs().values()).get(randomIndex);
return job;
}
return new ArrayList<Job>(vrp.getJobs().values()).get(randomIndex);
}
private int getNuOfJobs2BeRemoved() {
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();
}
}

View file

@ -1,31 +1,31 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* Copyright (C) 2014 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
* 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 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.job.Job;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.util.RandomNumberGeneration;
import org.apache.logging.log4j.LogManager;
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);
@ -44,14 +44,6 @@ final class RuinRandom implements RuinStrategy {
private double fractionOfAllNodes2beRuined;
private Random random = RandomNumberGeneration.getRandom();
private RuinListeners ruinListeners;
public void setRandom(Random random) {
this.random = random;
}
/**
* Constructs ruinRandom.
*
@ -62,8 +54,7 @@ final class RuinRandom implements RuinStrategy {
super();
this.vrp = vrp;
this.fractionOfAllNodes2beRuined = fraction;
ruinListeners = new RuinListeners();
logger.info("initialise " + this);
logger.info("initialise " + this);
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).
*/
@Override
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes) {
ruinListeners.ruinStarts(vehicleRoutes);
List<Job> unassignedJobs = new ArrayList<Job>();
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes) {
List<Job> unassignedJobs = new ArrayList<Job>();
int nOfJobs2BeRemoved = selectNuOfJobs2BeRemoved();
ruin(vehicleRoutes, nOfJobs2BeRemoved, unassignedJobs);
ruinListeners.ruinEnds(vehicleRoutes, unassignedJobs);
return unassignedJobs;
return unassignedJobs;
}
/**
* Removes nOfJobs2BeRemoved from vehicleRoutes, including targetJob.
*/
@Override
public Collection<Job> ruin(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved) {
ruinListeners.ruinStarts(vehicleRoutes);
List<Job> unassignedJobs = new ArrayList<Job>();
public Collection<Job> ruinRoutes(Collection<VehicleRoute> vehicleRoutes, Job targetJob, int nOfJobs2BeRemoved) {
List<Job> unassignedJobs = new ArrayList<Job>();
if(targetJob != null){
boolean removed = false;
for (VehicleRoute route : vehicleRoutes) {
removed = route.getTourActivities().removeJob(targetJob);
removed = removeJob(targetJob,route);
if (removed) {
nOfJobs2BeRemoved--;
unassignedJobs.add(targetJob);
ruinListeners.removed(targetJob,route);
break;
}
}
}
ruin(vehicleRoutes, nOfJobs2BeRemoved, unassignedJobs);
ruinListeners.ruinEnds(vehicleRoutes, unassignedJobs);
return unassignedJobs;
return unassignedJobs;
}
public void setRuinFraction(double fractionOfAllNodes2beRuined) {
@ -117,13 +103,7 @@ final class RuinRandom implements RuinStrategy {
Job job = pickRandomJob(availableJobs);
unassignedJobs.add(job);
availableJobs.remove(job);
for (VehicleRoute route : vehicleRoutes) {
boolean removed = route.getTourActivities().removeJob(job);
if (removed) {
ruinListeners.removed(job,route);
break;
}
}
removeJob(job,vehicleRoutes);
}
}
@ -142,19 +122,5 @@ final class RuinRandom implements RuinStrategy {
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();
}
}