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 17:02:19 +02:00
parent c72c243bf0
commit e12136393a
8 changed files with 75 additions and 98 deletions

View file

@ -404,7 +404,7 @@ public class Jsprit {
);
AbstractInsertionStrategy regret;
final RegretInsertion.DefaultScorer scorer;
final DefaultScorer scorer;
if (es != null) {
RegretInsertionConcurrent regretInsertion = (RegretInsertionConcurrent) new InsertionBuilder(vrp, fm, stateManager, constraintManager)
@ -424,7 +424,6 @@ public class Jsprit {
.considerFixedCosts(toDouble(getProperty(Parameter.FIXED_COST_PARAM.toString())))
.setActivityInsertionCostCalculator(activityInsertion)
.build();
regretInsertion.setFleetManager(fm);
scorer = getRegretScorer(vrp);
regretInsertion.setScoringFunction(scorer);
regret = regretInsertion;
@ -522,9 +521,9 @@ public class Jsprit {
}
private RegretInsertion.DefaultScorer getRegretScorer(VehicleRoutingProblem vrp) {
RegretInsertion.DefaultScorer scorer;
scorer = new RegretInsertion.DefaultScorer(vrp);
private DefaultScorer getRegretScorer(VehicleRoutingProblem vrp) {
DefaultScorer scorer;
scorer = new DefaultScorer(vrp);
scorer.setTimeWindowParam(Double.valueOf(properties.getProperty(Parameter.REGRET_TIME_WINDOW_SCORER.toString())));
scorer.setDepotDistanceParam(Double.valueOf(properties.getProperty(Parameter.REGRET_DISTANCE_SCORER.toString())));
return scorer;

View file

@ -166,12 +166,11 @@ public class InsertionBuilder {
}
} else if (strategy.equals(Strategy.REGRET)) {
if (executor == null) {
RegretInsertion regret = new RegretInsertion(costCalculator, vrp);
regret.setFleetManager(fleetManager);
RegretInsertion regret = new RegretInsertion(costCalculator, vrp, fleetManager);
insertion = regret;
} else {
insertion = new RegretInsertionConcurrent(costCalculator, vrp, executor);
insertion = new RegretInsertionConcurrent(costCalculator, vrp, executor, fleetManager);
}
} else throw new IllegalStateException("you should never get here");
for (InsertionListener l : iListeners) insertion.addListener(l);

View file

@ -13,7 +13,7 @@ import java.util.*;
*/
class InsertionDataUpdater {
static void update(VehicleFleetManager fleetManager, JobInsertionCostsCalculator insertionCostsCalculator, TreeSet<VersionedInsertionData> insertionDataSet, int updateRound, Map<VehicleRoute, Integer> updates, Job unassignedJob, Collection<VehicleRoute> routes) {
static boolean update(VehicleFleetManager fleetManager, JobInsertionCostsCalculator insertionCostsCalculator, TreeSet<VersionedInsertionData> insertionDataSet, int updateRound, Job unassignedJob, Collection<VehicleRoute> routes) {
for(VehicleRoute route : routes) {
Collection<Vehicle> relevantVehicles = new ArrayList<Vehicle>();
if (!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) {
@ -28,8 +28,8 @@ class InsertionDataUpdater {
}
insertionDataSet.add(new VersionedInsertionData(iData, updateRound, route));
}
updates.put(route, updateRound);
}
return true;
}
static VehicleRoute findRoute(Collection<VehicleRoute> routes, Job job) {

View file

@ -47,10 +47,6 @@ public class RegretInsertion extends AbstractInsertionStrategy {
private VehicleFleetManager fleetManager;
public void setFleetManager(VehicleFleetManager fleetManager) {
this.fleetManager = fleetManager;
}
/**
* Sets the scoring function.
* <p/>
@ -62,10 +58,11 @@ public class RegretInsertion extends AbstractInsertionStrategy {
this.scoringFunction = scoringFunction;
}
public RegretInsertion(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem) {
public RegretInsertion(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem, VehicleFleetManager fleetManager) {
super(vehicleRoutingProblem);
this.scoringFunction = new DefaultScorer(vehicleRoutingProblem);
this.insertionCostsCalculator = jobInsertionCalculator;
this.fleetManager = fleetManager;
this.vrp = vehicleRoutingProblem;
logger.debug("initialise {}", this);
}
@ -117,10 +114,12 @@ public class RegretInsertion extends AbstractInsertionStrategy {
if(!firstRun && lastModified == null) throw new IllegalStateException("fooo");
if(firstRun){
firstRun = false;
updateInsertionData(priorityQueues, routes, unassignedJobList, badJobList, updateRound, updates);
updateInsertionData(priorityQueues, routes, unassignedJobList, updateRound);
for(VehicleRoute r : routes) updates.put(r,updateRound);
}
else{
updateInsertionData(priorityQueues, Arrays.asList(lastModified), unassignedJobList, badJobList, updateRound, updates);
updateInsertionData(priorityQueues, Arrays.asList(lastModified), unassignedJobList, updateRound);
updates.put(lastModified,updateRound);
}
updateRound++;
ScoredJob bestScoredJob = InsertionDataUpdater.getBest(fleetManager,insertionCostsCalculator,scoringFunction,priorityQueues,updates,unassignedJobList,badJobList);
@ -141,12 +140,12 @@ public class RegretInsertion extends AbstractInsertionStrategy {
return badJobs;
}
private void updateInsertionData(TreeSet<VersionedInsertionData>[] priorityQueues, Collection<VehicleRoute> routes, List<Job> unassignedJobList, List<Job> badJobList, int updateRound, Map<VehicleRoute, Integer> updates) {
private void updateInsertionData(TreeSet<VersionedInsertionData>[] priorityQueues, Collection<VehicleRoute> routes, List<Job> unassignedJobList, int updateRound) {
for (Job unassignedJob : unassignedJobList) {
if(priorityQueues[unassignedJob.getIndex()] == null){
priorityQueues[unassignedJob.getIndex()] = new TreeSet<VersionedInsertionData>(InsertionDataUpdater.getComparator());
}
InsertionDataUpdater.update(fleetManager,insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, updates, unassignedJob, routes);
InsertionDataUpdater.update(fleetManager,insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, routes);
}
}

View file

@ -26,8 +26,9 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.*;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
/**
* Insertion based on regret approach.
@ -48,15 +49,10 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
private final JobInsertionCostsCalculator insertionCostsCalculator;
private final ExecutorCompletionService<ScoredJob> completionService;
private final ExecutorService executor;
private VehicleFleetManager fleetManager;
public void setFleetManager(VehicleFleetManager fleetManager) {
this.fleetManager = fleetManager;
}
/**
* Sets the scoring function.
* <p/>
@ -68,12 +64,13 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
this.scoringFunction = scoringFunction;
}
public RegretInsertionConcurrent(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem, ExecutorService executorService) {
public RegretInsertionConcurrent(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem, ExecutorService executorService, VehicleFleetManager fleetManager) {
super(vehicleRoutingProblem);
this.scoringFunction = new DefaultScorer(vehicleRoutingProblem);
this.insertionCostsCalculator = jobInsertionCalculator;
this.vrp = vehicleRoutingProblem;
completionService = new ExecutorCompletionService<ScoredJob>(executorService);
this.executor = executorService;
this.fleetManager = fleetManager;
logger.debug("initialise " + this);
}
@ -123,13 +120,15 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
while (!jobs.isEmpty()) {
List<Job> unassignedJobList = new ArrayList<Job>(jobs);
List<Job> badJobList = new ArrayList<Job>();
if(!firstRun && lastModified == null) throw new IllegalStateException("fooo");
if(!firstRun && lastModified == null) throw new IllegalStateException("ho. this must not be.");
if(firstRun){
firstRun = false;
updateInsertionData(priorityQueues, routes, unassignedJobList, badJobList, updateRound, updates);
updateInsertionData(priorityQueues, routes, unassignedJobList, updateRound);
for(VehicleRoute r : routes) updates.put(r,updateRound);
}
else{
updateInsertionData(priorityQueues, Arrays.asList(lastModified), unassignedJobList, badJobList, updateRound, updates);
updateInsertionData(priorityQueues, Arrays.asList(lastModified), unassignedJobList, updateRound);
updates.put(lastModified,updateRound);
}
updateRound++;
ScoredJob bestScoredJob = InsertionDataUpdater.getBest(fleetManager, insertionCostsCalculator, scoringFunction, priorityQueues, updates, unassignedJobList, badJobList);
@ -150,13 +149,25 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
return badJobs;
}
private void updateInsertionData(TreeSet<VersionedInsertionData>[] priorityQueues, Collection<VehicleRoute> routes, List<Job> unassignedJobList, List<Job> badJobList, int updateRound, Map<VehicleRoute, Integer> updates) {
for (Job unassignedJob : unassignedJobList) {
private void updateInsertionData(final TreeSet<VersionedInsertionData>[] priorityQueues, final Collection<VehicleRoute> routes, List<Job> unassignedJobList, final int updateRound) {
List<Callable<Boolean>> tasks = new ArrayList<Callable<Boolean>>();
for (final Job unassignedJob : unassignedJobList) {
if(priorityQueues[unassignedJob.getIndex()] == null){
priorityQueues[unassignedJob.getIndex()] = new TreeSet<VersionedInsertionData>(InsertionDataUpdater.getComparator());
}
// completionService.submit(ne)
InsertionDataUpdater.update(fleetManager,insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, updates, unassignedJob, routes);
final TreeSet<VersionedInsertionData> priorityQueue = priorityQueues[unassignedJob.getIndex()];
tasks.add(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return InsertionDataUpdater.update(fleetManager, insertionCostsCalculator, priorityQueue, updateRound, unassignedJob, routes);
}
});
}
try {
List<Future<Boolean>> futures = executor.invokeAll(tasks);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}