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

speed up regret insertion

This commit is contained in:
oblonski 2015-10-15 18:12:54 +02:00
parent e12136393a
commit 093baf1abe
3 changed files with 55 additions and 14 deletions

View file

@ -13,12 +13,12 @@ import java.util.*;
*/ */
class InsertionDataUpdater { class InsertionDataUpdater {
static boolean update(VehicleFleetManager fleetManager, JobInsertionCostsCalculator insertionCostsCalculator, TreeSet<VersionedInsertionData> insertionDataSet, int updateRound, Job unassignedJob, Collection<VehicleRoute> routes) { static boolean update(boolean addAllAvailable, Set<String> initialVehicleIds, VehicleFleetManager fleetManager, JobInsertionCostsCalculator insertionCostsCalculator, TreeSet<VersionedInsertionData> insertionDataSet, int updateRound, Job unassignedJob, Collection<VehicleRoute> routes) {
for(VehicleRoute route : routes) { for(VehicleRoute route : routes) {
Collection<Vehicle> relevantVehicles = new ArrayList<Vehicle>(); Collection<Vehicle> relevantVehicles = new ArrayList<Vehicle>();
if (!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) { if (!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) {
relevantVehicles.add(route.getVehicle()); relevantVehicles.add(route.getVehicle());
relevantVehicles.addAll(fleetManager.getAvailableVehicles(route.getVehicle())); if(addAllAvailable && initialVehicleIds.contains(route.getVehicle().getId())) relevantVehicles.addAll(fleetManager.getAvailableVehicles(route.getVehicle()));
} else relevantVehicles.addAll(fleetManager.getAvailableVehicles()); } else relevantVehicles.addAll(fleetManager.getAvailableVehicles());
for (Vehicle v : relevantVehicles) { for (Vehicle v : relevantVehicles) {
double depTime = v.getEarliestDeparture(); double depTime = v.getEarliestDeparture();
@ -32,6 +32,8 @@ class InsertionDataUpdater {
return true; return true;
} }
static VehicleRoute findRoute(Collection<VehicleRoute> routes, Job job) { static VehicleRoute findRoute(Collection<VehicleRoute> routes, Job job) {
for(VehicleRoute r : routes){ for(VehicleRoute r : routes){
if(r.getVehicle().getBreak() == job) return r; if(r.getVehicle().getBreak() == job) return r;
@ -49,7 +51,7 @@ class InsertionDataUpdater {
}; };
} }
static ScoredJob getBest(VehicleFleetManager fleetManager, JobInsertionCostsCalculator insertionCostsCalculator, ScoringFunction scoringFunction, TreeSet<VersionedInsertionData>[] priorityQueues, Map<VehicleRoute, Integer> updates, List<Job> unassignedJobList, List<Job> badJobs) { static ScoredJob getBest(boolean switchAllowed, Set<String> initialVehicleIds, VehicleFleetManager fleetManager, JobInsertionCostsCalculator insertionCostsCalculator, ScoringFunction scoringFunction, TreeSet<VersionedInsertionData>[] priorityQueues, Map<VehicleRoute, Integer> updates, List<Job> unassignedJobList, List<Job> badJobs) {
ScoredJob bestScoredJob = null; ScoredJob bestScoredJob = null;
for(Job j : unassignedJobList){ for(Job j : unassignedJobList){
VehicleRoute bestRoute = null; VehicleRoute bestRoute = null;
@ -65,6 +67,8 @@ class InsertionDataUpdater {
} }
} }
if(versionedIData.getiData() instanceof InsertionData.NoInsertionFound) continue; if(versionedIData.getiData() instanceof InsertionData.NoInsertionFound) continue;
if(versionedIData.getiData().getSelectedVehicle() != versionedIData.getRoute().getVehicle() && !switchAllowed) continue;
if(versionedIData.getiData().getSelectedVehicle() != versionedIData.getRoute().getVehicle() && initialVehicleIds.contains(versionedIData.getRoute().getVehicle().getId())) continue;
if(versionedIData.getiData().getSelectedVehicle() != versionedIData.getRoute().getVehicle()) { if(versionedIData.getiData().getSelectedVehicle() != versionedIData.getRoute().getVehicle()) {
if (fleetManager.isLocked(versionedIData.getiData().getSelectedVehicle())) { if (fleetManager.isLocked(versionedIData.getiData().getSelectedVehicle())) {
Vehicle available = fleetManager.getAvailableVehicle(versionedIData.getiData().getSelectedVehicle().getVehicleTypeIdentifier()); Vehicle available = fleetManager.getAvailableVehicle(versionedIData.getiData().getSelectedVehicle().getVehicleTypeIdentifier());

View file

@ -47,6 +47,22 @@ public class RegretInsertion extends AbstractInsertionStrategy {
private VehicleFleetManager fleetManager; private VehicleFleetManager fleetManager;
private Set<String> initialVehicleIds;
private boolean switchAllowed = true;
public RegretInsertion(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem, VehicleFleetManager fleetManager) {
super(vehicleRoutingProblem);
this.scoringFunction = new DefaultScorer(vehicleRoutingProblem);
this.insertionCostsCalculator = jobInsertionCalculator;
this.fleetManager = fleetManager;
this.vrp = vehicleRoutingProblem;
this.initialVehicleIds = getInitialVehicleIds(vehicleRoutingProblem);
logger.debug("initialise {}", this);
}
/** /**
* Sets the scoring function. * Sets the scoring function.
* <p/> * <p/>
@ -58,13 +74,16 @@ public class RegretInsertion extends AbstractInsertionStrategy {
this.scoringFunction = scoringFunction; this.scoringFunction = scoringFunction;
} }
public RegretInsertion(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem, VehicleFleetManager fleetManager) { public void setSwitchAllowed(boolean switchAllowed) {
super(vehicleRoutingProblem); this.switchAllowed = switchAllowed;
this.scoringFunction = new DefaultScorer(vehicleRoutingProblem); }
this.insertionCostsCalculator = jobInsertionCalculator;
this.fleetManager = fleetManager; private Set<String> getInitialVehicleIds(VehicleRoutingProblem vehicleRoutingProblem) {
this.vrp = vehicleRoutingProblem; Set<String> ids = new HashSet<String>();
logger.debug("initialise {}", this); for(VehicleRoute r : vehicleRoutingProblem.getInitialVehicleRoutes()){
ids.add(r.getVehicle().getId());
}
return ids;
} }
@Override @Override
@ -122,7 +141,7 @@ public class RegretInsertion extends AbstractInsertionStrategy {
updates.put(lastModified,updateRound); updates.put(lastModified,updateRound);
} }
updateRound++; updateRound++;
ScoredJob bestScoredJob = InsertionDataUpdater.getBest(fleetManager,insertionCostsCalculator,scoringFunction,priorityQueues,updates,unassignedJobList,badJobList); ScoredJob bestScoredJob = InsertionDataUpdater.getBest(switchAllowed,initialVehicleIds,fleetManager,insertionCostsCalculator,scoringFunction,priorityQueues,updates,unassignedJobList,badJobList);
if (bestScoredJob != null) { if (bestScoredJob != null) {
if (bestScoredJob.isNewRoute()) { if (bestScoredJob.isNewRoute()) {
routes.add(bestScoredJob.getRoute()); routes.add(bestScoredJob.getRoute());
@ -145,7 +164,7 @@ public class RegretInsertion extends AbstractInsertionStrategy {
if(priorityQueues[unassignedJob.getIndex()] == null){ if(priorityQueues[unassignedJob.getIndex()] == null){
priorityQueues[unassignedJob.getIndex()] = new TreeSet<VersionedInsertionData>(InsertionDataUpdater.getComparator()); priorityQueues[unassignedJob.getIndex()] = new TreeSet<VersionedInsertionData>(InsertionDataUpdater.getComparator());
} }
InsertionDataUpdater.update(fleetManager,insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, routes); InsertionDataUpdater.update(switchAllowed, initialVehicleIds,fleetManager,insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, routes);
} }
} }

View file

@ -53,6 +53,11 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
private VehicleFleetManager fleetManager; private VehicleFleetManager fleetManager;
private Set<String> initialVehicleIds;
private boolean switchAllowed = true;
/** /**
* Sets the scoring function. * Sets the scoring function.
* <p/> * <p/>
@ -71,6 +76,7 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
this.vrp = vehicleRoutingProblem; this.vrp = vehicleRoutingProblem;
this.executor = executorService; this.executor = executorService;
this.fleetManager = fleetManager; this.fleetManager = fleetManager;
this.initialVehicleIds = getInitialVehicleIds(vehicleRoutingProblem);
logger.debug("initialise " + this); logger.debug("initialise " + this);
} }
@ -79,6 +85,18 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
return "[name=regretInsertion][additionalScorer=" + scoringFunction + "]"; return "[name=regretInsertion][additionalScorer=" + scoringFunction + "]";
} }
public void setSwitchAllowed(boolean switchAllowed) {
this.switchAllowed = switchAllowed;
}
private Set<String> getInitialVehicleIds(VehicleRoutingProblem vehicleRoutingProblem) {
Set<String> ids = new HashSet<String>();
for(VehicleRoute r : vehicleRoutingProblem.getInitialVehicleRoutes()){
ids.add(r.getVehicle().getId());
}
return ids;
}
/** /**
* Runs insertion. * Runs insertion.
@ -131,7 +149,7 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
updates.put(lastModified,updateRound); updates.put(lastModified,updateRound);
} }
updateRound++; updateRound++;
ScoredJob bestScoredJob = InsertionDataUpdater.getBest(fleetManager, insertionCostsCalculator, scoringFunction, priorityQueues, updates, unassignedJobList, badJobList); ScoredJob bestScoredJob = InsertionDataUpdater.getBest(switchAllowed,initialVehicleIds,fleetManager, insertionCostsCalculator, scoringFunction, priorityQueues, updates, unassignedJobList, badJobList);
if (bestScoredJob != null) { if (bestScoredJob != null) {
if (bestScoredJob.isNewRoute()) { if (bestScoredJob.isNewRoute()) {
routes.add(bestScoredJob.getRoute()); routes.add(bestScoredJob.getRoute());
@ -159,7 +177,7 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
tasks.add(new Callable<Boolean>() { tasks.add(new Callable<Boolean>() {
@Override @Override
public Boolean call() throws Exception { public Boolean call() throws Exception {
return InsertionDataUpdater.update(fleetManager, insertionCostsCalculator, priorityQueue, updateRound, unassignedJob, routes); return InsertionDataUpdater.update(switchAllowed,initialVehicleIds,fleetManager, insertionCostsCalculator, priorityQueue, updateRound, unassignedJob, routes);
} }
}); });
} }