mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
add bad job list
This commit is contained in:
parent
c3155a0938
commit
322d1d7d13
3 changed files with 32 additions and 67 deletions
|
|
@ -52,7 +52,7 @@ public class VariablePlusFixedSolutionCostCalculatorFactory {
|
||||||
c += stateManager.getRouteState(r, InternalStates.COSTS, Double.class);
|
c += stateManager.getRouteState(r, InternalStates.COSTS, Double.class);
|
||||||
c += getFixedCosts(r.getVehicle());
|
c += getFixedCosts(r.getVehicle());
|
||||||
}
|
}
|
||||||
c += solution.getBadJobs().size() * c * .05;
|
c += solution.getBadJobs().size() * c * .1;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,12 +85,8 @@ final class BestInsertionConcurrent implements InsertionStrategy{
|
||||||
|
|
||||||
private JobInsertionCostsCalculator bestInsertionCostCalculator;
|
private JobInsertionCostsCalculator bestInsertionCostCalculator;
|
||||||
|
|
||||||
private boolean minVehiclesFirst = false;
|
|
||||||
|
|
||||||
private int nuOfBatches;
|
private int nuOfBatches;
|
||||||
|
|
||||||
private ExecutorService executor;
|
|
||||||
|
|
||||||
private ExecutorCompletionService<Insertion> completionService;
|
private ExecutorCompletionService<Insertion> completionService;
|
||||||
|
|
||||||
public void setRandom(Random random) {
|
public void setRandom(Random random) {
|
||||||
|
|
@ -100,11 +96,10 @@ final class BestInsertionConcurrent implements InsertionStrategy{
|
||||||
public BestInsertionConcurrent(JobInsertionCostsCalculator jobInsertionCalculator, ExecutorService executorService, int nuOfBatches, VehicleRoutingProblem vehicleRoutingProblem) {
|
public BestInsertionConcurrent(JobInsertionCostsCalculator jobInsertionCalculator, ExecutorService executorService, int nuOfBatches, VehicleRoutingProblem vehicleRoutingProblem) {
|
||||||
super();
|
super();
|
||||||
this.insertionsListeners = new InsertionListeners();
|
this.insertionsListeners = new InsertionListeners();
|
||||||
this.executor = executorService;
|
|
||||||
this.nuOfBatches = nuOfBatches;
|
this.nuOfBatches = nuOfBatches;
|
||||||
inserter = new Inserter(insertionsListeners, vehicleRoutingProblem);
|
inserter = new Inserter(insertionsListeners, vehicleRoutingProblem);
|
||||||
bestInsertionCostCalculator = jobInsertionCalculator;
|
bestInsertionCostCalculator = jobInsertionCalculator;
|
||||||
completionService = new ExecutorCompletionService<Insertion>(executor);
|
completionService = new ExecutorCompletionService<Insertion>(executorService);
|
||||||
logger.info("initialise " + this);
|
logger.info("initialise " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,16 +111,13 @@ final class BestInsertionConcurrent implements InsertionStrategy{
|
||||||
@Override
|
@Override
|
||||||
public Collection<Job> insertJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
public Collection<Job> insertJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||||
insertionsListeners.informInsertionStarts(vehicleRoutes,unassignedJobs);
|
insertionsListeners.informInsertionStarts(vehicleRoutes,unassignedJobs);
|
||||||
|
List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size());
|
||||||
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
|
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
|
||||||
Collections.shuffle(unassignedJobList, random);
|
Collections.shuffle(unassignedJobList, random);
|
||||||
|
|
||||||
List<Batch> batches = distributeRoutes(vehicleRoutes,nuOfBatches);
|
List<Batch> batches = distributeRoutes(vehicleRoutes,nuOfBatches);
|
||||||
|
|
||||||
for(final Job unassignedJob : unassignedJobList){
|
for(final Job unassignedJob : unassignedJobList){
|
||||||
|
|
||||||
Insertion bestInsertion = null;
|
Insertion bestInsertion = null;
|
||||||
double bestInsertionCost = Double.MAX_VALUE;
|
double bestInsertionCost = Double.MAX_VALUE;
|
||||||
|
|
||||||
for(final Batch batch : batches){
|
for(final Batch batch : batches){
|
||||||
completionService.submit(new Callable<Insertion>() {
|
completionService.submit(new Callable<Insertion>() {
|
||||||
|
|
||||||
|
|
@ -135,9 +127,7 @@ final class BestInsertionConcurrent implements InsertionStrategy{
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < batches.size(); i++) {
|
for (int i = 0; i < batches.size(); i++) {
|
||||||
Future<Insertion> futureIData = completionService.take();
|
Future<Insertion> futureIData = completionService.take();
|
||||||
|
|
@ -148,8 +138,7 @@ final class BestInsertionConcurrent implements InsertionStrategy{
|
||||||
bestInsertionCost = insertion.getInsertionData().getInsertionCost();
|
bestInsertionCost = insertion.getInsertionData().getInsertionCost();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch(InterruptedException e){
|
||||||
catch(InterruptedException e){
|
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
catch (ExecutionException e) {
|
catch (ExecutionException e) {
|
||||||
|
|
@ -157,43 +146,18 @@ final class BestInsertionConcurrent implements InsertionStrategy{
|
||||||
logger.error(e.getCause().toString());
|
logger.error(e.getCause().toString());
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!minVehiclesFirst){
|
|
||||||
VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
||||||
InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
|
InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
|
||||||
if(newIData.getInsertionCost() < bestInsertionCost){
|
if(newIData.getInsertionCost() < bestInsertionCost){
|
||||||
bestInsertion = new Insertion(newRoute,newIData);
|
bestInsertion = new Insertion(newRoute,newIData);
|
||||||
bestInsertionCost = newIData.getInsertionCost();
|
|
||||||
vehicleRoutes.add(newRoute);
|
vehicleRoutes.add(newRoute);
|
||||||
batches.get(random.nextInt(batches.size())).routes.add(newRoute);
|
batches.get(random.nextInt(batches.size())).routes.add(newRoute);
|
||||||
}
|
}
|
||||||
}
|
if(bestInsertion == null) badJobs.add(unassignedJob);
|
||||||
|
else inserter.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
|
||||||
if(bestInsertion == null){
|
|
||||||
VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
|
||||||
InsertionData bestI = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, Double.MAX_VALUE);
|
|
||||||
if(bestI instanceof InsertionData.NoInsertionFound){
|
|
||||||
throw new IllegalStateException(getErrorMsg(unassignedJob));
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
bestInsertion = new Insertion(newRoute,bestI);
|
|
||||||
vehicleRoutes.add(newRoute);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// logger.info("insert " + unassignedJob + " pickup@" + bestInsertion.getInsertionData().getPickupInsertionIndex() + " delivery@" + bestInsertion.getInsertionData().getDeliveryInsertionIndex());
|
|
||||||
inserter.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
|
|
||||||
}
|
}
|
||||||
insertionsListeners.informInsertionEndsListeners(vehicleRoutes);
|
insertionsListeners.informInsertionEndsListeners(vehicleRoutes);
|
||||||
return null;
|
return badJobs;
|
||||||
}
|
|
||||||
|
|
||||||
private String getErrorMsg(Job unassignedJob) {
|
|
||||||
return "given the vehicles, could not insert job\n" +
|
|
||||||
"\t" + unassignedJob +
|
|
||||||
"\n\tthis might have the following reasons:\n" +
|
|
||||||
"\t- no vehicle has the capacity to transport the job [check whether there is at least one vehicle that is capable to transport the job]\n" +
|
|
||||||
"\t- the time-window cannot be met, even in a commuter tour the time-window is missed [check whether it is possible to reach the time-window on the shortest path or make hard time-windows soft]\n" +
|
|
||||||
"\t- if you deal with finite vehicles, and the available vehicles are already fully employed, no vehicle can be found anymore to transport the job [add penalty-vehicles]";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,7 @@ public class BicycleMessenger {
|
||||||
|
|
||||||
//create your algorithm
|
//create your algorithm
|
||||||
VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(bicycleMessengerProblem,"input/algorithmConfig_open.xml");
|
VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(bicycleMessengerProblem,"input/algorithmConfig_open.xml");
|
||||||
|
// vraBuilder.setNuOfThreads(2);
|
||||||
vraBuilder.addDefaultCostCalculators();
|
vraBuilder.addDefaultCostCalculators();
|
||||||
vraBuilder.setStateAndConstraintManager(stateManager, constraintManager);
|
vraBuilder.setStateAndConstraintManager(stateManager, constraintManager);
|
||||||
VehicleRoutingAlgorithm algorithm = vraBuilder.build();
|
VehicleRoutingAlgorithm algorithm = vraBuilder.build();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue