mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
mod regret insertion
This commit is contained in:
parent
cebbe3a60d
commit
600e29f353
3 changed files with 76 additions and 125 deletions
|
|
@ -184,7 +184,6 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
|||
|
||||
private JobInsertionCostsCalculator insertionCostsCalculator;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the scoring function.
|
||||
*
|
||||
|
|
@ -242,9 +241,23 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
|||
|
||||
private ScoredJob nextJob(Collection<VehicleRoute> routes, List<Job> unassignedJobList, List<Job> badJobs) {
|
||||
ScoredJob bestScoredJob = null;
|
||||
double bestScore = -1 * Double.MAX_VALUE;
|
||||
|
||||
for (Job unassignedJob : unassignedJobList) {
|
||||
ScoredJob scoredJob = getScoredJob(routes,unassignedJob,insertionCostsCalculator,scoringFunction);
|
||||
if(scoredJob instanceof BadJob){
|
||||
badJobs.add(unassignedJob);
|
||||
continue;
|
||||
}
|
||||
if(bestScoredJob == null) bestScoredJob = scoredJob;
|
||||
else{
|
||||
if(scoredJob.getScore() > bestScoredJob.getScore()){
|
||||
bestScoredJob = scoredJob;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestScoredJob;
|
||||
}
|
||||
|
||||
static ScoredJob getScoredJob(Collection<VehicleRoute> routes, Job unassignedJob, JobInsertionCostsCalculator insertionCostsCalculator, ScoringFunction scoringFunction) {
|
||||
InsertionData best = null;
|
||||
InsertionData secondBest = null;
|
||||
VehicleRoute bestRoute = null;
|
||||
|
|
@ -271,7 +284,6 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
|||
VehicleRoute emptyRoute = VehicleRoute.emptyRoute();
|
||||
InsertionData iData = insertionCostsCalculator.getInsertionData(emptyRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, benchmark);
|
||||
if (!(iData instanceof InsertionData.NoInsertionFound)) {
|
||||
// iData = new InsertionData(iData.getInsertionCost()*1000.,iData.getPickupInsertionIndex(),iData.getDeliveryInsertionIndex(),iData.getSelectedVehicle(),iData.getSelectedDriver());
|
||||
if (best == null) {
|
||||
best = iData;
|
||||
bestRoute = emptyRoute;
|
||||
|
|
@ -284,29 +296,30 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
|||
}
|
||||
}
|
||||
if(best == null){
|
||||
badJobs.add(unassignedJob);
|
||||
continue;
|
||||
return new RegretInsertion.BadJob(unassignedJob);
|
||||
}
|
||||
double score = score(unassignedJob, best, secondBest);
|
||||
if (score > bestScore) {
|
||||
double score = score(unassignedJob, best, secondBest, scoringFunction);
|
||||
ScoredJob scoredJob;
|
||||
if(bestRoute == emptyRoute){
|
||||
bestScoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, true);
|
||||
scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, true);
|
||||
}
|
||||
else bestScoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, false);
|
||||
bestScore = score;
|
||||
}
|
||||
}
|
||||
return bestScoredJob;
|
||||
else scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, false);
|
||||
return scoredJob;
|
||||
}
|
||||
|
||||
|
||||
private double score(Job unassignedJob, InsertionData best, InsertionData secondBest) {
|
||||
static double score(Job unassignedJob, InsertionData best, InsertionData secondBest, ScoringFunction scoringFunction) {
|
||||
if(best == null){
|
||||
throw new IllegalStateException("cannot insert job " + unassignedJob.getId());
|
||||
}
|
||||
double score;
|
||||
if(secondBest == null){
|
||||
score = best.getInsertionCost() + scoringFunction.score(best,unassignedJob);
|
||||
if(secondBest == null){ //either there is only one vehicle or there are more vehicles, but they cannot load unassignedJob
|
||||
//if only one vehicle, I want the job to be inserted with min iCosts
|
||||
//if there are more vehicles, I want this job to be prioritized since there are no alternatives
|
||||
score = Integer.MAX_VALUE - best.getInsertionCost() + scoringFunction.score(best, unassignedJob);
|
||||
}
|
||||
else{
|
||||
score = (secondBest.getInsertionCost()-best.getInsertionCost()) + scoringFunction.score(best,unassignedJob);
|
||||
score = (secondBest.getInsertionCost()-best.getInsertionCost()) + scoringFunction.score(best, unassignedJob);
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
|
|||
|
||||
private final ExecutorCompletionService<ScoredJob> completionService;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the scoring function.
|
||||
*
|
||||
|
|
@ -118,7 +117,7 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
|
|||
|
||||
@Override
|
||||
public ScoredJob call() throws Exception {
|
||||
return getScoredJob(routes, unassignedJob);
|
||||
return RegretInsertion.getScoredJob(routes, unassignedJob, insertionCostsCalculator, scoringFunction);
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -152,71 +151,10 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy {
|
|||
return bestScoredJob;
|
||||
}
|
||||
|
||||
private ScoredJob getScoredJob(Collection<VehicleRoute> routes, Job unassignedJob) {
|
||||
InsertionData best = null;
|
||||
InsertionData secondBest = null;
|
||||
VehicleRoute bestRoute = null;
|
||||
|
||||
double benchmark = Double.MAX_VALUE;
|
||||
for (VehicleRoute route : routes) {
|
||||
if (secondBest != null) {
|
||||
benchmark = secondBest.getInsertionCost();
|
||||
}
|
||||
InsertionData iData = insertionCostsCalculator.getInsertionData(route, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, benchmark);
|
||||
if (iData instanceof InsertionData.NoInsertionFound) continue;
|
||||
if (best == null) {
|
||||
best = iData;
|
||||
bestRoute = route;
|
||||
} else if (iData.getInsertionCost() < best.getInsertionCost()) {
|
||||
secondBest = best;
|
||||
best = iData;
|
||||
bestRoute = route;
|
||||
} else if (secondBest == null || (iData.getInsertionCost() < secondBest.getInsertionCost())) {
|
||||
secondBest = iData;
|
||||
}
|
||||
}
|
||||
|
||||
VehicleRoute emptyRoute = VehicleRoute.emptyRoute();
|
||||
InsertionData iData = insertionCostsCalculator.getInsertionData(emptyRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, benchmark);
|
||||
if (!(iData instanceof InsertionData.NoInsertionFound)) {
|
||||
// iData = new InsertionData(iData.getInsertionCost()*1000.,iData.getPickupInsertionIndex(),iData.getDeliveryInsertionIndex(),iData.getSelectedVehicle(),iData.getSelectedDriver());
|
||||
if (best == null) {
|
||||
best = iData;
|
||||
bestRoute = emptyRoute;
|
||||
} else if (iData.getInsertionCost() < best.getInsertionCost()) {
|
||||
secondBest = best;
|
||||
best = iData;
|
||||
bestRoute = emptyRoute;
|
||||
} else if (secondBest == null || (iData.getInsertionCost() < secondBest.getInsertionCost())) {
|
||||
secondBest = iData;
|
||||
}
|
||||
}
|
||||
if(best == null){
|
||||
return new RegretInsertion.BadJob(unassignedJob);
|
||||
}
|
||||
double score = score(unassignedJob, best, secondBest);
|
||||
ScoredJob scoredJob;
|
||||
if(bestRoute == emptyRoute){
|
||||
scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, true);
|
||||
}
|
||||
else scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, false);
|
||||
return scoredJob;
|
||||
}
|
||||
|
||||
|
||||
private double score(Job unassignedJob, InsertionData best, InsertionData secondBest) {
|
||||
if(best == null){
|
||||
throw new IllegalStateException("cannot insert job " + unassignedJob.getId());
|
||||
}
|
||||
double score;
|
||||
if(secondBest == null){
|
||||
score = best.getInsertionCost() + scoringFunction.score(best,unassignedJob);
|
||||
}
|
||||
else{
|
||||
score = (secondBest.getInsertionCost()-best.getInsertionCost()) + scoringFunction.score(best,unassignedJob);
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ public class RegretInsertionTest {
|
|||
RegretInsertion regretInsertion = new RegretInsertion(calculator,vrp);
|
||||
Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>();
|
||||
|
||||
CkeckJobSequence position = new CkeckJobSequence(1, s1);
|
||||
CkeckJobSequence position = new CkeckJobSequence(2, s1);
|
||||
regretInsertion.addListener(position);
|
||||
regretInsertion.insertJobs(routes,vrp.getJobs().values());
|
||||
Assert.assertTrue(position.isCorrect());
|
||||
|
|
@ -109,7 +109,7 @@ public class RegretInsertionTest {
|
|||
RegretInsertion regretInsertion = new RegretInsertion(calculator,vrp);
|
||||
Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>();
|
||||
|
||||
CkeckJobSequence position = new CkeckJobSequence(1, s2);
|
||||
CkeckJobSequence position = new CkeckJobSequence(2, s2);
|
||||
regretInsertion.addListener(position);
|
||||
regretInsertion.insertJobs(routes,vrp.getJobs().values());
|
||||
Assert.assertTrue(position.isCorrect());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue