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:
parent
e12136393a
commit
093baf1abe
3 changed files with 55 additions and 14 deletions
|
|
@ -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());
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue