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()); } final TreeSet<VersionedInsertionData> priorityQueue = priorityQueues[unassignedJob.getIndex()]; tasks.add( new Callable<Boolean>() { @Override public Boolean call() throws Exception { return InsertionDataUpdater.update( switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, priorityQueue, updateRound, unassignedJob, routes); } }); } try { List<Future<Boolean>> futures = executor.invokeAll(tasks); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e); } }
/** * Runs insertion. * * <p> * * <p>Before inserting a job, all unassigned jobs are scored according to its best- and * secondBest-insertion plus additional scoring variables. * * @throws java.lang.RuntimeException if smth went wrong with thread execution */ @Override public Collection<Job> insertUnassignedJobs( Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) { List<Job> badJobs = new ArrayList<Job>(unassignedJobs.size()); Iterator<Job> jobIterator = unassignedJobs.iterator(); while (jobIterator.hasNext()) { Job job = jobIterator.next(); if (job instanceof Break) { VehicleRoute route = InsertionDataUpdater.findRoute(routes, job); if (route == null) { badJobs.add(job); } else { InsertionData iData = insertionCostsCalculator.getInsertionData( route, job, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, Double.MAX_VALUE); if (iData instanceof InsertionData.NoInsertionFound) { badJobs.add(job); } else { insertJob(job, iData, route); } } jobIterator.remove(); } } List<Job> jobs = new ArrayList<Job>(unassignedJobs); TreeSet<VersionedInsertionData>[] priorityQueues = new TreeSet[vrp.getJobs().values().size() + 2]; VehicleRoute lastModified = null; boolean firstRun = true; int updateRound = 0; Map<VehicleRoute, Integer> updates = new HashMap<VehicleRoute, Integer>(); while (!jobs.isEmpty()) { List<Job> unassignedJobList = new ArrayList<Job>(jobs); List<Job> badJobList = new ArrayList<Job>(); if (!firstRun && lastModified == null) throw new IllegalStateException("ho. this must not be."); if (firstRun) { firstRun = false; updateInsertionData(priorityQueues, routes, unassignedJobList, updateRound); for (VehicleRoute r : routes) updates.put(r, updateRound); } else { updateInsertionData( priorityQueues, Arrays.asList(lastModified), unassignedJobList, updateRound); updates.put(lastModified, updateRound); } updateRound++; ScoredJob bestScoredJob = InsertionDataUpdater.getBest( switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, scoringFunction, priorityQueues, updates, unassignedJobList, badJobList); if (bestScoredJob != null) { if (bestScoredJob.isNewRoute()) { routes.add(bestScoredJob.getRoute()); } insertJob( bestScoredJob.getJob(), bestScoredJob.getInsertionData(), bestScoredJob.getRoute()); jobs.remove(bestScoredJob.getJob()); lastModified = bestScoredJob.getRoute(); } else lastModified = null; for (Job bad : badJobList) { jobs.remove(bad); badJobs.add(bad); } } return badJobs; }