diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertion.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertion.java index c276c0e3..b0feb01d 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertion.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertion.java @@ -184,8 +184,7 @@ public class RegretInsertion extends AbstractInsertionStrategy { private JobInsertionCostsCalculator insertionCostsCalculator; - - /** + /** * Sets the scoring function. * *

By default, the this.TimeWindowScorer is used. @@ -242,73 +241,87 @@ public class RegretInsertion extends AbstractInsertionStrategy { private ScoredJob nextJob(Collection routes, List unassignedJobList, List badJobs) { ScoredJob bestScoredJob = null; - double bestScore = -1 * Double.MAX_VALUE; - for (Job unassignedJob : unassignedJobList) { - 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){ + ScoredJob scoredJob = getScoredJob(routes,unassignedJob,insertionCostsCalculator,scoringFunction); + if(scoredJob instanceof BadJob){ badJobs.add(unassignedJob); continue; } - double score = score(unassignedJob, best, secondBest); - if (score > bestScore) { - if(bestRoute == emptyRoute){ - bestScoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, true); + if(bestScoredJob == null) bestScoredJob = scoredJob; + else{ + if(scoredJob.getScore() > bestScoredJob.getScore()){ + bestScoredJob = scoredJob; } - else bestScoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, false); - bestScore = score; } } return bestScoredJob; } + static ScoredJob getScoredJob(Collection routes, Job unassignedJob, JobInsertionCostsCalculator insertionCostsCalculator, ScoringFunction scoringFunction) { + InsertionData best = null; + InsertionData secondBest = null; + VehicleRoute bestRoute = null; - private double score(Job unassignedJob, InsertionData best, InsertionData secondBest) { - double score; - if(secondBest == null){ - score = best.getInsertionCost() + scoringFunction.score(best,unassignedJob); - } - else{ - score = (secondBest.getInsertionCost()-best.getInsertionCost()) + scoringFunction.score(best,unassignedJob); + 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; + } } - return score; + + 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)) { + 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, scoringFunction); + ScoredJob scoredJob; + if(bestRoute == emptyRoute){ + scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, true); + } + else scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, false); + return scoredJob; + } + + + 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){ //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); + } + return score; } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertionConcurrent.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertionConcurrent.java index 8c8f31dc..528ed0ff 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertionConcurrent.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/RegretInsertionConcurrent.java @@ -53,8 +53,7 @@ public class RegretInsertionConcurrent extends AbstractInsertionStrategy { private final ExecutorCompletionService completionService; - - /** + /** * Sets the scoring function. * *

By default, the this.TimeWindowScorer is used. @@ -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 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; - } + + } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java index b595a994..e45393df 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/RegretInsertionTest.java @@ -80,7 +80,7 @@ public class RegretInsertionTest { RegretInsertion regretInsertion = new RegretInsertion(calculator,vrp); Collection routes = new ArrayList(); - 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 routes = new ArrayList(); - 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());