mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
improve regret insertion
This commit is contained in:
parent
db7bd290dc
commit
fc3121c905
5 changed files with 50 additions and 34 deletions
|
|
@ -124,10 +124,17 @@ public class AlgorithmEventsRecorder implements RuinListener, IterationStartsLis
|
||||||
public void ruinStarts(Collection<VehicleRoute> routes) {
|
public void ruinStarts(Collection<VehicleRoute> routes) {
|
||||||
if(!record()) return;
|
if(!record()) return;
|
||||||
fileSink.stepBegins(graph.getId(),0,BEFORE_RUIN_RENDER_SOLUTION);
|
fileSink.stepBegins(graph.getId(),0,BEFORE_RUIN_RENDER_SOLUTION);
|
||||||
|
markAllNodesAsInserted();
|
||||||
addRoutes(routes);
|
addRoutes(routes);
|
||||||
fileSink.stepBegins(graph.getId(),0,RUIN);
|
fileSink.stepBegins(graph.getId(),0,RUIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void markAllNodesAsInserted() {
|
||||||
|
for(Job j : vrp.getJobs().values()){
|
||||||
|
markInserted(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addRoutes(Collection<VehicleRoute> routes) {
|
private void addRoutes(Collection<VehicleRoute> routes) {
|
||||||
for(VehicleRoute route : routes){
|
for(VehicleRoute route : routes){
|
||||||
String prevNode = makeStartId(route.getVehicle());
|
String prevNode = makeStartId(route.getVehicle());
|
||||||
|
|
|
||||||
|
|
@ -473,8 +473,8 @@ public class VehicleRoutingAlgorithms {
|
||||||
stateManager.updateSkillStates();
|
stateManager.updateSkillStates();
|
||||||
stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen());
|
stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen());
|
||||||
stateManager.addStateUpdater(new OpenRouteStateVerifier());
|
stateManager.addStateUpdater(new OpenRouteStateVerifier());
|
||||||
stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts()));
|
// stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts()));
|
||||||
stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
// stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* define constraints
|
* define constraints
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,13 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class BadJob extends ScoredJob {
|
||||||
|
|
||||||
|
BadJob(Job job) {
|
||||||
|
super(job, 0., null, null, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scorer to include other impacts on score such as time-window length or distance to depot.
|
* Scorer to include other impacts on score such as time-window length or distance to depot.
|
||||||
*
|
*
|
||||||
|
|
@ -216,25 +223,24 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
|
|
||||||
while (!jobs.isEmpty()) {
|
while (!jobs.isEmpty()) {
|
||||||
List<Job> unassignedJobList = new ArrayList<Job>(jobs);
|
List<Job> unassignedJobList = new ArrayList<Job>(jobs);
|
||||||
ScoredJob bestScoredJob = nextJob(routes, unassignedJobList);
|
List<Job> badJobList = new ArrayList<Job>();
|
||||||
Job handledJob;
|
ScoredJob bestScoredJob = nextJob(routes, unassignedJobList, badJobList);
|
||||||
if(bestScoredJob == null){
|
if(bestScoredJob != null){
|
||||||
handledJob = unassignedJobList.get(0);
|
|
||||||
badJobs.add(handledJob);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(bestScoredJob.isNewRoute()){
|
if(bestScoredJob.isNewRoute()){
|
||||||
routes.add(bestScoredJob.getRoute());
|
routes.add(bestScoredJob.getRoute());
|
||||||
}
|
}
|
||||||
insertJob(bestScoredJob.getJob(),bestScoredJob.getInsertionData(),bestScoredJob.getRoute());
|
insertJob(bestScoredJob.getJob(),bestScoredJob.getInsertionData(),bestScoredJob.getRoute());
|
||||||
handledJob = bestScoredJob.getJob();
|
jobs.remove(bestScoredJob.getJob());
|
||||||
|
}
|
||||||
|
for(Job bad : badJobList) {
|
||||||
|
jobs.remove(bad);
|
||||||
|
badJobs.add(bad);
|
||||||
}
|
}
|
||||||
jobs.remove(handledJob);
|
|
||||||
}
|
}
|
||||||
return badJobs;
|
return badJobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScoredJob nextJob(Collection<VehicleRoute> routes, List<Job> unassignedJobList) {
|
private ScoredJob nextJob(Collection<VehicleRoute> routes, List<Job> unassignedJobList, List<Job> badJobs) {
|
||||||
ScoredJob bestScoredJob = null;
|
ScoredJob bestScoredJob = null;
|
||||||
double bestScore = -1 * Double.MAX_VALUE;
|
double bestScore = -1 * Double.MAX_VALUE;
|
||||||
|
|
||||||
|
|
@ -277,7 +283,10 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
secondBest = iData;
|
secondBest = iData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(best == null){
|
||||||
|
badJobs.add(unassignedJob);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
double score = score(unassignedJob, best, secondBest);
|
double score = score(unassignedJob, best, secondBest);
|
||||||
if (score > bestScore) {
|
if (score > bestScore) {
|
||||||
if(bestRoute == emptyRoute){
|
if(bestRoute == emptyRoute){
|
||||||
|
|
@ -292,9 +301,6 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
||||||
|
|
||||||
|
|
||||||
private double score(Job unassignedJob, InsertionData best, InsertionData secondBest) {
|
private double score(Job unassignedJob, InsertionData best, InsertionData secondBest) {
|
||||||
if(best == null){
|
|
||||||
throw new IllegalStateException("cannot insert job " + unassignedJob.getId());
|
|
||||||
}
|
|
||||||
double score;
|
double score;
|
||||||
if(secondBest == null){
|
if(secondBest == null){
|
||||||
score = best.getInsertionCost() + scoringFunction.score(best,unassignedJob);
|
score = best.getInsertionCost() + scoringFunction.score(best,unassignedJob);
|
||||||
|
|
|
||||||
|
|
@ -93,25 +93,24 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
|
||||||
|
|
||||||
while (!jobs.isEmpty()) {
|
while (!jobs.isEmpty()) {
|
||||||
List<Job> unassignedJobList = new ArrayList<Job>(jobs);
|
List<Job> unassignedJobList = new ArrayList<Job>(jobs);
|
||||||
ScoredJob bestScoredJob = nextJob(routes, unassignedJobList);
|
List<Job> badJobList = new ArrayList<Job>();
|
||||||
Job handledJob;
|
ScoredJob bestScoredJob = nextJob(routes, unassignedJobList, badJobList);
|
||||||
if(bestScoredJob == null){
|
if(bestScoredJob != null){
|
||||||
handledJob = unassignedJobList.get(0);
|
|
||||||
badJobs.add(handledJob);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(bestScoredJob.isNewRoute()){
|
if(bestScoredJob.isNewRoute()){
|
||||||
routes.add(bestScoredJob.getRoute());
|
routes.add(bestScoredJob.getRoute());
|
||||||
}
|
}
|
||||||
insertJob(bestScoredJob.getJob(),bestScoredJob.getInsertionData(),bestScoredJob.getRoute());
|
insertJob(bestScoredJob.getJob(),bestScoredJob.getInsertionData(),bestScoredJob.getRoute());
|
||||||
handledJob = bestScoredJob.getJob();
|
jobs.remove(bestScoredJob.getJob());
|
||||||
|
}
|
||||||
|
for(Job j : badJobList) {
|
||||||
|
jobs.remove(j);
|
||||||
|
badJobs.add(j);
|
||||||
}
|
}
|
||||||
jobs.remove(handledJob);
|
|
||||||
}
|
}
|
||||||
return badJobs;
|
return badJobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScoredJob nextJob(final Collection<VehicleRoute> routes, List<Job> unassignedJobList) {
|
private ScoredJob nextJob(final Collection<VehicleRoute> routes, List<Job> unassignedJobList, List<Job> badJobList) {
|
||||||
ScoredJob bestScoredJob = null;
|
ScoredJob bestScoredJob = null;
|
||||||
|
|
||||||
for (final Job unassignedJob : unassignedJobList) {
|
for (final Job unassignedJob : unassignedJobList) {
|
||||||
|
|
@ -129,7 +128,8 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
|
||||||
for(int i=0; i < unassignedJobList.size(); i++){
|
for(int i=0; i < unassignedJobList.size(); i++){
|
||||||
Future<ScoredJob> fsj = completionService.take();
|
Future<ScoredJob> fsj = completionService.take();
|
||||||
ScoredJob sJob = fsj.get();
|
ScoredJob sJob = fsj.get();
|
||||||
if(sJob == null){
|
if(sJob instanceof RegretInsertion.BadJob){
|
||||||
|
badJobList.add(sJob.getJob());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(bestScoredJob == null){
|
if(bestScoredJob == null){
|
||||||
|
|
@ -191,7 +191,9 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
|
||||||
secondBest = iData;
|
secondBest = iData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(best == null){
|
||||||
|
return new RegretInsertion.BadJob(unassignedJob);
|
||||||
|
}
|
||||||
double score = score(unassignedJob, best, secondBest);
|
double score = score(unassignedJob, best, secondBest);
|
||||||
ScoredJob scoredJob;
|
ScoredJob scoredJob;
|
||||||
if(bestRoute == emptyRoute){
|
if(bestRoute == emptyRoute){
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ import java.util.*;
|
||||||
*/
|
*/
|
||||||
public class StateManager implements RouteAndActivityStateGetter, IterationStartsListener, RuinListener, InsertionStartsListener, JobInsertedListener, InsertionEndsListener {
|
public class StateManager implements RouteAndActivityStateGetter, IterationStartsListener, RuinListener, InsertionStartsListener, JobInsertedListener, InsertionEndsListener {
|
||||||
|
|
||||||
|
|
||||||
static class States_ {
|
static class States_ {
|
||||||
|
|
||||||
private Map<StateId,Object> states = new HashMap<StateId,Object>();
|
private Map<StateId,Object> states = new HashMap<StateId,Object>();
|
||||||
|
|
@ -104,10 +103,6 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
|
||||||
|
|
||||||
private Object[][][] vehicle_dependent_activity_states;
|
private Object[][][] vehicle_dependent_activity_states;
|
||||||
|
|
||||||
// private Object[][] route_states;
|
|
||||||
//
|
|
||||||
// private Object[][][] vehicle_dependent_route_states;
|
|
||||||
|
|
||||||
private Map<VehicleRoute,Object[]> route_state_map;
|
private Map<VehicleRoute,Object[]> route_state_map;
|
||||||
|
|
||||||
private Map<VehicleRoute,Object[][]> vehicle_dependent_route_state_map;
|
private Map<VehicleRoute,Object[][]> vehicle_dependent_route_state_map;
|
||||||
|
|
@ -496,6 +491,10 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
|
||||||
updaters.add(updater);
|
updaters.add(updater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addAllStateUpdater(Collection<StateUpdater> updaters){
|
||||||
|
for(StateUpdater u : updaters) addStateUpdater(u);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an unmodifiable collections of stateUpdaters that have been added to this stateManager.
|
* Returns an unmodifiable collections of stateUpdaters that have been added to this stateManager.
|
||||||
*
|
*
|
||||||
|
|
@ -618,5 +617,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
|
||||||
addActivityVisitor(new UpdateSkills(this));
|
addActivityVisitor(new UpdateSkills(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addCoreUpdater(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue