diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/objectivefunction/MissedBreak.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/objectivefunction/MissedBreak.java index ff9147ef8..fb62e36fd 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/objectivefunction/MissedBreak.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/objectivefunction/MissedBreak.java @@ -29,17 +29,13 @@ public MissedBreak() { @Override protected double calculateRouteLevelCost(VehicleRoutingProblem problem, VehicleRoute route) { for (TourActivity act : route.getActivities()) { - if (act instanceof BreakActivity) { + if (act instanceof BreakActivity) return 0d; - } } if (route.getVehicle().getBreak() != null) { - if (route.getEnd().getArrTime() > route.getVehicle().getBreak().getActivity().getSingleTimeWindow() - .getEnd()) { + if (route.getEnd().getArrTime() > route.getVehicle().getBreak().getActivity().getBreakTimeWindow().getEnd()) return 4 * (getMaxCosts() * 2 + route.getVehicle().getBreak().getActivity().getOperationTime() - * route.getVehicle().getType().getVehicleCostParams().perServiceTimeUnit); - - } + * route.getVehicle().getType().getVehicleCostParams().perServiceTimeUnit); } return 0d; } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/BreakInsertionCalculator.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/BreakInsertionCalculator.java index 313eac36c..b982d608c 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/BreakInsertionCalculator.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/BreakInsertionCalculator.java @@ -102,12 +102,10 @@ public String toString() { @Override public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job jobToInsert, final Vehicle newVehicle, double newVehicleDepartureTime, final Driver newDriver, final double bestKnownCosts) { Break breakToInsert = (Break) jobToInsert; - if (newVehicle.getBreak() == null || newVehicle.getBreak() != breakToInsert) { + if (newVehicle.getBreak() == null || newVehicle.getBreak() != breakToInsert) return InsertionData.createEmptyInsertionData(); - } - if (currentRoute.isEmpty()) { + if (currentRoute.isEmpty()) return InsertionData.createEmptyInsertionData(); - } JobInsertionContext insertionContext = new JobInsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime); int insertionIndex = InsertionData.NO_INDEX; @@ -118,9 +116,8 @@ public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job /* check hard constraints at route level */ - if (!hardRouteLevelConstraint.fulfilled(insertionContext)) { + if (!hardRouteLevelConstraint.fulfilled(insertionContext)) return InsertionData.createEmptyInsertionData(); - } /* check soft constraints at route level @@ -156,7 +153,7 @@ public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job List locations = Arrays.asList(prevAct.getLocation(), nextAct.getLocation()); for (Location location : locations) { breakAct2Insert.setLocation(location); - TimeWindow timeWindow = breakToInsert.getActivity().getTimeWindow(); + TimeWindow timeWindow = breakToInsert.getActivity().getBreakTimeWindow(); breakAct2Insert.setTheoreticalEarliestOperationStartTime(timeWindow.getStart()); breakAct2Insert.setTheoreticalLatestOperationStartTime(timeWindow.getEnd()); ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, breakAct2Insert, nextAct, prevActStartTime); @@ -182,9 +179,8 @@ public InsertionData getInsertionData(final VehicleRoute currentRoute, final Job break; } } - if (insertionIndex == InsertionData.NO_INDEX) { + if (insertionIndex == InsertionData.NO_INDEX) return InsertionData.createEmptyInsertionData(); - } InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver); breakAct2Insert.setLocation(bestLocation); insertionData.getEvents().add(new InsertBreak(currentRoute, newVehicle, breakAct2Insert, insertionIndex)); diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/BreakScheduling.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/BreakScheduling.java index 311f496ff..adcbe78ee 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/BreakScheduling.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/BreakScheduling.java @@ -50,7 +50,7 @@ public class BreakScheduling implements InsertionStartsListener, JobInsertedList private final EventListeners eventListeners; - private Set modifiedRoutes = new HashSet(); + private Set modifiedRoutes = new HashSet<>(); public BreakScheduling(VehicleRoutingProblem vrp, StateManager stateManager, ConstraintManager constraintManager) { this.stateManager = stateManager; @@ -69,7 +69,7 @@ public void informJobInserted(Job job2insert, VehicleRoute inRoute, double addit stateManager.removed(aBreak, inRoute); stateManager.reCalculateStates(inRoute); } - if (inRoute.getEnd().getArrTime() > aBreak.getActivity().getTimeWindow().getEnd()) { + if (inRoute.getEnd().getArrTime() > aBreak.getActivity().getBreakTimeWindow().getEnd()) { InsertionData iData = breakInsertionCalculator.getInsertionData(inRoute, aBreak, inRoute.getVehicle(), inRoute.getDepartureTime(), inRoute.getDriver(), Double.MAX_VALUE); if (!(iData instanceof InsertionData.NoInsertionFound)) { logger.trace("insert: [jobId={}]{}", aBreak.getId(), iData); @@ -96,7 +96,7 @@ public void ruinEnds(Collection routes, Collection unassigned logger.trace("ruin: {}", aBreak.getId()); } } - List breaks = new ArrayList(); + List breaks = new ArrayList<>(); for (Job j : unassignedJobs) { if (j instanceof Break) { breaks.add((Break) j); @@ -119,7 +119,7 @@ public void informInsertionStarts(Collection vehicleRoutes, Collec for (VehicleRoute route : vehicleRoutes) { Break aBreak = route.getVehicle().getBreak(); if (aBreak != null && !route.getTourActivities().servesJob(aBreak)) { - if (route.getEnd().getArrTime() > aBreak.getActivity().getTimeWindow().getEnd()) { + if (route.getEnd().getArrTime() > aBreak.getActivity().getBreakTimeWindow().getEnd()) { InsertionData iData = breakInsertionCalculator.getInsertionData(route, aBreak, route.getVehicle(), route.getDepartureTime(), route.getDriver(), Double.MAX_VALUE); if (!(iData instanceof InsertionData.NoInsertionFound)) { logger.trace("insert: [jobId={}]{}", aBreak.getId(), iData); diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/InsertionDataUpdater.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/InsertionDataUpdater.java index df0fc6747..456658045 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/InsertionDataUpdater.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/InsertionDataUpdater.java @@ -18,14 +18,21 @@ package com.graphhopper.jsprit.core.algorithm.recreate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + import com.graphhopper.jsprit.core.problem.job.Job; import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; import com.graphhopper.jsprit.core.problem.vehicle.Vehicle; import com.graphhopper.jsprit.core.problem.vehicle.VehicleFleetManager; import com.graphhopper.jsprit.core.problem.vehicle.VehicleImpl; -import java.util.*; - /** * Created by schroeder on 15/10/15. */ @@ -33,13 +40,15 @@ class InsertionDataUpdater { static boolean update(boolean addAllAvailable, Set initialVehicleIds, VehicleFleetManager fleetManager, JobInsertionCostsCalculator insertionCostsCalculator, TreeSet insertionDataSet, int updateRound, Job unassignedJob, Collection routes) { for (VehicleRoute route : routes) { - Collection relevantVehicles = new ArrayList(); + Collection relevantVehicles = new ArrayList<>(); if (!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) { relevantVehicles.add(route.getVehicle()); if (addAllAvailable && !initialVehicleIds.contains(route.getVehicle().getId())) { relevantVehicles.addAll(fleetManager.getAvailableVehicles(route.getVehicle())); } - } else relevantVehicles.addAll(fleetManager.getAvailableVehicles()); + } else { + relevantVehicles.addAll(fleetManager.getAvailableVehicles()); + } for (Vehicle v : relevantVehicles) { double depTime = v.getEarliestDeparture(); InsertionData iData = insertionCostsCalculator.getInsertionData(route, unassignedJob, v, depTime, route.getDriver(), Double.MAX_VALUE); @@ -67,13 +76,16 @@ static Comparator getComparator() { }; } - static ScoredJob getBest(boolean switchAllowed, Set initialVehicleIds, VehicleFleetManager fleetManager, JobInsertionCostsCalculator insertionCostsCalculator, ScoringFunction scoringFunction, TreeSet[] priorityQueues, Map updates, List unassignedJobList, List badJobs) { + static ScoredJob getBest(boolean switchAllowed, Set initialVehicleIds, VehicleFleetManager fleetManager, + JobInsertionCostsCalculator insertionCostsCalculator, ScoringFunction scoringFunction, + Map> priorityQueues, Map updates, + List unassignedJobList, List badJobs) { ScoredJob bestScoredJob = null; for (Job j : unassignedJobList) { VehicleRoute bestRoute = null; InsertionData best = null; InsertionData secondBest = null; - TreeSet priorityQueue = priorityQueues[j.getIndex()]; + TreeSet priorityQueue = priorityQueues.get(j.getId()); Iterator iterator = priorityQueue.iterator(); while (iterator.hasNext()) { VersionedInsertionData versionedIData = iterator.next(); @@ -82,11 +94,17 @@ static ScoredJob getBest(boolean switchAllowed, Set initialVehicleIds, V continue; } } - if (versionedIData.getiData() instanceof InsertionData.NoInsertionFound) continue; + if (versionedIData.getiData() instanceof InsertionData.NoInsertionFound) { + continue; + } if (!(versionedIData.getRoute().getVehicle() instanceof VehicleImpl.NoVehicle)) { if (versionedIData.getiData().getSelectedVehicle() != versionedIData.getRoute().getVehicle()) { - if (!switchAllowed) continue; - if (initialVehicleIds.contains(versionedIData.getRoute().getVehicle().getId())) continue; + if (!switchAllowed) { + continue; + } + if (initialVehicleIds.contains(versionedIData.getRoute().getVehicle().getId())) { + continue; + } } } if (versionedIData.getiData().getSelectedVehicle() != versionedIData.getRoute().getVehicle()) { @@ -98,10 +116,14 @@ static ScoredJob getBest(boolean switchAllowed, Set initialVehicleIds, V for (Event e : oldData.getEvents()) { if (e instanceof SwitchVehicle) { newData.getEvents().add(new SwitchVehicle(versionedIData.getRoute(), available, oldData.getVehicleDepartureTime())); - } else newData.getEvents().add(e); + } else { + newData.getEvents().add(e); + } } versionedIData = new VersionedInsertionData(newData, versionedIData.getVersion(), versionedIData.getRoute()); - } else continue; + } else { + continue; + } } } int currentDataVersion = updates.get(versionedIData.getRoute()); @@ -137,7 +159,9 @@ static ScoredJob getBest(boolean switchAllowed, Set initialVehicleIds, V ScoredJob scoredJob; if (bestRoute == emptyRoute) { scoredJob = new ScoredJob(j, score, best, bestRoute, true); - } else scoredJob = new ScoredJob(j, score, best, bestRoute, false); + } else { + scoredJob = new ScoredJob(j, score, best, bestRoute, false); + } if (bestScoredJob == null) { bestScoredJob = scoredJob; diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/RegretInsertionConcurrentFast.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/RegretInsertionConcurrentFast.java index 9f166871e..c253553f0 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/RegretInsertionConcurrentFast.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/RegretInsertionConcurrentFast.java @@ -18,18 +18,28 @@ package com.graphhopper.jsprit.core.algorithm.recreate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; import com.graphhopper.jsprit.core.problem.constraint.DependencyType; import com.graphhopper.jsprit.core.problem.job.Break; import com.graphhopper.jsprit.core.problem.job.Job; import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; import com.graphhopper.jsprit.core.problem.vehicle.VehicleFleetManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; /** * Insertion based on regret approach. @@ -58,7 +68,7 @@ public class RegretInsertionConcurrentFast extends AbstractInsertionStrategy { private boolean switchAllowed = true; - private DependencyType[] dependencyTypes = null; + private HashMap dependencyTypes = null; /** @@ -93,15 +103,15 @@ public void setSwitchAllowed(boolean switchAllowed) { } private Set getInitialVehicleIds(VehicleRoutingProblem vehicleRoutingProblem) { - Set ids = new HashSet(); + Set ids = new HashSet<>(); for (VehicleRoute r : vehicleRoutingProblem.getInitialVehicleRoutes()) { ids.add(r.getVehicle().getId()); } return ids; } - public void setDependencyTypes(DependencyType[] dependencyTypes) { - this.dependencyTypes = dependencyTypes; + public void setDependencyTypes(HashMap hashMap) { + this.dependencyTypes = hashMap; } @@ -114,7 +124,7 @@ public void setDependencyTypes(DependencyType[] dependencyTypes) { */ @Override public Collection insertUnassignedJobs(Collection routes, Collection unassignedJobs) { - List badJobs = new ArrayList(unassignedJobs.size()); + List badJobs = new ArrayList<>(unassignedJobs.size()); Iterator jobIterator = unassignedJobs.iterator(); while (jobIterator.hasNext()) { @@ -135,18 +145,20 @@ public Collection insertUnassignedJobs(Collection routes, Col } } - List jobs = new ArrayList(unassignedJobs); - TreeSet[] priorityQueues = new TreeSet[vrp.getJobs().values().size() + 2]; + List jobs = new ArrayList<>(unassignedJobs); + Map> priorityQueues = new HashMap<>(vrp.getJobs().values().size() + 2); VehicleRoute lastModified = null; boolean firstRun = true; int updateRound = 0; - Map updates = new HashMap(); + Map updates = new HashMap<>(); while (!jobs.isEmpty()) { - List unassignedJobList = new ArrayList(jobs); - List badJobList = new ArrayList(); + List unassignedJobList = new ArrayList<>(jobs); + List badJobList = new ArrayList<>(); if (!firstRun && lastModified == null) throw new IllegalStateException("ho. this must not be."); updateInsertionData(priorityQueues, routes, unassignedJobList, updateRound, firstRun, lastModified, updates); - if (firstRun) firstRun = false; + if (firstRun) { + firstRun = false; + } updateRound++; ScoredJob bestScoredJob = InsertionDataUpdater.getBest(switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, scoringFunction, priorityQueues, updates, unassignedJobList, badJobList); if (bestScoredJob != null) { @@ -156,7 +168,9 @@ public Collection insertUnassignedJobs(Collection routes, Col insertJob(bestScoredJob.getJob(), bestScoredJob.getInsertionData(), bestScoredJob.getRoute()); jobs.remove(bestScoredJob.getJob()); lastModified = bestScoredJob.getRoute(); - } else lastModified = null; + } else { + lastModified = null; + } for (Job bad : badJobList) { jobs.remove(bad); badJobs.add(bad); @@ -165,32 +179,41 @@ public Collection insertUnassignedJobs(Collection routes, Col return badJobs; } - private void updateInsertionData(final TreeSet[] priorityQueues, final Collection routes, List unassignedJobList, final int updateRound, final boolean firstRun, final VehicleRoute lastModified, Map updates) { - List> tasks = new ArrayList>(); + private void updateInsertionData(final Map> priorityQueues, + final Collection routes, List unassignedJobList, final int updateRound, + final boolean firstRun, final VehicleRoute lastModified, Map updates) { + List> tasks = new ArrayList<>(); boolean updatedAllRoutes = false; for (final Job unassignedJob : unassignedJobList) { - if (priorityQueues[unassignedJob.getIndex()] == null) { - priorityQueues[unassignedJob.getIndex()] = new TreeSet(InsertionDataUpdater.getComparator()); + String unassignedJobId = unassignedJob.getId(); + if (priorityQueues.get(unassignedJobId) == null) { + priorityQueues.put(unassignedJobId, new TreeSet<>(InsertionDataUpdater.getComparator())); } if (firstRun) { updatedAllRoutes = true; - makeCallables(tasks, updatedAllRoutes, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, routes, lastModified); + makeCallables(tasks, updatedAllRoutes, priorityQueues.get(unassignedJobId), updateRound, unassignedJob, + routes, lastModified); } else { - if (dependencyTypes == null || dependencyTypes[unassignedJob.getIndex()] == null) { - makeCallables(tasks, updatedAllRoutes, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, routes, lastModified); + if (dependencyTypes == null || dependencyTypes.get(unassignedJobId) == null) { + makeCallables(tasks, updatedAllRoutes, priorityQueues.get(unassignedJobId), updateRound, + unassignedJob, routes, lastModified); } else { - DependencyType dependencyType = dependencyTypes[unassignedJob.getIndex()]; + DependencyType dependencyType = dependencyTypes.get(unassignedJobId); if (dependencyType.equals(DependencyType.INTER_ROUTE) || dependencyType.equals(DependencyType.INTRA_ROUTE)) { updatedAllRoutes = true; - makeCallables(tasks, updatedAllRoutes, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, routes, lastModified); + makeCallables(tasks, updatedAllRoutes, priorityQueues.get(unassignedJobId), updateRound, + unassignedJob, routes, lastModified); } else { - makeCallables(tasks, updatedAllRoutes, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, routes, lastModified); + makeCallables(tasks, updatedAllRoutes, priorityQueues.get(unassignedJobId), updateRound, + unassignedJob, routes, lastModified); } } } } if (updatedAllRoutes) { - for (VehicleRoute r : routes) updates.put(r, updateRound); + for (VehicleRoute r : routes) { + updates.put(r, updateRound); + } } else { updates.put(lastModified, updateRound); } @@ -204,19 +227,9 @@ private void updateInsertionData(final TreeSet[] priorit private void makeCallables(List> tasks, boolean updateAll, final TreeSet priorityQueue, final int updateRound, final Job unassignedJob, final Collection routes, final VehicleRoute lastModified) { if (updateAll) { - tasks.add(new Callable() { - @Override - public Boolean call() throws Exception { - return InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, priorityQueue, updateRound, unassignedJob, routes); - } - }); + tasks.add(() -> InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, priorityQueue, updateRound, unassignedJob, routes)); } else { - tasks.add(new Callable() { - @Override - public Boolean call() throws Exception { - return InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, priorityQueue, updateRound, unassignedJob, Arrays.asList(lastModified)); - } - }); + tasks.add(() -> InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, priorityQueue, updateRound, unassignedJob, Arrays.asList(lastModified))); } } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/RegretInsertionFast.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/RegretInsertionFast.java index de4b65a53..3d251c747 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/RegretInsertionFast.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/recreate/RegretInsertionFast.java @@ -18,15 +18,24 @@ package com.graphhopper.jsprit.core.algorithm.recreate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; import com.graphhopper.jsprit.core.problem.constraint.DependencyType; import com.graphhopper.jsprit.core.problem.job.Job; import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; import com.graphhopper.jsprit.core.problem.vehicle.VehicleFleetManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; /** * Insertion based on regret approach. @@ -52,7 +61,7 @@ public class RegretInsertionFast extends AbstractInsertionStrategy { private boolean switchAllowed = true; - private DependencyType[] dependencyTypes = null; + private Map dependencyTypes = null; public RegretInsertionFast(JobInsertionCostsCalculator jobInsertionCalculator, VehicleRoutingProblem vehicleRoutingProblem, VehicleFleetManager fleetManager) { super(vehicleRoutingProblem); @@ -79,12 +88,12 @@ public void setSwitchAllowed(boolean switchAllowed) { this.switchAllowed = switchAllowed; } - public void setDependencyTypes(DependencyType[] dependencyTypes) { + public void setDependencyTypes(Map dependencyTypes) { this.dependencyTypes = dependencyTypes; } private Set getInitialVehicleIds(VehicleRoutingProblem vehicleRoutingProblem) { - Set ids = new HashSet(); + Set ids = new HashSet<>(); for (VehicleRoute r : vehicleRoutingProblem.getInitialVehicleRoutes()) { ids.add(r.getVehicle().getId()); } @@ -104,37 +113,37 @@ public String toString() { */ @Override public Collection insertUnassignedJobs(Collection routes, Collection unassignedJobs) { - List badJobs = new ArrayList(unassignedJobs.size()); - -// Iterator 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 jobs = new ArrayList(unassignedJobs); - TreeSet[] priorityQueues = new TreeSet[vrp.getJobs().values().size() + 2]; + List badJobs = new ArrayList<>(unassignedJobs.size()); + + // Iterator 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 jobs = new ArrayList<>(unassignedJobs); + Map> priorityQueues = new HashMap<>(vrp.getJobs().values().size() + 2); VehicleRoute lastModified = null; boolean firstRun = true; int updateRound = 0; - Map updates = new HashMap(); + Map updates = new HashMap<>(); while (!jobs.isEmpty()) { - List unassignedJobList = new ArrayList(jobs); - List badJobList = new ArrayList(); + List unassignedJobList = new ArrayList<>(jobs); + List badJobList = new ArrayList<>(); if (!firstRun && lastModified == null) throw new IllegalStateException("last modified route is null. this should not be."); if (firstRun) { @@ -143,7 +152,7 @@ public Collection insertUnassignedJobs(Collection routes, Col } else { //update for all routes || remove history and only update modified route updateInsertionData(priorityQueues, routes, unassignedJobList, updateRound, firstRun, lastModified, updates); -// updates.put(lastModified,updateRound); + // updates.put(lastModified,updateRound); } updateRound++; ScoredJob bestScoredJob = InsertionDataUpdater.getBest(switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, scoringFunction, priorityQueues, updates, unassignedJobList, badJobList); @@ -154,7 +163,9 @@ public Collection insertUnassignedJobs(Collection routes, Col insertJob(bestScoredJob.getJob(), bestScoredJob.getInsertionData(), bestScoredJob.getRoute()); jobs.remove(bestScoredJob.getJob()); lastModified = bestScoredJob.getRoute(); - } else lastModified = null; + } else { + lastModified = null; + } for (Job bad : badJobList) { jobs.remove(bad); badJobs.add(bad); @@ -163,25 +174,40 @@ public Collection insertUnassignedJobs(Collection routes, Col return badJobs; } - private void updateInsertionData(TreeSet[] priorityQueues, Collection routes, List unassignedJobList, int updateRound, boolean firstRun, VehicleRoute lastModified, Map updates) { + private void updateInsertionData(Map> priorityQueues, + Collection routes, List unassignedJobList, int updateRound, boolean firstRun, + VehicleRoute lastModified, Map updates) { for (Job unassignedJob : unassignedJobList) { - if (priorityQueues[unassignedJob.getIndex()] == null) { - priorityQueues[unassignedJob.getIndex()] = new TreeSet(InsertionDataUpdater.getComparator()); + String unassignedJobId = unassignedJob.getId(); + if (priorityQueues.get(unassignedJobId) == null) { + priorityQueues.put(unassignedJobId, + new TreeSet<>(InsertionDataUpdater.getComparator())); } if (firstRun) { - InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, routes); - for (VehicleRoute r : routes) updates.put(r, updateRound); + InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, + priorityQueues.get(unassignedJobId), updateRound, unassignedJob, routes); + for (VehicleRoute r : routes) { + updates.put(r, updateRound); + } } else { - if (dependencyTypes == null || dependencyTypes[unassignedJob.getIndex()] == null) { - InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, Arrays.asList(lastModified)); + if (dependencyTypes == null || dependencyTypes.get(unassignedJobId) == null) { + InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, + insertionCostsCalculator, priorityQueues.get(unassignedJobId), updateRound, unassignedJob, + Arrays.asList(lastModified)); updates.put(lastModified, updateRound); } else { - DependencyType dependencyType = dependencyTypes[unassignedJob.getIndex()]; + DependencyType dependencyType = dependencyTypes.get(unassignedJobId); if (dependencyType.equals(DependencyType.INTER_ROUTE) || dependencyType.equals(DependencyType.INTRA_ROUTE)) { - InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, routes); - for (VehicleRoute r : routes) updates.put(r, updateRound); + InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, + insertionCostsCalculator, priorityQueues.get(unassignedJobId), updateRound, + unassignedJob, routes); + for (VehicleRoute r : routes) { + updates.put(r, updateRound); + } } else { - InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, insertionCostsCalculator, priorityQueues[unassignedJob.getIndex()], updateRound, unassignedJob, Arrays.asList(lastModified)); + InsertionDataUpdater.update(switchAllowed, initialVehicleIds, fleetManager, + insertionCostsCalculator, priorityQueues.get(unassignedJobId), updateRound, + unassignedJob, Arrays.asList(lastModified)); updates.put(lastModified, updateRound); } } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/ruin/JobNeighborhoodsOptimized.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/ruin/JobNeighborhoodsOptimized.java index 9d2b28270..3399a6fa2 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/ruin/JobNeighborhoodsOptimized.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/ruin/JobNeighborhoodsOptimized.java @@ -18,14 +18,21 @@ package com.graphhopper.jsprit.core.algorithm.ruin; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.graphhopper.jsprit.core.algorithm.ruin.distance.JobDistance; import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; import com.graphhopper.jsprit.core.problem.job.Job; import com.graphhopper.jsprit.core.util.StopWatch; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; /** * Created by schroeder on 07/01/15. @@ -50,9 +57,8 @@ public ArrayIterator(int noItems, int[] itemArray, Job[] jobs) { @Override public boolean hasNext() { - if (index < noItems && index < itemArray.length) { + if (index < noItems && index < itemArray.length) return true; - } return false; } @@ -73,6 +79,8 @@ public void remove() { private VehicleRoutingProblem vrp; + private Map jobIndexMapping; + private int[][] neighbors; private Job[] jobs; @@ -90,12 +98,16 @@ public JobNeighborhoodsOptimized(VehicleRoutingProblem vrp, JobDistance jobDista this.capacity = capacity; neighbors = new int[vrp.getJobsInclusiveInitialJobsInRoutes().size() + 1][capacity]; jobs = new Job[vrp.getJobsInclusiveInitialJobsInRoutes().size() + 1]; + jobIndexMapping = new HashMap<>(); + for (Job job : vrp.getJobsInclusiveInitialJobsInRoutes().values()) { + jobIndexMapping.put(job, jobIndexMapping.size()); + } logger.debug("initialize {}", this); } @Override public Iterator getNearestNeighborsIterator(int nNeighbors, Job neighborTo) { - int[] neighbors = this.neighbors[neighborTo.getIndex() - 1]; + int[] neighbors = this.neighbors[jobIndexMapping.get(neighborTo)]; return new ArrayIterator(nNeighbors, neighbors, jobs); } @@ -116,36 +128,37 @@ private void calculateDistancesFromJob2Job() { StopWatch stopWatch = new StopWatch(); stopWatch.start(); for (Job job_i : vrp.getJobsInclusiveInitialJobsInRoutes().values()) { - jobs[job_i.getIndex()] = job_i; - List jobList = new ArrayList(vrp.getJobsInclusiveInitialJobsInRoutes().values().size()); + jobs[jobIndexMapping.get(job_i)] = job_i; + List jobList = new ArrayList<>(vrp.getJobsInclusiveInitialJobsInRoutes().values().size()); for (Job job_j : vrp.getJobsInclusiveInitialJobsInRoutes().values()) { - if (job_i == job_j) continue; + if (job_i == job_j) { + continue; + } double distance = jobDistance.getDistance(job_i, job_j); - if (distance > maxDistance) maxDistance = distance; + if (distance > maxDistance) { + maxDistance = distance; + } ReferencedJob referencedJob = new ReferencedJob(job_j, distance); jobList.add(referencedJob); } Collections.sort(jobList, getComparator()); int[] jobIndices = new int[capacity]; for (int index = 0; index < capacity; index++) { - jobIndices[index] = jobList.get(index).getJob().getIndex(); + jobIndices[index] = jobIndexMapping.get(jobList.get(index).getJob()); } - neighbors[job_i.getIndex() - 1] = jobIndices; + neighbors[jobIndexMapping.get(job_i)] = jobIndices; } stopWatch.stop(); logger.debug("pre-processing comp-time: {}", stopWatch); } private Comparator getComparator() { - return new Comparator() { - @Override - public int compare(ReferencedJob o1, ReferencedJob o2) { - if (o1.getDistance() < o2.getDistance()) { - return -1; - } else if (o1.getDistance() > o2.getDistance()) { - return 1; - } else return 0; - } + return (o1, o2) -> { + if (o1.getDistance() < o2.getDistance()) + return -1; + else if (o1.getDistance() > o2.getDistance()) + return 1; + else return 0; }; } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/util/QuickCompactMatrix.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/util/QuickCompactMatrix.java new file mode 100644 index 000000000..ab5313946 --- /dev/null +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/algorithm/util/QuickCompactMatrix.java @@ -0,0 +1,240 @@ +package com.graphhopper.jsprit.core.algorithm.util; + +import java.util.Arrays; +import java.util.List; +import java.util.function.BiFunction; + +import com.graphhopper.jsprit.core.problem.HasIndex; + +/** + * A quick, compact, but flexible int array based matrix. + * + * @author Balage + * + * @param + * The type of the items. + */ +public class QuickCompactMatrix { + + // The shift in redirection array indexing: the minimum index of the items + private int shift; + // The size of the redirection array: the difference of the minimum and + // maximum index of the items + private int redirectionSize; + // The matrix size: the number of items + private int matrixSize; + // The redirection array: maps the item index to matrix index + private int[] redirection; + // The matrix + private int[][] matrix; + + /** + * Wrapper class to avoid repeated calculation. + * + * @author Balage + * + * @param + * The item type. + */ + private static class CopyWrapper implements BiFunction { + + private QuickCompactMatrix source; + private BiFunction valueCalculator; + + public CopyWrapper(QuickCompactMatrix source, BiFunction valueCalculator) { + this.source = source; + this.valueCalculator = valueCalculator; + } + + @Override + public Integer apply(S item1, S item2) { + if (source.contains(item1) && source.contains(item2)) + return source.getValue(item1, item2); + else + return valueCalculator.apply(item1, item2); + } + } + + /** + * Wraps the calculator to use an other instance of the matrix for + * calculating values whenever it is possible. + *

+ * The wrapper is helpful, when creating an extended matrix from an old one + * and the cost of calculating the value is high. + *

+ *

+ * This class wraps the original value calculator. When it is called to + * calculate a value, first checks if it is available in the source matrix + * and returns the value from the source. Otherwise it delegates the + * calculation to the wrapped calculator. + *

+ * + * @param source + * The source matrix. + * @param valueCalculator + * The calculator. + * @return A wrapped calculator. + */ + public static BiFunction getCopyWrapper(QuickCompactMatrix source, + BiFunction valueCalculator) { + return new CopyWrapper<>(source, valueCalculator); + } + + /** + * Plain constructor. + *

+ * It gets no other matrix to extend. + *

+ * + * @param items + * The list of items. + * @param valueCalculator + * The function to calculate matrix cell values. + */ + public QuickCompactMatrix(List items, BiFunction valueCalculator) { + calculateDimensions(items); + initializeRedirectionArray(items); + initializeMatrix(); + calculateValues(items, valueCalculator); + } + + /** + * Calculates the shift value and redirection array and the matrix size. + * + * @param items + * The list of items. + */ + private void calculateDimensions(List items) { + shift = 0; + int min = Integer.MAX_VALUE; + int max = 0; + for (T i : items) { + int idx = i.getIndex(); + if (idx < min) { + min = idx; + } + if (idx > max) { + max = idx; + } + } + shift = min; + redirectionSize = max - shift + 1; + matrixSize = items.size(); + } + + /** + * Initialize the redirection matrix. + * + * @param items + * The list of items. + */ + private void initializeRedirectionArray(List items) { + // Initialize the array and fill up with -1. (Filling the values with -1 + // ensures that IndexOutOfBounds is thrown when calling getValue with + // items not in this original list.) + redirection = new int[redirectionSize]; + Arrays.fill(redirection, -1); + + // Determine the matrix indexing for each item index + int counter = 0; + for (T i : items) { + redirection[i.getIndex() - shift] = counter++; + } + } + + /** + * Initialize the matrix. + */ + private void initializeMatrix() { + matrix = new int[matrixSize][matrixSize]; + } + + /** + * Calculates the matrix values. + *

+ * It only calculates the values above the from index. + *

+ * + * @param items + * The list of items. + * @param valueCalculator + * The value calculator to use. + */ + private void calculateValues(List items, BiFunction valueCalculator) { + for (int row = 0; row < matrixSize; row++) { + T rowItem = items.get(row); + int rowIndex = redirection[rowItem.getIndex() - shift]; + for (int col = 0; col < matrixSize; col++) { + T colItem = items.get(col); + int colIndex = redirection[colItem.getIndex() - shift]; + matrix[rowIndex][colIndex] = valueCalculator.apply(rowItem, colItem); + } + } + } + + /** + * Returns the value from the matrix. + * + * @param rowItem + * The row item. + * @param colItem + * The column item. + * @return The value from the matrix. + * @throws IndexOutOfBoundsException + * When any of the items passed are not mapped. + */ + public int getValue(T rowItem, T colItem) { + int rowIndex = redirection[rowItem.getIndex() - shift]; + int colIndex = redirection[colItem.getIndex() - shift]; + return matrix[rowIndex][colIndex]; + } + + /** + * Returns the internal (matrix) index of the item. + * + * @param item + * The item to get the index of. + * @return The matrix index or -1 if the item is not mapped. + */ + public int getMatrixIndex(T item) { + int rowItemIndex = item.getIndex() - shift; + if (rowItemIndex < 0 || rowItemIndex >= redirectionSize) + return -1; + else + return redirection[rowItemIndex]; + } + + /** + * Checks if the item is part of the matrix. + * + * @param item + * The item to check. + * @return True if the item is mapped in the matrix. + */ + public boolean contains(T item) { + return getMatrixIndex(item) != -1; + } + + /** + * @return The shift in index used when addressing the redirection array by + * item index. + */ + public int getShift() { + return shift; + } + + /** + * @return The size of the redirection array. + */ + public int getRedirectionSize() { + return redirectionSize; + } + + /** + * @return The matrix size. + */ + public int getMatrixSize() { + return matrixSize; + } + +} diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblem.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblem.java index 5d0e3fa0a..7c65a73ba 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblem.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblem.java @@ -17,6 +17,20 @@ */ package com.graphhopper.jsprit.core.problem; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.graphhopper.jsprit.core.distance.EuclideanDistanceCalculator; import com.graphhopper.jsprit.core.problem.cost.VehicleRoutingActivityCosts; import com.graphhopper.jsprit.core.problem.cost.VehicleRoutingTransportCosts; @@ -33,10 +47,6 @@ import com.graphhopper.jsprit.core.util.Coordinate; import com.graphhopper.jsprit.core.util.DefaultCosts; import com.graphhopper.jsprit.core.util.Locations; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; /** @@ -74,35 +84,27 @@ public static Builder newInstance() { private VehicleRoutingActivityCosts activityCosts = new WaitingTimeCosts(); - private Map jobs = new LinkedHashMap(); + private Map jobs = new LinkedHashMap<>(); - private Map tentativeJobs = new LinkedHashMap(); + private Map tentativeJobs = new LinkedHashMap<>(); - private Set jobsInInitialRoutes = new HashSet(); + private Set jobsInInitialRoutes = new HashSet<>(); - private Map tentative_coordinates = new HashMap(); + private Map tentative_coordinates = new HashMap<>(); private FleetSize fleetSize = FleetSize.INFINITE; - private Collection vehicleTypes = new ArrayList(); + private Collection vehicleTypes = new ArrayList<>(); - private Collection initialRoutes = new ArrayList(); + private Collection initialRoutes = new ArrayList<>(); - private Set uniqueVehicles = new LinkedHashSet(); + private Set uniqueVehicles = new LinkedHashSet<>(); - private Set addedVehicleIds = new LinkedHashSet(); + private Set addedVehicleIds = new LinkedHashSet<>(); private boolean hasBreaks = false; - private JobActivityFactory jobActivityFactory = new JobActivityFactory() { - - @Override - public List createActivities(Job job) { - // Now its safe, but be carful if another implementation of Job is made - return ((AbstractJob) job).getActivityList().getAll(); - } - - }; + private JobActivityFactory jobActivityFactory = job -> ((AbstractJob) job).getActivityList().getAll(); private int jobIndexCounter = 1; @@ -112,7 +114,7 @@ public List createActivities(Job job) { private int vehicleTypeIdIndexCounter = 1; - private Map typeKeyIndices = new HashMap(); + private Map typeKeyIndices = new HashMap<>(); // Deprecated ? // private Map> activityMap = new HashMap<>(); @@ -135,7 +137,7 @@ private void incVehicleTypeIdIndexCounter() { vehicleTypeIdIndexCounter++; } - private Set allLocations = new HashSet(); + private Set allLocations = new HashSet<>(); /** * Returns the unmodifiable map of collected locations (mapped by their location-id). @@ -155,14 +157,7 @@ public Map getLocationMap() { * @return locations */ public Locations getLocations() { - return new Locations() { - - @Override - public Coordinate getCoord(String id) { - return tentative_coordinates.get(id); - } - - }; + return id -> tentative_coordinates.get(id); } /** @@ -206,26 +201,52 @@ public Builder setFleetSize(FleetSize fleetSize) { * @throws IllegalStateException if job is neither a shipment nor a service, or jobId has already been added. */ public Builder addJob(Job job) { - if (!(job instanceof AbstractJob)) { + if (!(job instanceof AbstractJob)) throw new IllegalArgumentException("job must be of type AbstractJob"); - } return addJob((AbstractJob) job); } + /** + * Handshake class for C++ like friend visibility behavior emulation. + * + *

+ * This is not a class for the end-users. (To be frank, this class can't + * be instantiate outside the parent task. + *

+ * + *

+ * Based on + * {@link https://stackoverflow.com/questions/182278/is-there-a-way-to-simulate-the-c-friend-concept-in-java} + *

+ * + * @author Balage + */ + // C++ like friend behavior simulation + public final static class FriendlyHandshake { + private FriendlyHandshake() { + } + } + + private static final FriendlyHandshake FRIENDLY_HANDSHAKE = new FriendlyHandshake(); + /** * Adds a job which is either a service or a shipment. *

- *

Note that job.getId() must be unique, i.e. no job (either it is a shipment or a service) is allowed to have an already allocated id. + *

+ * Note that job.getId() must be unique, i.e. no job (either it is a + * shipment or a service) is allowed to have an already allocated id. * - * @param job job to be added + * @param job + * job to be added * @return this builder - * @throws IllegalStateException if job is neither a shipment nor a service, or jobId has already been added. + * @throws IllegalStateException + * if job is neither a shipment nor a service, or jobId has + * already been added. */ public Builder addJob(AbstractJob job) { - if (tentativeJobs.containsKey(job.getId())) { + if (tentativeJobs.containsKey(job.getId())) throw new IllegalArgumentException("vehicle routing problem already contains a service or shipment with id " + job.getId() + ". make sure you use unique ids for all services and shipments"); - } - job.impl_setIndex(jobIndexCounter); + // job.impl_setIndex(FRIENDLY_HANDSHAKE, jobIndexCounter); incJobIndexCounter(); tentativeJobs.put(job.getId(), job); addLocationToTentativeLocations(job); @@ -260,9 +281,8 @@ private boolean addBreaksToActivityMap() { if (v.getBreak() != null) { hasBreaks = true; List breakActivities = jobActivityFactory.createActivities(v.getBreak()); - if (breakActivities.isEmpty()) { + if (breakActivities.isEmpty()) throw new IllegalArgumentException("at least one activity for break needs to be created by activityFactory"); - } for (AbstractActivity act : breakActivities) { act.setIndex(activityIndexCounter); incActivityIndexCounter(); @@ -330,9 +350,8 @@ public Builder addInitialVehicleRoutes(Collection routes) { * @return this builder */ public Builder addVehicle(Vehicle vehicle) { - if (!(vehicle instanceof AbstractVehicle)) { + if (!(vehicle instanceof AbstractVehicle)) throw new IllegalArgumentException("vehicle must be an AbstractVehicle"); - } return addVehicle((AbstractVehicle) vehicle); } @@ -343,9 +362,9 @@ public Builder addVehicle(Vehicle vehicle) { * @return this builder */ public Builder addVehicle(AbstractVehicle vehicle) { - if (addedVehicleIds.contains(vehicle.getId())) { + if (addedVehicleIds.contains(vehicle.getId())) throw new IllegalArgumentException("problem already contains a vehicle with id " + vehicle.getId() + ". choose unique ids for each vehicle."); - } else { + else { addedVehicleIds.add(vehicle.getId()); } if (!uniqueVehicles.contains(vehicle)) { @@ -404,7 +423,7 @@ public Builder setActivityCosts(VehicleRoutingActivityCosts activityCosts) { public VehicleRoutingProblem build() { if (transportCosts == null) { transportCosts = new DefaultCosts(EuclideanDistanceCalculator.getInstance()) - .withCoordinateConverter(getLocations()); + .withCoordinateConverter(getLocations()); } for (Job job : tentativeJobs.values()) { if (!jobsInInitialRoutes.contains(job.getId())) { @@ -412,9 +431,8 @@ public VehicleRoutingProblem build() { } } boolean hasBreaks = addBreaksToActivityMap(); - if (hasBreaks && fleetSize.equals(FleetSize.INFINITE)) { + if (hasBreaks && fleetSize.equals(FleetSize.INFINITE)) throw new UnsupportedOperationException("breaks are not yet supported when dealing with infinite fleet. either set it to finite or omit breaks."); - } return new VehicleRoutingProblem(this); } @@ -538,14 +556,7 @@ public static enum FleetSize { private int nuActivities; - private final JobActivityFactory jobActivityFactory = new JobActivityFactory() { - - @Override - public List createActivities(Job job) { - return copyAndGetActivities(job); - } - - }; + private final JobActivityFactory jobActivityFactory = job -> copyAndGetActivities(job); private VehicleRoutingProblem(Builder builder) { jobs = builder.jobs; @@ -567,7 +578,7 @@ private VehicleRoutingProblem(Builder builder) { @Override public String toString() { return "[fleetSize=" + fleetSize + "][#jobs=" + jobs.size() + "][#vehicles=" + vehicles.size() + "][#vehicleTypes=" + vehicleTypes.size() + "][" + - "transportCost=" + transportCosts + "][activityCosts=" + activityCosts + "]"; + "transportCost=" + transportCosts + "][activityCosts=" + activityCosts + "]"; } /** @@ -600,7 +611,7 @@ public Map getJobsInclusiveInitialJobsInRoutes() { * @return copied collection of initial vehicle routes */ public Collection getInitialVehicleRoutes() { - Collection copiedInitialRoutes = new ArrayList(); + Collection copiedInitialRoutes = new ArrayList<>(); for (VehicleRoute route : initialVehicleRoutes) { copiedInitialRoutes.add(VehicleRoute.copyOf(route)); } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/ConstraintManager.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/ConstraintManager.java index 1a15d35e3..617591486 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/ConstraintManager.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/constraint/ConstraintManager.java @@ -17,19 +17,20 @@ */ package com.graphhopper.jsprit.core.problem.constraint; -import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; -import com.graphhopper.jsprit.core.problem.job.Job; -import com.graphhopper.jsprit.core.problem.misc.JobInsertionContext; -import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity; -import com.graphhopper.jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; +import com.graphhopper.jsprit.core.problem.misc.JobInsertionContext; +import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity; +import com.graphhopper.jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter; + /** * Manager that manage hard- and soft constraints, both on route and activity level. * @@ -61,38 +62,31 @@ public static enum Priority { private boolean skillconstraintSet = false; - private final DependencyType[] dependencyTypes; + private final HashMap dependencyTypes; public ConstraintManager(VehicleRoutingProblem vrp, RouteAndActivityStateGetter stateManager) { this.vrp = vrp; this.stateManager = stateManager; - dependencyTypes = new DependencyType[vrp.getJobs().size() + 1]; + dependencyTypes = new HashMap<>(vrp.getJobs().size() + 1); } public ConstraintManager(VehicleRoutingProblem vrp, RouteAndActivityStateGetter stateManager, Collection constraints) { this.vrp = vrp; this.stateManager = stateManager; - dependencyTypes = new DependencyType[vrp.getJobs().size() + 1]; + dependencyTypes = new HashMap<>(vrp.getJobs().size() + 1); resolveConstraints(constraints); } - public DependencyType[] getDependencyTypes() { + public HashMap getDependencyTypes() { return dependencyTypes; } public void setDependencyType(String jobId, DependencyType dependencyType) { - Job job = vrp.getJobs().get(jobId); - if (job != null) { - dependencyTypes[job.getIndex()] = dependencyType; - } + dependencyTypes.put(jobId, dependencyType); } public DependencyType getDependencyType(String jobId) { - Job job = vrp.getJobs().get(jobId); - if (job != null) { - return dependencyTypes[job.getIndex()]; - } - return DependencyType.NO_TYPE; + return dependencyTypes.getOrDefault(jobId, DependencyType.NO_TYPE); } private void resolveConstraints(Collection constraints) { @@ -145,7 +139,7 @@ public void addSkillsConstraint() { } } -// public void add + // public void add public void addConstraint(HardActivityConstraint actLevelConstraint, Priority priority) { actLevelConstraintManager.addConstraint(actLevelConstraint, priority); @@ -174,7 +168,7 @@ public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prev } public Collection getConstraints() { - List constraints = new ArrayList(); + List constraints = new ArrayList<>(); constraints.addAll(actLevelConstraintManager.getAllConstraints()); constraints.addAll(routeLevelConstraintManager.getConstraints()); constraints.addAll(softActivityConstraintManager.getConstraints()); diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/AbstractJob.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/AbstractJob.java index cfe0ae55d..6819fbbf2 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/AbstractJob.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/AbstractJob.java @@ -380,23 +380,28 @@ protected AbstractJob(JobBuilder builder) { AbstractJob() { } - @Override - public int getIndex() { - return index; - } - - /** - * Sets the index of the job within the problem. - *

- * This method isn't part of the public API and should not be called! - *

- * - * @param index - * The index. - */ - public void impl_setIndex(int index) { - this.index = index; - } + // @Override + // public int getIndex() { + // return index; + // } + + // + // /** + // * Sets the index of the job within the problem. + // *

+ // * This method isn't part of the public API and should not be called! + // If + // * it is still called, it will throw {@link IllegalStateException}. + // *

+ // * + // * @param index + // * The index. + // */ + // public void impl_setIndex(FriendlyHandshake handshake, int index) { + // if (handshake == null) + // throw new IllegalStateException(); + // this.index = index; + // } /** * @return User-specific domain data associated with the job diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/AbstractListBackedJobActivityList.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/AbstractListBackedJobActivityList.java index fb750c812..9195ea73c 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/AbstractListBackedJobActivityList.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/AbstractListBackedJobActivityList.java @@ -1,11 +1,11 @@ package com.graphhopper.jsprit.core.problem.job; -import com.graphhopper.jsprit.core.problem.solution.route.activity.JobActivity; - import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.graphhopper.jsprit.core.problem.solution.route.activity.JobActivity; + /** * Simple activity list implementation. *

@@ -29,12 +29,35 @@ public AbstractListBackedJobActivityList(AbstractJob job) { super(job); } + /** + * Handshake class for C++ like friend visibility behavior emulation. + * + *

+ * This is not a class for the end-users. (To be frank, this class can't be + * instantiate outside the parent task. + *

+ * + *

+ * Based on + * {@link https://stackoverflow.com/questions/182278/is-there-a-way-to-simulate-the-c-friend-concept-in-java} + *

+ * + * @author Balage + */ + // C++ like friend behavior simulation + public final static class FriendlyHandshake { + private FriendlyHandshake() { + } + } + + private static final FriendlyHandshake FRIENDLY_HANDSHAKE = new FriendlyHandshake(); + @Override public void addActivity(JobActivity activity) { validateActivity(activity); if (!_activities.contains(activity)) { _activities.add(activity); - activity.impl_setOrderNumber(_activities.size()); + activity.impl_setOrderNumber(FRIENDLY_HANDSHAKE, _activities.size()); } } @@ -55,9 +78,8 @@ public List getAll() { */ protected int indexOf(JobActivity activity) { int idx = _activities.indexOf(activity); - if (idx == -1) { + if (idx == -1) throw new IllegalArgumentException("Activity " + activity.getName() + " is not in the list."); - } return idx; } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Break.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Break.java index feccd29fe..30cf80937 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Break.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Break.java @@ -31,7 +31,7 @@ public class Break extends AbstractSingleActivityJob implements I public static final class Builder extends ServiceJob.BuilderBase { private static final Location VARIABLE_LOCATION = Location - .newInstance("@@@VARIABLE_LOCATION"); + .newInstance("@@@VARIABLE_LOCATION"); public Builder(String id) { super(id); @@ -71,7 +71,7 @@ protected Break createInstance() { @Override protected BreakActivity createActivity( - BuilderBase, ?> builder) { + BuilderBase, ?> builder) { return BreakActivity.newInstance(this, (Builder) builder); } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Job.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Job.java index 5312c4517..200fac98c 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Job.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Job.java @@ -22,7 +22,6 @@ import java.util.List; import com.graphhopper.jsprit.core.problem.HasId; -import com.graphhopper.jsprit.core.problem.HasIndex; import com.graphhopper.jsprit.core.problem.Location; import com.graphhopper.jsprit.core.problem.SizeDimension; import com.graphhopper.jsprit.core.problem.Skills; @@ -33,7 +32,7 @@ * * @author schroeder */ -public interface Job extends HasId, HasIndex { +public interface Job extends HasId { /** * Returns the unique identifier (id) of a job. diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Service.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Service.java index 9c0368310..45325575f 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Service.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Service.java @@ -363,8 +363,11 @@ public double getServiceDuration() { * @return time window * */ + @Deprecated public TimeWindow getTimeWindow() { - return theRealActivity.getSingleTimeWindow(); + if (getTheRealActivity().getTimeWindows().size() > 1) + throw new IllegalArgumentException("More than one time window in. " + this); + return getTheRealActivity().getTimeWindows().iterator().next(); } /** @@ -452,15 +455,15 @@ protected void createActivities(JobBuilder jobBuilder) // This is unused being a legacy implementation } - @Override - public int getIndex() { - return theRealJob.getIndex(); - } - - @Override - public void impl_setIndex(int index) { - theRealJob.impl_setIndex(index); - } + // @Override + // public int getIndex() { + // return theRealJob.getIndex(); + // } + // + // @Override + // public void impl_setIndex(FriendlyHandshake handshake, int index) { + // theRealJob.impl_setIndex(handshake, index); + // } @Override public List getAllLocations() { diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Shipment.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Shipment.java index 4613606df..5a21753c0 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Shipment.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/job/Shipment.java @@ -516,10 +516,10 @@ protected void createActivities(JobBuilder jobBuilder) // This is unused being a legacy implementation } - @Override - public int getIndex() { - return theRealJob.getIndex(); - } + // @Override + // public int getIndex() { + // return theRealJob.getIndex(); + // } @Override public Object getUserData() { @@ -556,10 +556,10 @@ public String toString() { return theRealJob.toString(); } - @Override - public void impl_setIndex(int index) { - theRealJob.impl_setIndex(index); - } + // @Override + // public void impl_setIndex(FriendlyHandshake handshake, int index) { + // theRealJob.impl_setIndex(handshake, index); + // } @Override diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/VehicleRoute.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/VehicleRoute.java index 40188c650..2a3b790ff 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/VehicleRoute.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/VehicleRoute.java @@ -22,19 +22,24 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import com.graphhopper.jsprit.core.problem.JobActivityFactory; -import com.graphhopper.jsprit.core.problem.SimpleJobActivityFactory; import com.graphhopper.jsprit.core.problem.driver.Driver; import com.graphhopper.jsprit.core.problem.driver.DriverImpl; +import com.graphhopper.jsprit.core.problem.job.AbstractJob; import com.graphhopper.jsprit.core.problem.job.AbstractSingleActivityJob; import com.graphhopper.jsprit.core.problem.job.Break; import com.graphhopper.jsprit.core.problem.job.DeliveryJob; import com.graphhopper.jsprit.core.problem.job.PickupJob; import com.graphhopper.jsprit.core.problem.job.ShipmentJob; +import com.graphhopper.jsprit.core.problem.solution.route.activity.DeliveryActivity; import com.graphhopper.jsprit.core.problem.solution.route.activity.End; import com.graphhopper.jsprit.core.problem.solution.route.activity.JobActivity; +import com.graphhopper.jsprit.core.problem.solution.route.activity.PickupActivity; import com.graphhopper.jsprit.core.problem.solution.route.activity.Start; import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow; import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivities; @@ -60,9 +65,8 @@ public class VehicleRoute { * if route is null */ public static VehicleRoute copyOf(VehicleRoute route) { - if (route == null) { + if (route == null) throw new IllegalArgumentException("route must not be null"); - } return new VehicleRoute(route); } @@ -83,11 +87,10 @@ public static VehicleRoute emptyRoute() { * Builder that builds the vehicle route. * * @author stefan + * @author Balage */ public static class Builder { - private Map openActivities = new HashMap<>(); - /** * Returns new instance of this builder. *

@@ -111,10 +114,9 @@ public static class Builder { * @return this builder */ public static Builder newInstance(Vehicle vehicle, Driver driver) { - if (vehicle == null || driver == null) { + if (vehicle == null || driver == null) throw new IllegalArgumentException( - "null arguments not accepted. ini emptyRoute with VehicleImpl.createNoVehicle() and DriverImpl.noDriver()"); - } + "null arguments not accepted. ini emptyRoute with VehicleImpl.createNoVehicle() and DriverImpl.noDriver()"); return new Builder(vehicle, driver); } @@ -139,10 +141,9 @@ public static Builder newInstance(Vehicle vehicle, Driver driver) { * @return this builder */ public static Builder newInstance(Vehicle vehicle) { - if (vehicle == null) { + if (vehicle == null) throw new IllegalArgumentException( - "null arguments not accepted. ini emptyRoute with VehicleImpl.createNoVehicle() and DriverImpl.noDriver()"); - } + "null arguments not accepted. ini emptyRoute with VehicleImpl.createNoVehicle() and DriverImpl.noDriver()"); return new Builder(vehicle, DriverImpl.noDriver()); } @@ -156,21 +157,6 @@ public static Builder newInstance(Vehicle vehicle) { private TourActivities tourActivities = new TourActivities(); - // private TourActivityFactory serviceActivityFactory = new - // DefaultTourActivityFactory(); - // - // private TourShipmentActivityFactory shipmentActivityFactory = new - // DefaultShipmentActivityFactory(); - - private Set openShipments = new HashSet<>(); - - private JobActivityFactory jobActivityFactory = new SimpleJobActivityFactory(); - - public Builder setJobActivityFactory(JobActivityFactory jobActivityFactory) { - this.jobActivityFactory = jobActivityFactory; - return this; - } - private Builder(Vehicle vehicle, Driver driver) { super(); this.vehicle = vehicle; @@ -180,218 +166,242 @@ private Builder(Vehicle vehicle, Driver driver) { end = new End(vehicle.getEndLocation(), 0.0, vehicle.getLatestArrival()); } + public Builder setDepartureTime(double departureTime) { + if (departureTime < start.getEndTime()) + throw new IllegalArgumentException( + "departureTime < vehicle.getEarliestDepartureTime(). this must not be."); + start.setEndTime(departureTime); + return this; + } + + /** - * Sets the departure-time of the route, i.e. which is the time the - * vehicle departs from start-location. - *

- *

- * Note that departureTime cannot be lower than - * earliestDepartureTime of vehicle. + * Adds the first activity of a job with its first time window. * - * @param departureTime - * departure time of vehicle being employed for this route - * @return builder - * @throws IllegalArgumentException - * if departureTime < vehicle.getEarliestDeparture() + * @param job + * The job to get the activity from. + * @return The builder. */ - public Builder setDepartureTime(double departureTime) { - if (departureTime < start.getEndTime()) { - throw new IllegalArgumentException("departureTime < vehicle.getEarliestDepartureTime(). this must not be."); - } - start.setEndTime(departureTime); + public Builder addActivity(AbstractJob job) { + return addActivity(job, 0); + } + + /** + * Adds all activities of a job with their first time window. + * + * @param job + * The job to get the activities from. + * @return The builder. + */ + public Builder addAllActivities(AbstractJob job) { + job.getActivityList().getAll().forEach(a -> addActivity(a)); return this; } /** - * Adds a service to this route. Activity is initialized with - * .getSingleTimeWindow(). If you want to explicitly set another time - * window use {@linkplain #addService(Service TimeWindow)} - *

- *

- * This implies that for this service a serviceActivity is created with - * {@link TourActivityFactory} and added to the sequence of - * tourActivities. - *

- *

- * The resulting activity occurs in the activity-sequence in the order - * adding/inserting. + * Adds the selected activity of a job with its first time window. + * + * @param job + * The job to get the activity from. + * @param activityIndex + * The (0-based) index of the activity to add. + * @return The builder. + * @throws IndexOutOfBoundsException + * When the index is invalid. + */ + public Builder addActivity(AbstractJob job, int activityIndex) { + if (job == null) + throw new IllegalArgumentException("job must not be null"); + JobActivity activity = job.getActivityList().getAll().get(activityIndex); + return addActivity(activity); + } + + /** + * Adds the first activity with the selected type of a job with its + * first time window. * *

- * Note: Using this method is not recommended. Use the - * {@linkplain #addService(AbstractSingleActivityJob, TimeWindow)} - * instead. + * Note: If your job has more than one activity of the same type, you + * have to add them manually: *

* - * @param service - * to be added - * @return this builder + *
+         * job.getActivityList().getAll().stream()
+         *     .filter(a -> a instanceof ExchangeActivity))
+         *     .forEach(a -> addActivity(a));
+         * 
+ * + * @param job + * The job to get the activity from. + * @param activityClass + * The class of the activity. + * @return The builder. * @throws IllegalArgumentException - * if service is null + * When there is no activity with the given type in the job. */ - public Builder addService(AbstractSingleActivityJob service) { - if (service == null) { - throw new IllegalArgumentException("service must not be null"); - } - return addSingleActivityJob(service); + public Builder addActivity(AbstractJob job, Class activityClass) { + if (job == null) + throw new IllegalArgumentException("job must not be null"); + Optional activity = job.getActivityList().getAll().stream() + .filter(a -> activityClass.isAssignableFrom(a.getClass())) + .findFirst(); + if (activity.isPresent()) + return addActivity(activity.get()); + else + throw new IllegalArgumentException("Job has no " + activityClass.getSimpleName() + " activity"); } - public Builder addService(AbstractSingleActivityJob service, - TimeWindow timeWindow) { - if (service == null) { - throw new IllegalArgumentException("service must not be null"); - } - return addSingleActivityJob(service, timeWindow); + /** + * Adds the first activity of a job with the given time window. + * + * @param job + * The job to get the activity from. + * @param timeWindow + * The time window to use. + * @return The builder. + */ + public Builder addActivity(AbstractJob job, TimeWindow timeWindow) { + return addActivity(job, 0, timeWindow); } - private Builder addSingleActivityJob(AbstractSingleActivityJob service) { - return addSingleActivityJob(service, service.getActivity().getSingleTimeWindow()); + /** + * Adds the first activity with the selected type of a job with the + * selected time window. + * + * @param job + * The job to get the activity from. + * @param activityClass + * The class of the activity. + * @param timeWindow + * The time window to use. + * @return The builder. + * @throws IllegalArgumentException + * When there is no activity with the given type in the job. + */ + public Builder addActivity(AbstractJob job, Class activityClass, TimeWindow timeWindow) { + if (job == null) + throw new IllegalArgumentException("job must not be null"); + Optional activity = job.getActivityList().getAll().stream() + .filter(a -> activityClass.isAssignableFrom(a.getClass())) + .findFirst(); + if (activity.isPresent()) + return addActivity(activity.get(), timeWindow); + else + throw new IllegalArgumentException("Job has no " + activityClass.getSimpleName() + " activity"); } - private Builder addSingleActivityJob(AbstractSingleActivityJob service, - TimeWindow timeWindow) { - if (service == null) { - throw new IllegalArgumentException("service must not be null"); - } - List acts = jobActivityFactory.createActivities(service); - TourActivity act = acts.get(0); - act.setTheoreticalEarliestOperationStartTime(timeWindow.getStart()); - act.setTheoreticalLatestOperationStartTime(timeWindow.getEnd()); - tourActivities.addActivity(act); + /** + * Adds the selected activity of a job with the specified time window. + * + * @param job + * The job to get the activity from. + * @param activityIndex + * The (0-based) index of the activity to add. + * @param timeWindow + * The time window to use. + * @return The builder. + * @throws IndexOutOfBoundsException + * When the index is invalid. + */ + public Builder addActivity(AbstractJob job, int activityIndex, TimeWindow timeWindow) { + if (job == null) + throw new IllegalArgumentException("job must not be null"); + TourActivity act = job.getActivityList().getAll().get(activityIndex); + return addActivity(act, timeWindow); + } + + /** + * Adds the activity to the route with its first time window. + * + * @param activity + * The activity to add. + * @return The builder. + */ + public Builder addActivity(JobActivity activity) { + return addActivity(activity, activity.getTimeWindows().iterator().next()); + } + + /** + * Adds the activity to the route with the selected time window. + * + * @param activity + * The activity to add. + * @param timeWindow + * The time window to use. + * @return The builder. + */ + public Builder addActivity(TourActivity activity, TimeWindow timeWindow) { + if (activity == null) + throw new IllegalArgumentException("activity must not be null"); + activity.setTheoreticalEarliestOperationStartTime(timeWindow.getStart()); + activity.setTheoreticalLatestOperationStartTime(timeWindow.getEnd()); + tourActivities.addActivity(activity); return this; } + @Deprecated + public Builder addService(AbstractSingleActivityJob service) { + return addActivity(service); + } + + @Deprecated + public Builder addService(AbstractSingleActivityJob service, TimeWindow timeWindow) { + return addActivity(service, timeWindow); + } + + @Deprecated public Builder addBreak(Break currentbreak) { - if (currentbreak == null) { - throw new IllegalArgumentException("break must not be null"); - } - return addSingleActivityJob(currentbreak); + return addActivity(currentbreak); } + @Deprecated public Builder addBreak(Break currentbreak, TimeWindow timeWindow) { - if (currentbreak == null) { - throw new IllegalArgumentException("break must not be null"); - } - return addSingleActivityJob(currentbreak, timeWindow); + return addActivity(currentbreak, timeWindow); } - /** - * Adds a pickup to this route. - * - *

- * Note: Using this method is not recommended. Use the - * {@linkplain #addPickup(PickupJob, TimeWindow)} instead. - *

- * - * @param pickup - * pickup to be added - * @return the builder - */ + @Deprecated public Builder addPickup(PickupJob pickup) { - if (pickup == null) { - throw new IllegalArgumentException("pickup must not be null"); - } - return addService(pickup); + return addActivity(pickup); } + @Deprecated public Builder addPickup(PickupJob pickup, TimeWindow timeWindow) { - if (pickup == null) { - throw new IllegalArgumentException("pickup must not be null"); - } - return addSingleActivityJob(pickup, timeWindow); + return addActivity(pickup, timeWindow); } - /** - * Adds a delivery to this route. - * - *

- * Note: Using this method is not recommended. Use the - * {@linkplain #addDelivery(DeliveryJob, TimeWindow)} instead. - *

- * - * - * @param delivery - * delivery to be added - * @return the builder - */ + @Deprecated public Builder addDelivery(DeliveryJob delivery) { - if (delivery == null) { - throw new IllegalArgumentException("delivery must not be null"); - } - return addService(delivery); + return addActivity(delivery); } + @Deprecated public Builder addDelivery(DeliveryJob delivery, TimeWindow timeWindow) { - if (delivery == null) { - throw new IllegalArgumentException("delivery must not be null"); - } - return addSingleActivityJob(delivery, timeWindow); + return addActivity(delivery, timeWindow); } - /** - * Adds a the pickup of the specified shipment. - * - *

- * Note: Using this method is not recommended. Use the - * {@linkplain #addPickup(ShipmentJob, TimeWindow)} instead. - *

- * - * @param shipment - * to be picked up and added to this route - * @return the builder - * @throws IllegalArgumentException - * if method has already been called with the specified - * shipment. - */ + @Deprecated public Builder addPickup(ShipmentJob shipment) { - return addPickup(shipment, - shipment.getPickupActivity().getSingleTimeWindow()); + return addActivity(shipment, PickupActivity.class); } + @Deprecated public Builder addPickup(ShipmentJob shipment, TimeWindow pickupTimeWindow) { - if (openShipments.contains(shipment)) { - throw new IllegalArgumentException("shipment has already been added. cannot add it twice."); - } - List acts = jobActivityFactory.createActivities(shipment); - TourActivity act = acts.get(0); - act.setTheoreticalEarliestOperationStartTime(pickupTimeWindow.getStart()); - act.setTheoreticalLatestOperationStartTime(pickupTimeWindow.getEnd()); - tourActivities.addActivity(act); - openShipments.add(shipment); - openActivities.put(shipment, acts.get(1)); - return this; + return addActivity(shipment, PickupActivity.class, pickupTimeWindow); } - /** - * Adds a the delivery of the specified shipment. The shipment could - * have only one time window. - * - *

- * Note: Using this method is not recommended. Use the - * {@linkplain #addDelivery(ShipmentJob, TimeWindow)} instead. - *

- * - * @param shipment - * to be delivered and add to this vehicleRoute - * @return builder - * @throws IllegalArgumentException - * if specified shipment has not been picked up yet (i.e. - * method addPickup(shipment) has not been called yet). - */ + @Deprecated public Builder addDelivery(ShipmentJob shipment) { - return addDelivery(shipment, shipment.getDeliveryActivity().getSingleTimeWindow()); + return addActivity(shipment, DeliveryActivity.class); } + @Deprecated public Builder addDelivery(ShipmentJob shipment, TimeWindow deliveryTimeWindow) { - if (openShipments.contains(shipment)) { - TourActivity act = openActivities.get(shipment); - act.setTheoreticalEarliestOperationStartTime(deliveryTimeWindow.getStart()); - act.setTheoreticalLatestOperationStartTime(deliveryTimeWindow.getEnd()); - tourActivities.addActivity(act); - openShipments.remove(shipment); - } else { - throw new IllegalArgumentException( - "cannot deliver shipment. shipment " + shipment + " needs to be picked up first."); - } + return addActivity(shipment, PickupActivity.class, deliveryTimeWindow); + + } + + public Builder setJobActivityFactory(JobActivityFactory copyJobActivityFactory) { + // TODO Does nothing and it is a problem return this; } @@ -404,9 +414,7 @@ public Builder addDelivery(ShipmentJob shipment, TimeWindow deliveryTimeWindow) * though but not delivery. */ public VehicleRoute build() { - if (!openShipments.isEmpty()) { - throw new IllegalArgumentException("there are still shipments that have not been delivered yet."); - } + validateActivities(); if (!vehicle.isReturnToDepot()) { if (!tourActivities.isEmpty()) { end.setLocation(tourActivities.getActivities().get(tourActivities.getActivities().size() - 1).getLocation()); @@ -415,6 +423,56 @@ public VehicleRoute build() { return new VehicleRoute(this); } + private void validateActivities() { + Map> activityCounter = new HashMap<>(); + Set activities = new HashSet<>(); + Set duplicatedActivities = new HashSet<>(); + tourActivities.getActivities().stream() + .filter(a -> a instanceof JobActivity) + .map(a -> (JobActivity) a) + .forEach(ja -> { + // Checks duplicated activities + if (activities.contains(ja)) { + duplicatedActivities.add(ja); + return; + } + activities.add(ja); + + AbstractJob job = ja.getJob(); + // New job, add all activities to missing list + if (!activityCounter.containsKey(job)) { + activityCounter.put(job, new HashSet<>(job.getActivityList().getAll())); + } + Set missingActivities = activityCounter.get(job); + + // Remove activity from missing + missingActivities.remove(ja); + + // All activity has been found + if (missingActivities.isEmpty()) { + activityCounter.remove(job); + } + }); + + if (!duplicatedActivities.isEmpty()) { + System.err.println("Duplicated activities: \n" + duplicatedActivities.stream() + .map(a -> a.toString()) + .collect(Collectors.joining("\n ", " ", ""))); + } + if (!activityCounter.isEmpty()) { + System.err.println("Missing activities:"); + for (Entry> missing : activityCounter.entrySet()) { + System.err.println(" "+missing.getKey()); + for (JobActivity act : missing.getValue()) { + System.err.println(" "+act); + } + } + } + + if (!duplicatedActivities.isEmpty() || !activityCounter.isEmpty()) + throw new IllegalArgumentException("Invalid route. See details above."); + } + } private TourActivities tourActivities; @@ -557,10 +615,9 @@ private void setStartAndEnd(Vehicle vehicle, double vehicleDepTime) { * if start is null */ public double getDepartureTime() { - if (start == null) { + if (start == null) throw new IllegalArgumentException( - "cannot get departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead."); - } + "cannot get departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead."); return start.getEndTime(); } @@ -595,8 +652,8 @@ public End getEnd() { @Override public String toString() { return "[id=" + id + "][start=" + start + "][end=" + end + "][departureTime=" + start.getEndTime() + "][vehicle=" + vehicle - + "][driver=" - + driver + "][nuOfActs=" + tourActivities.getActivities().size() + "]"; + + "][driver=" + + driver + "][nuOfActs=" + tourActivities.getActivities().size() + "]"; } public void setId(int id) { diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/activity/BreakActivity.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/activity/BreakActivity.java index 2e473b7a1..73f4393a9 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/activity/BreakActivity.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/activity/BreakActivity.java @@ -116,9 +116,9 @@ public void setLocation(Location breakLocation) { /** * @return The time window of the break. */ - public TimeWindow getTimeWindow() { + public TimeWindow getBreakTimeWindow() { // Break has always a single time window - return getSingleTimeWindow(); + return getTimeWindows().iterator().next(); } } diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/activity/JobActivity.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/activity/JobActivity.java index 66f216cd0..88f9ecc10 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/activity/JobActivity.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/solution/route/activity/JobActivity.java @@ -6,6 +6,7 @@ import com.graphhopper.jsprit.core.problem.Location; import com.graphhopper.jsprit.core.problem.SizeDimension; import com.graphhopper.jsprit.core.problem.job.AbstractJob; +import com.graphhopper.jsprit.core.problem.job.AbstractListBackedJobActivityList.FriendlyHandshake; import com.graphhopper.jsprit.core.problem.job.Job; /** @@ -97,18 +98,6 @@ public Collection getTimeWindows() { return timeWindows; } - /** - * @return A single time window. - * @throws IllegalArgumentException - * When more than one time window exists. - */ - // TODO: Is it legacy code, should be removed later - @Deprecated - public TimeWindow getSingleTimeWindow() { - if (timeWindows.size() > 1) - throw new IllegalArgumentException("More than one time window in. " + this); - return timeWindows.iterator().next(); - } @Override public int hashCode() { @@ -148,12 +137,18 @@ public int getOrderNumber() { /** * Sets the order number of the activity within the job. *

- * Warning! This function is not part of the API. + * Warning! This function is not part of the API. Calling it would throw + * {@linkplain IllegalStateException}. *

* + * @param friendLock + * Internal friend handshake object. * @param orderNumber + * The order number. */ - public void impl_setOrderNumber(int orderNumber) { + public void impl_setOrderNumber(FriendlyHandshake hadshake, int orderNumber) { + if (hadshake == null) + throw new IllegalStateException(); this.orderNumber = orderNumber; } diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/IgnoreBreakTimeWindowTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/IgnoreBreakTimeWindowTest.java index be9f4de0d..a467a9dcf 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/IgnoreBreakTimeWindowTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/IgnoreBreakTimeWindowTest.java @@ -65,30 +65,30 @@ public void doNotIgnoreBreakTW() { ServiceJob service4 = new ServiceJob.Builder("2").setLocation(Location.newInstance(0, 0)) - .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(17, 17)).build(); + .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(17, 17)).build(); ServiceJob service5 = new ServiceJob.Builder("3").setLocation(Location.newInstance(0, 0)) - .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(18, 18)).build(); + .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(18, 18)).build(); ServiceJob service7 = new ServiceJob.Builder("4").setLocation(Location.newInstance(0, 0)) - .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(10, 10)).build(); + .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(10, 10)).build(); ServiceJob service8 = new ServiceJob.Builder("5").setLocation(Location.newInstance(0, 0)) - .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(12, 12)).build(); + .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(12, 12)).build(); ServiceJob service10 = new ServiceJob.Builder("6").setLocation(Location.newInstance(0, 0)) - .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(16, 16)).build(); + .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(16, 16)).build(); ServiceJob service11 = new ServiceJob.Builder("7").setLocation(Location.newInstance(0, 0)) - .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(13, 13)).build(); + .setServiceTime(1.).setTimeWindow(TimeWindow.newInstance(13, 13)).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance() - .addVehicle(vehicle2) - .addJob(service4) - .addJob(service5).addJob(service7) - .addJob(service8).addJob(service10).addJob(service11) - .setFleetSize(VehicleRoutingProblem.FleetSize.FINITE) - .build(); + .addVehicle(vehicle2) + .addJob(service4) + .addJob(service5).addJob(service7) + .addJob(service8).addJob(service10).addJob(service11) + .setFleetSize(VehicleRoutingProblem.FleetSize.FINITE) + .build(); VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp); vra.setMaxIterations(50); @@ -103,7 +103,7 @@ private boolean breakShouldBeTime(VehicleRoutingProblemSolution solution) { boolean inTime = true; for (TourActivity act : solution.getRoutes().iterator().next().getActivities()) { if (act instanceof BreakActivity) { - TimeWindow timeWindow = ((BreakActivity) act).getSingleTimeWindow(); + TimeWindow timeWindow = ((BreakActivity) act).getBreakTimeWindow(); if (act.getEndTime() < timeWindow.getStart()) { inTime = false; } diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/state/UpdateVehicleDependentTimeWindowTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/state/UpdateVehicleDependentTimeWindowTest.java index 28f297a60..eb5ce91f7 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/state/UpdateVehicleDependentTimeWindowTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/state/UpdateVehicleDependentTimeWindowTest.java @@ -90,7 +90,7 @@ public void doBefore() { vrpBuilder.addVehicle(vehicle).addVehicle(vehicle2).addVehicle(vehicle3).addVehicle(equivalentOf3); - Collection vehicles = new ArrayList(); + Collection vehicles = new ArrayList<>(); vehicles.add(vehicle); vehicles.add(vehicle2); vehicles.add(vehicle3); @@ -106,22 +106,17 @@ public void doBefore() { vrp = vrpBuilder.build(); route = VehicleRoute.Builder.newInstance(vehicle).setJobActivityFactory(new CopyJobActivityFactory()) - .addService(service).addService(service2) - .addService(service3).build(); + .addService(service).addService(service2) + .addService(service3).build(); stateManager = new StateManager(vrp); UpdateVehicleDependentPracticalTimeWindows updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, routingCosts, activityCosts); - updater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() { - - @Override - public Collection get(VehicleRoute route) { - Collection vehicles = new ArrayList(); - vehicles.add(route.getVehicle()); - vehicles.addAll(fleetManager.getAvailableVehicles(route.getVehicle())); - return vehicles; - } - + updater.setVehiclesToUpdate(route -> { + Collection vehicles1 = new ArrayList<>(); + vehicles1.add(route.getVehicle()); + vehicles1.addAll(fleetManager.getAvailableVehicles(route.getVehicle())); + return vehicles1; }); stateManager.addStateUpdater(updater); stateManager.informInsertionStarts(Arrays.asList(route), Collections.emptyList()); @@ -141,68 +136,68 @@ public void whenSwitchIsNotAllowed_itShouldCalOnlyStatesOfCurrentVehicle() { @Test public void stateManagerShouldHaveMemorizedCorrectLatestEndOfAct3() { assertEquals(70., stateManager.getActivityState(route.getActivities().get(2), vehicle, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @Test public void stateManagerShouldHaveMemorizedCorrectLatestEndOfAct3_v2() { assertEquals(70., stateManager.getActivityState(route.getActivities().get(2), vehicle, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @Test public void stateManagerShouldHaveMemorizedCorrectLatestEndOfAct3WithVehicle2() { assertEquals(30., stateManager.getActivityState(route.getActivities().get(2), vehicle2, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @Test public void stateManagerShouldHaveMemorizedCorrectLatestEndOfAct3WithVehicle3() { assertEquals(90., stateManager.getActivityState(route.getActivities().get(2), vehicle3, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @Test public void stateManagerShouldHaveMemorizedCorrectLatestEndOfAct2() { assertEquals(60., stateManager.getActivityState(route.getActivities().get(1), vehicle, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @Test public void stateManagerShouldHaveMemorizedCorrectLatestEndOfAct2_v2() { assertEquals(60., stateManager.getActivityState(route.getActivities().get(1), vehicle, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @Test public void stateManagerShouldHaveMemorizedCorrectLatestEndOfAct2WithVehicle2() { assertEquals(20., stateManager.getActivityState(route.getActivities().get(1), vehicle2, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @Test public void stateManagerShouldHaveMemorizedCorrectLatestEndOfAct2WithVehicle3() { assertEquals(80., stateManager.getActivityState(route.getActivities().get(1), vehicle3, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @Test public void stateManagerShouldHaveMemorizedCorrectLatestEndOfAct2WithEquivalentOfVehicle3() { assertEquals(80., stateManager.getActivityState(route.getActivities().get(1), equivalentOf3, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @Test public void stateManagerShouldHaveMemorizedCorrectLatestEndOfAct1WithVehicle2() { assertEquals(10., stateManager.getActivityState(route.getActivities().get(0), vehicle2, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @Test public void stateManagerShouldHaveMemorizedCorrectLatestEndOfAct1WithVehicle3() { assertEquals(70., stateManager.getActivityState(route.getActivities().get(0), vehicle3, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @@ -211,54 +206,51 @@ public void twUpdateShouldWorkWithMultipleTWs() { // VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("0,0")).setEarliestStart(0.).setLatestArrival(100.).build(); ServiceJob service = new ServiceJob.Builder("s1").setLocation(Location.newInstance("10,0")) - .addTimeWindow(30, 40).build(); + .addTimeWindow(30, 40).build(); ServiceJob service2 = new ServiceJob.Builder("s2") - .addTimeWindow(20, 30).addTimeWindow(40, 60).addTimeWindow(70, 80).setLocation(Location.newInstance("20,0")).build(); + .addTimeWindow(20, 30).addTimeWindow(40, 60).addTimeWindow(70, 80).setLocation(Location.newInstance("20,0")).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(service).addJob(service2).addVehicle(vehicle) - .setRoutingCost(routingCosts).build(); + .setRoutingCost(routingCosts).build(); - VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle).setJobActivityFactory(vrp.getJobActivityFactory()) - .addService(service).addService(service2, TimeWindow.newInstance(70, 80)) - .build(); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle) + .setJobActivityFactory(vrp.getJobActivityFactory()) + .addService(service) + .addService(service2, TimeWindow.newInstance(70, 80)) + .build(); StateManager stateManager = new StateManager(vrp); UpdateVehicleDependentPracticalTimeWindows updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, routingCosts, activityCosts); - updater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() { - - @Override - public Collection get(VehicleRoute route) { - Collection vehicles = new ArrayList(); - vehicles.add(route.getVehicle()); - // vehicles.addAll(fleetManager.getAvailableVehicles(route.getVehicle())); - return vehicles; - } - + updater.setVehiclesToUpdate(route1 -> { + Collection vehicles = new ArrayList<>(); + vehicles.add(route1.getVehicle()); + // vehicles.addAll(fleetManager.getAvailableVehicles(route.getVehicle())); + return vehicles; }); stateManager.addStateUpdater(updater); stateManager.informInsertionStarts(Arrays.asList(route), Collections.emptyList()); assertEquals(80., stateManager.getActivityState(route.getActivities().get(1), vehicle, - InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); + InternalStates.LATEST_OPERATION_START_TIME, Double.class), 0.01); } @Test public void updateOfOpenRoutesShouldBeDoneCorrectly() { VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v") - .setReturnToDepot(false) - .setStartLocation(Location.Builder.newInstance().setCoordinate(Coordinate.newInstance(0, 0)).build()) - .setLatestArrival(51) - .build(); + .setReturnToDepot(false) + .setStartLocation(Location.Builder.newInstance().setCoordinate(Coordinate.newInstance(0, 0)).build()) + .setLatestArrival(51) + .build(); ServiceJob service = new ServiceJob.Builder("s") - .setLocation(Location.Builder.newInstance().setCoordinate(Coordinate.newInstance(50, 0)).build()).build(); + .setLocation(Location.Builder.newInstance().setCoordinate(Coordinate.newInstance(50, 0)).build()).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance() - .addJob(service).addVehicle(vehicle).setFleetSize(VehicleRoutingProblem.FleetSize.FINITE) - .build(); + .addJob(service).addVehicle(vehicle).setFleetSize(VehicleRoutingProblem.FleetSize.FINITE) + .build(); VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle) - .setJobActivityFactory(vrp.getJobActivityFactory()).addService(service).build(); + .setJobActivityFactory(vrp.getJobActivityFactory()).addService(service).build(); stateManager = new StateManager(vrp); UpdateVehicleDependentPracticalTimeWindows updater = new UpdateVehicleDependentPracticalTimeWindows(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts()); diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/util/QuickCompactMatrixTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/util/QuickCompactMatrixTest.java new file mode 100644 index 000000000..62baf8194 --- /dev/null +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/algorithm/util/QuickCompactMatrixTest.java @@ -0,0 +1,122 @@ +package com.graphhopper.jsprit.core.algorithm.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; + +import org.junit.Test; + +import com.graphhopper.jsprit.core.problem.HasIndex; + +public class QuickCompactMatrixTest { + + public static class Item implements HasIndex { + private int index; + + public Item(int index) { + this.index = index; + } + + @Override + public int getIndex() { + return index; + } + } + + private static final BiFunction INDEX_DIST = (i1, i2) -> Math + .abs(i1.getIndex() - i2.getIndex()); + + private List create(int... indexes) { + List res = new ArrayList<>(indexes.length); + for (int indexe : indexes) { + res.add(new Item(indexe)); + } + return res; + } + + @Test + public void whenConstructed_correctSizesCalculated() { + List items = create(0, 1, 2, 3, 4); + QuickCompactMatrix matrix = new QuickCompactMatrix<>(items, INDEX_DIST); + assertEquals(0, matrix.getShift()); + assertEquals(5, matrix.getRedirectionSize()); + assertEquals(5, matrix.getMatrixSize()); + } + + @Test + public void whenConstructed_correctShiftIsCorrect() { + List items = create(1, 3, 5, 7, 9); + QuickCompactMatrix matrix = new QuickCompactMatrix<>(items, INDEX_DIST); + assertEquals(1, matrix.getShift()); + assertEquals(9, matrix.getRedirectionSize()); + assertEquals(5, matrix.getMatrixSize()); + } + + @Test + public void whenReadingMatrixIndex_correctValueIsReturned() { + List items = create(1, 3, 5, 7, 9); + QuickCompactMatrix matrix = new QuickCompactMatrix<>(items, INDEX_DIST); + assertEquals(0, matrix.getMatrixIndex(items.get(0))); + assertEquals(4, matrix.getMatrixIndex(items.get(4))); + assertEquals(-1, matrix.getMatrixIndex(new Item(0))); + assertEquals(-1, matrix.getMatrixIndex(new Item(10))); + assertEquals(-1, matrix.getMatrixIndex(new Item(2))); + } + + @Test + public void whenCallingContains_correctAnswerIsReturned() { + List items = create(1, 3, 5, 7, 9); + QuickCompactMatrix matrix = new QuickCompactMatrix<>(items, INDEX_DIST); + assertTrue(matrix.contains(items.get(0))); + assertTrue(matrix.contains(items.get(4))); + assertFalse(matrix.contains(new Item(0))); + assertFalse(matrix.contains(new Item(10))); + assertFalse(matrix.contains(new Item(2))); + } + + @Test + public void whenReadingValue_correctValueIsReturned() { + List items = create(1, 3, 5, 7, 9); + QuickCompactMatrix matrix = new QuickCompactMatrix<>(items, INDEX_DIST); + assertEquals(2, matrix.getValue(items.get(0), items.get(1))); + assertEquals(6, matrix.getValue(items.get(0), items.get(3))); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void whenReadingValueOfWrongItem_exceptionIsThrown() { + List items = create(1, 3, 5, 7, 9); + QuickCompactMatrix matrix = new QuickCompactMatrix<>(items, INDEX_DIST); + assertEquals(2, matrix.getValue(items.get(0), new Item(2))); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void whenReadingValueOfWrongItem_exceptionIsThrown_underflow() { + List items = create(1, 3, 5, 7, 9); + QuickCompactMatrix matrix = new QuickCompactMatrix<>(items, INDEX_DIST); + assertEquals(2, matrix.getValue(items.get(0), new Item(0))); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void whenReadingValueOfWrongItem_exceptionIsThrown_overflow() { + List items = create(1, 3, 5, 7, 9); + QuickCompactMatrix matrix = new QuickCompactMatrix<>(items, INDEX_DIST); + assertEquals(2, matrix.getValue(items.get(0), new Item(10))); + } + + @Test + public void whenConstructedWithCopy_theValuesAreCorrect() { + List sourceItems = create(0, 1, 2, 3, 4); + QuickCompactMatrix sourceMatrix = new QuickCompactMatrix<>(sourceItems, INDEX_DIST); + List items = create(1, 2, 5); + QuickCompactMatrix matrix = new QuickCompactMatrix<>(items, + QuickCompactMatrix.getCopyWrapper(sourceMatrix, INDEX_DIST)); + + assertEquals(1, matrix.getValue(items.get(0), items.get(1))); + assertEquals(4, matrix.getValue(items.get(0), items.get(2))); + } + +} diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblemTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblemTest.java index b1ad85795..74181d9d9 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblemTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/VehicleRoutingProblemTest.java @@ -241,7 +241,7 @@ public void whenServicesAreAddedAllAtOnce_vrpShouldContainThem() { when(s2.getId()).thenReturn("s2"); when(s2.getActivityList()).thenReturn(new SequentialJobActivityList(s2)); - Collection services = new ArrayList(); + Collection services = new ArrayList<>(); services.add(s1); services.add(s2); @@ -285,13 +285,13 @@ public void whenSettingRoutingCosts_vprShouldContainIt() { @Override public double getTransportTime(Location from, Location to, - double departureTime, Driver driver, Vehicle vehicle) { + double departureTime, Driver driver, Vehicle vehicle) { return 0; } @Override public double getTransportCost(Location from, Location to, - double departureTime, Driver driver, Vehicle vehicle) { + double departureTime, Driver driver, Vehicle vehicle) { return 4.0; } }); @@ -362,7 +362,7 @@ public void whenAddingTwoVehicleWithDiffType_getAddedVehicleTypesShouldReturnThe @Test public void whenAddingVehicleWithDiffStartAndEnd_startLocationMustBeRegisteredInLocationMap() { VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")) - .setEndLocation(Location.newInstance("end")).build(); + .setEndLocation(Location.newInstance("end")).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addVehicle(vehicle); @@ -372,7 +372,7 @@ public void whenAddingVehicleWithDiffStartAndEnd_startLocationMustBeRegisteredIn @Test public void whenAddingVehicleWithDiffStartAndEnd_endLocationMustBeRegisteredInLocationMap() { VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")) - .setEndLocation(Location.newInstance("end")).build(); + .setEndLocation(Location.newInstance("end")).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addVehicle(vehicle); @@ -382,7 +382,7 @@ public void whenAddingVehicleWithDiffStartAndEnd_endLocationMustBeRegisteredInLo @Test public void whenAddingInitialRoute_itShouldBeAddedCorrectly() { VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v") - .setStartLocation(Location.newInstance("start")).setEndLocation(Location.newInstance("end")).build(); + .setStartLocation(Location.newInstance("start")).setEndLocation(Location.newInstance("end")).build(); VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addInitialVehicleRoute(route); @@ -393,11 +393,11 @@ public void whenAddingInitialRoute_itShouldBeAddedCorrectly() { @Test public void whenAddingInitialRoutes_theyShouldBeAddedCorrectly() { VehicleImpl vehicle1 = VehicleImpl.Builder.newInstance("v") - .setStartLocation(Location.newInstance("start")).setEndLocation(Location.newInstance("end")).build(); + .setStartLocation(Location.newInstance("start")).setEndLocation(Location.newInstance("end")).build(); VehicleRoute route1 = VehicleRoute.Builder.newInstance(vehicle1, DriverImpl.noDriver()).build(); VehicleImpl vehicle2 = VehicleImpl.Builder.newInstance("v") - .setStartLocation(Location.newInstance("start")).setEndLocation(Location.newInstance("end")).build(); + .setStartLocation(Location.newInstance("start")).setEndLocation(Location.newInstance("end")).build(); VehicleRoute route2 = VehicleRoute.Builder.newInstance(vehicle2, DriverImpl.noDriver()).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); @@ -413,8 +413,8 @@ public void whenAddingInitialRoute_locationOfVehicleMustBeMemorized() { Location start = TestUtils.loc("start", Coordinate.newInstance(0, 1)); Location end = Location.newInstance("end"); VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v") - .setStartLocation(start) - .setEndLocation(end).build(); + .setStartLocation(start) + .setEndLocation(end).build(); VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addInitialVehicleRoute(route); @@ -429,8 +429,8 @@ public void whenAddingJobAndInitialRouteWithThatJobAfterwards_thisJobShouldNotBe VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addJob(service); VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v") - .setStartLocation(TestUtils.loc("start", Coordinate.newInstance(0, 1))) - .setEndLocation(Location.newInstance("end")).build(); + .setStartLocation(TestUtils.loc("start", Coordinate.newInstance(0, 1))) + .setEndLocation(Location.newInstance("end")).build(); VehicleRoute initialRoute = VehicleRoute.Builder.newInstance(vehicle).addService(service).build(); vrpBuilder.addInitialVehicleRoute(initialRoute); VehicleRoutingProblem vrp = vrpBuilder.build(); @@ -438,21 +438,24 @@ public void whenAddingJobAndInitialRouteWithThatJobAfterwards_thisJobShouldNotBe assertEquals(3, vrp.getAllLocations().size()); } - @Test - public void whenAddingTwoJobs_theyShouldHaveProperIndeces() { - ServiceJob service = new ServiceJob.Builder("myService").setLocation(Location.newInstance("loc")).build(); - ShipmentJob shipment = new ShipmentJob.Builder("shipment").setPickupLocation(Location.Builder.newInstance().setId("pick").build()) - .setDeliveryLocation(Location.newInstance("del")).build(); - VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); - vrpBuilder.addJob(service); - vrpBuilder.addJob(shipment); - VehicleRoutingProblem vrp = vrpBuilder.build(); - - assertEquals(1, service.getIndex()); - assertEquals(2, shipment.getIndex()); - assertEquals(3, vrp.getAllLocations().size()); - - } + // @Test + // public void whenAddingTwoJobs_theyShouldHaveProperIndeces() { + // ServiceJob service = new + // ServiceJob.Builder("myService").setLocation(Location.newInstance("loc")).build(); + // ShipmentJob shipment = new + // ShipmentJob.Builder("shipment").setPickupLocation(Location.Builder.newInstance().setId("pick").build()) + // .setDeliveryLocation(Location.newInstance("del")).build(); + // VehicleRoutingProblem.Builder vrpBuilder = + // VehicleRoutingProblem.Builder.newInstance(); + // vrpBuilder.addJob(service); + // vrpBuilder.addJob(shipment); + // VehicleRoutingProblem vrp = vrpBuilder.build(); + // + // assertEquals(1, service.getIndex()); + // assertEquals(2, shipment.getIndex()); + // assertEquals(3, vrp.getAllLocations().size()); + // + // } @Test(expected = IllegalArgumentException.class) public void whenAddingTwoServicesWithTheSameId_itShouldThrowException() { @@ -467,9 +470,9 @@ public void whenAddingTwoServicesWithTheSameId_itShouldThrowException() { @Test(expected = IllegalArgumentException.class) public void whenAddingTwoShipmentsWithTheSameId_itShouldThrowException() { ShipmentJob shipment1 = new ShipmentJob.Builder("shipment").setPickupLocation(Location.Builder.newInstance().setId("pick").build()) - .setDeliveryLocation(Location.newInstance("del")).build(); + .setDeliveryLocation(Location.newInstance("del")).build(); ShipmentJob shipment2 = new ShipmentJob.Builder("shipment").setPickupLocation(Location.Builder.newInstance().setId("pick").build()) - .setDeliveryLocation(Location.newInstance("del")).build(); + .setDeliveryLocation(Location.newInstance("del")).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addJob(shipment1); vrpBuilder.addJob(shipment2); @@ -480,9 +483,9 @@ public void whenAddingTwoShipmentsWithTheSameId_itShouldThrowException() { @Test public void whenAddingTwoVehicles_theyShouldHaveProperIndices() { VehicleImpl veh1 = VehicleImpl.Builder.newInstance("v1").setStartLocation(TestUtils.loc("start", Coordinate.newInstance(0, 1))) - .setEndLocation(Location.newInstance("end")).build(); + .setEndLocation(Location.newInstance("end")).build(); VehicleImpl veh2 = VehicleImpl.Builder.newInstance("v2").setStartLocation(TestUtils.loc("start", Coordinate.newInstance(0, 1))) - .setEndLocation(Location.newInstance("end")).build(); + .setEndLocation(Location.newInstance("end")).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addVehicle(veh1); @@ -497,11 +500,11 @@ public void whenAddingTwoVehicles_theyShouldHaveProperIndices() { @Test public void whenAddingTwoVehiclesWithSameTypeIdentifier_typeIdentifiersShouldHaveSameIndices() { VehicleImpl veh1 = VehicleImpl.Builder.newInstance("v1") - .setStartLocation(TestUtils.loc("start", Coordinate.newInstance(0, 1))) - .setEndLocation(Location.newInstance("end")).build(); + .setStartLocation(TestUtils.loc("start", Coordinate.newInstance(0, 1))) + .setEndLocation(Location.newInstance("end")).build(); VehicleImpl veh2 = VehicleImpl.Builder.newInstance("v2") - .setStartLocation(TestUtils.loc("start", Coordinate.newInstance(0, 1))) - .setEndLocation(Location.newInstance("end")).build(); + .setStartLocation(TestUtils.loc("start", Coordinate.newInstance(0, 1))) + .setEndLocation(Location.newInstance("end")).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addVehicle(veh1); @@ -516,11 +519,11 @@ public void whenAddingTwoVehiclesWithSameTypeIdentifier_typeIdentifiersShouldHav @Test public void whenAddingTwoVehiclesDifferentTypeIdentifier_typeIdentifiersShouldHaveDifferentIndices() { VehicleImpl veh1 = VehicleImpl.Builder.newInstance("v1") - .setStartLocation(TestUtils.loc("start", Coordinate.newInstance(0, 1))) - .setEndLocation(Location.newInstance("end")).build(); + .setStartLocation(TestUtils.loc("start", Coordinate.newInstance(0, 1))) + .setEndLocation(Location.newInstance("end")).build(); VehicleImpl veh2 = VehicleImpl.Builder.newInstance("v2") - .setStartLocation(TestUtils.loc("startLoc", Coordinate.newInstance(0, 1))) - .setEndLocation(Location.newInstance("end")).build(); + .setStartLocation(TestUtils.loc("startLoc", Coordinate.newInstance(0, 1))) + .setEndLocation(Location.newInstance("end")).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); vrpBuilder.addVehicle(veh1); diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/job/ServiceJobTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/job/ServiceJobTest.java index 271952d83..591c29458 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/job/ServiceJobTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/job/ServiceJobTest.java @@ -54,7 +54,7 @@ public void whenTwoServicesHaveTheSameId_theyShouldBeEqual() { @Test public void noName() { - Set serviceSet = new HashSet(); + Set serviceSet = new HashSet<>(); ServiceJob one = new ServiceJob.Builder("service").addSizeDimension(0, 10).setLocation(Location.newInstance("foo")).build(); ServiceJob two = new ServiceJob.Builder("service").addSizeDimension(0, 10).setLocation(Location.newInstance("fo")).build(); serviceSet.add(one); @@ -72,18 +72,18 @@ public void whenCapacityDimValueIsNegative_throwIllegalStateExpception() { @Test public void whenAddingTwoCapDimension_nuOfDimsShouldBeTwo() { ServiceJob one = new ServiceJob.Builder("s").setLocation(Location.newInstance("foofoo")) - .addSizeDimension(0, 2) - .addSizeDimension(1, 4) - .build(); + .addSizeDimension(0, 2) + .addSizeDimension(1, 4) + .build(); assertEquals(2, one.getActivity().getLoadChange().getNuOfDimensions()); } @Test public void sizeAtStartAndEndShouldBeCorrect() { ServiceJob one = new ServiceJob.Builder("s").setLocation(Location.newInstance("foofoo")) - .addSizeDimension(0, 2) - .addSizeDimension(1, 4) - .build(); + .addSizeDimension(0, 2) + .addSizeDimension(1, 4) + .build(); assertTrue(one.getSizeAtEnd().equals(one.getActivity().getLoadChange())); assertTrue(one.getSizeAtStart().equals(SizeDimension.Builder.newInstance().addDimension(0, 0).addDimension(1, 0).build())); } @@ -91,7 +91,7 @@ public void sizeAtStartAndEndShouldBeCorrect() { @Test public void whenShipmentIsBuiltWithoutSpecifyingCapacity_itShouldHvCapWithOneDimAndDimValOfZero() { ServiceJob one = new ServiceJob.Builder("s").setLocation(Location.newInstance("foofoo")) - .build(); + .build(); assertEquals(1, one.getActivity().getLoadChange().getNuOfDimensions()); assertEquals(0, one.getActivity().getLoadChange().get(0)); } @@ -99,7 +99,7 @@ public void whenShipmentIsBuiltWithoutSpecifyingCapacity_itShouldHvCapWithOneDim @Test public void whenShipmentIsBuiltWithConstructorWhereSizeIsSpecified_capacityShouldBeSetCorrectly() { ServiceJob one = new ServiceJob.Builder("s").addSizeDimension(0, 1).setLocation(Location.newInstance("foofoo")) - .build(); + .build(); assertEquals(1, one.getActivity().getLoadChange().getNuOfDimensions()); assertEquals(1, one.getActivity().getLoadChange().get(0)); } @@ -167,14 +167,14 @@ public void whenTimeWindowIsNull_throwException() { @Test public void whenSettingTimeWindow_itShouldBeSetCorrectly() { ServiceJob s = new ServiceJob.Builder("s").setLocation(Location.newInstance("loc")).setTimeWindow(TimeWindow.newInstance(1.0, 2.0)).build(); - assertEquals(1.0, s.getActivity().getSingleTimeWindow().getStart(), 0.01); - assertEquals(2.0, s.getActivity().getSingleTimeWindow().getEnd(), 0.01); + assertEquals(1.0, s.getActivity().getTimeWindows().iterator().next().getStart(), 0.01); + assertEquals(2.0, s.getActivity().getTimeWindows().iterator().next().getEnd(), 0.01); } @Test public void whenAddingSkills_theyShouldBeAddedCorrectly() { ServiceJob s = new ServiceJob.Builder("s").setLocation(Location.newInstance("loc")) - .addRequiredSkill("drill").addRequiredSkill("screwdriver").build(); + .addRequiredSkill("drill").addRequiredSkill("screwdriver").build(); assertTrue(s.getRequiredSkills().containsSkill("drill")); assertTrue(s.getRequiredSkills().containsSkill("drill")); assertTrue(s.getRequiredSkills().containsSkill("ScrewDriver")); @@ -183,7 +183,7 @@ public void whenAddingSkills_theyShouldBeAddedCorrectly() { @Test public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly() { ServiceJob s = new ServiceJob.Builder("s").setLocation(Location.newInstance("loc")) - .addRequiredSkill("DriLl").addRequiredSkill("screwDriver").build(); + .addRequiredSkill("DriLl").addRequiredSkill("screwDriver").build(); assertTrue(s.getRequiredSkills().containsSkill("drill")); assertTrue(s.getRequiredSkills().containsSkill("drilL")); } @@ -193,9 +193,9 @@ public void whenAddingSeveralTimeWindows_itShouldBeSetCorrectly() { TimeWindow tw1 = TimeWindow.newInstance(1.0, 2.0); TimeWindow tw2 = TimeWindow.newInstance(3.0, 5.0); ServiceJob s = new ServiceJob.Builder("s").setLocation(Location.newInstance("loc")) - .addTimeWindow(tw1) - .addTimeWindow(tw2) - .build(); + .addTimeWindow(tw1) + .addTimeWindow(tw2) + .build(); assertEquals(2, s.getActivity().getTimeWindows().size()); assertThat(s.getActivity().getTimeWindows(), hasItem(is(tw1))); assertThat(s.getActivity().getTimeWindows(), hasItem(is(tw2))); @@ -204,16 +204,16 @@ public void whenAddingSeveralTimeWindows_itShouldBeSetCorrectly() { @Test public void whenAddingTimeWindow_itShouldBeSetCorrectly() { ServiceJob s = new ServiceJob.Builder("s").setLocation(Location.newInstance("loc")) - .addTimeWindow(TimeWindow.newInstance(1.0, 2.0)).build(); - assertEquals(1.0, s.getActivity().getSingleTimeWindow().getStart(), 0.01); - assertEquals(2.0, s.getActivity().getSingleTimeWindow().getEnd(), 0.01); + .addTimeWindow(TimeWindow.newInstance(1.0, 2.0)).build(); + assertEquals(1.0, s.getActivity().getTimeWindows().iterator().next().getStart(), 0.01); + assertEquals(2.0, s.getActivity().getTimeWindows().iterator().next().getEnd(), 0.01); } @Test public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly() { ServiceJob s = new ServiceJob.Builder("s").setLocation(Location.newInstance("loc")) - .addRequiredSkill("screwDriver").build(); + .addRequiredSkill("screwDriver").build(); assertFalse(s.getRequiredSkills().containsSkill("drill")); assertFalse(s.getRequiredSkills().containsSkill("drilL")); } @@ -221,15 +221,15 @@ public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly() { @Test public void nameShouldBeAssigned() { ServiceJob s = new ServiceJob.Builder("s").setLocation(Location.newInstance("loc")) - .setName("name").build(); + .setName("name").build(); assertEquals("name", s.getName()); } @Test public void shouldKnowMultipleTimeWindows() { ServiceJob s = new ServiceJob.Builder("s").setLocation(Location.newInstance("loc")) - .addTimeWindow(TimeWindow.newInstance(0., 10.)).addTimeWindow(TimeWindow.newInstance(20., 30.)) - .setName("name").build(); + .addTimeWindow(TimeWindow.newInstance(0., 10.)).addTimeWindow(TimeWindow.newInstance(20., 30.)) + .setName("name").build(); assertEquals(2, s.getActivity().getTimeWindows().size()); } @@ -252,21 +252,21 @@ public void whenMultipleTWOverlap2_throwEx() { @Test public void whenSettingPriorities_itShouldBeSetCorrectly() { ServiceJob s = new ServiceJob.Builder("s").setLocation(Location.newInstance("loc")) - .setPriority(1).build(); + .setPriority(1).build(); assertEquals(1, s.getPriority()); } @Test public void whenSettingPriorities_itShouldBeSetCorrectly2() { ServiceJob s = new ServiceJob.Builder("s").setLocation(Location.newInstance("loc")) - .setPriority(3).build(); + .setPriority(3).build(); assertEquals(3, s.getPriority()); } @Test public void whenNotSettingPriorities_defaultShouldBe2() { ServiceJob s = new ServiceJob.Builder("s").setLocation(Location.newInstance("loc")) - .build(); + .build(); assertEquals(2, s.getPriority()); } diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/job/ShipmentJobTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/job/ShipmentJobTest.java index 6b1259eed..384fdeb6b 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/job/ShipmentJobTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/job/ShipmentJobTest.java @@ -38,9 +38,9 @@ public class ShipmentJobTest { @Test public void whenTwoShipmentsHaveTheSameId_theyReferencesShouldBeUnEqual() { ShipmentJob one = new ShipmentJob.Builder("s").addSizeDimension(0, 10).setPickupLocation(Location.Builder.newInstance().setId("foo").build()). - setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); + setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); ShipmentJob two = new ShipmentJob.Builder("s").addSizeDimension(0, 10).setPickupLocation(Location.Builder.newInstance().setId("foo").build()). - setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); + setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); assertTrue(one != two); } @@ -48,7 +48,7 @@ public void whenTwoShipmentsHaveTheSameId_theyReferencesShouldBeUnEqual() { @Test public void sizeAtStartAndEndShouldBeCorrect() { ShipmentJob one = new ShipmentJob.Builder("s").addSizeDimension(0, 10).addSizeDimension(1, 5).setPickupLocation(Location.Builder.newInstance().setId("foo").build()). - setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); + setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); SizeDimension cap = SizeDimension.Builder.newInstance().addDimension(0, 0).addDimension(1, 0).build(); assertTrue(one.getSizeAtStart().equals(cap)); assertTrue(one.getSizeAtEnd().equals(cap)); @@ -57,9 +57,9 @@ public void sizeAtStartAndEndShouldBeCorrect() { @Test public void whenTwoShipmentsHaveTheSameId_theyShouldBeEqual() { ShipmentJob one = new ShipmentJob.Builder("s").addSizeDimension(0, 10).setPickupLocation(Location.Builder.newInstance().setId("foo").build()). - setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); + setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); ShipmentJob two = new ShipmentJob.Builder("s").addSizeDimension(0, 10).setPickupLocation(Location.Builder.newInstance().setId("foo").build()). - setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); + setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); assertTrue(one.equals(two)); } @@ -67,7 +67,7 @@ public void whenTwoShipmentsHaveTheSameId_theyShouldBeEqual() { @Test public void whenShipmentIsInstantiatedWithASizeOf10_theSizeShouldBe10() { ShipmentJob one = new ShipmentJob.Builder("s").addSizeDimension(0, 10).setPickupLocation(Location.Builder.newInstance().setId("foo").build()). - setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); + setDeliveryLocation(TestUtils.loc("foofoo")).setPickupServiceTime(10).setDeliveryServiceTime(20).build(); assertEquals(10, one.getSize().get(0)); } @@ -129,7 +129,7 @@ public void whenPickupLocationIsNull_itThrowsException() { @Test public void whenPickupCoordIsSet_itShouldBeDoneCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s") - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").setCoordinate(Coordinate.newInstance(1, 2)).build()).build(); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").setCoordinate(Coordinate.newInstance(1, 2)).build()).build(); assertEquals(1.0, s.getPickupActivity().getLocation().getCoordinate().getX(), 0.01); assertEquals(2.0, s.getPickupActivity().getLocation().getCoordinate().getY(), 0.01); assertEquals(1.0, s.getPickupActivity().getLocation().getCoordinate().getX(), 0.01); @@ -140,7 +140,7 @@ public void whenPickupCoordIsSet_itShouldBeDoneCorrectly() { @Test public void whenDeliveryLocationIdIsSet_itShouldBeDoneCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s") - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); assertEquals("delLoc", s.getDeliveryActivity().getLocation().getId()); assertEquals("delLoc", s.getDeliveryActivity().getLocation().getId()); } @@ -149,8 +149,8 @@ public void whenDeliveryLocationIdIsSet_itShouldBeDoneCorrectly() { @Test public void whenDeliveryCoordIsSet_itShouldBeDoneCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s").setDeliveryLocation(TestUtils.loc("delLoc", Coordinate.newInstance(1, 2))) - .setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()) - .build(); + .setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()) + .build(); assertEquals(1.0, s.getDeliveryActivity().getLocation().getCoordinate().getX(), 0.01); assertEquals(2.0, s.getDeliveryActivity().getLocation().getCoordinate().getY(), 0.01); assertEquals(1.0, s.getDeliveryActivity().getLocation().getCoordinate().getX(), 0.01); @@ -160,22 +160,22 @@ public void whenDeliveryCoordIsSet_itShouldBeDoneCorrectly() { @Test public void whenPickupServiceTimeIsNotSet_itShouldBeZero() { ShipmentJob s = new ShipmentJob.Builder("s") - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); assertEquals(0.0, s.getPickupActivity().getOperationTime(), 0.01); } @Test public void whenDeliveryServiceTimeIsNotSet_itShouldBeZero() { ShipmentJob s = new ShipmentJob.Builder("s") - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); assertEquals(0.0, s.getDeliveryActivity().getOperationTime(), 0.01); } @Test public void whenPickupServiceTimeIsSet_itShouldBeDoneCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s") - .setPickupServiceTime(2.0) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + .setPickupServiceTime(2.0) + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); assertEquals(2.0, s.getPickupActivity().getOperationTime(), 0.01); } @@ -189,7 +189,7 @@ public void whenPickupServiceIsSmallerThanZero_itShouldThrowException() { @Test public void whenDeliveryServiceTimeIsSet_itShouldBeDoneCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s").setDeliveryServiceTime(2.0) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); assertEquals(2.0, s.getDeliveryActivity().getOperationTime(), 0.01); } @@ -202,10 +202,10 @@ public void whenDeliveryServiceIsSmallerThanZero_itShouldThrowException() { @Test public void whenPickupTimeWindowIsNotSet_itShouldBeTheDefaultOne() { ShipmentJob s = new ShipmentJob.Builder("s").setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); - assertEquals(0.0, s.getPickupActivity().getSingleTimeWindow().getStart(), - 0.01); + assertEquals(0.0, s.getPickupActivity().getTimeWindows().iterator().next().getStart(), + 0.01); assertEquals(Double.MAX_VALUE, - s.getPickupActivity().getSingleTimeWindow().getEnd(), 0.01); + s.getPickupActivity().getTimeWindows().iterator().next().getEnd(), 0.01); } @Test(expected = IllegalArgumentException.class) @@ -217,19 +217,19 @@ public void whenPickupTimeWindowIsNull_itShouldThrowException() { @Test public void whenPickupTimeWindowIsSet_itShouldBeDoneCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s").setPickupTimeWindow(TimeWindow.newInstance(1, 2)) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); - assertEquals(1.0, s.getPickupActivity().getSingleTimeWindow().getStart(), - 0.01); - assertEquals(2.0, s.getPickupActivity().getSingleTimeWindow().getEnd(), 0.01); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + assertEquals(1.0, s.getPickupActivity().getTimeWindows().iterator().next().getStart(), + 0.01); + assertEquals(2.0, s.getPickupActivity().getTimeWindows().iterator().next().getEnd(), 0.01); } @Test public void whenDeliveryTimeWindowIsNotSet_itShouldBeTheDefaultOne() { ShipmentJob s = new ShipmentJob.Builder("s").setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); - assertEquals(0.0, s.getDeliveryActivity().getSingleTimeWindow().getStart(), - 0.01); + assertEquals(0.0, s.getDeliveryActivity().getTimeWindows().iterator().next().getStart(), + 0.01); assertEquals(Double.MAX_VALUE, - s.getDeliveryActivity().getSingleTimeWindow().getEnd(), 0.01); + s.getDeliveryActivity().getTimeWindows().iterator().next().getEnd(), 0.01); } @Test(expected = IllegalArgumentException.class) @@ -241,31 +241,31 @@ public void whenDeliveryTimeWindowIsNull_itShouldThrowException() { @Test public void whenDeliveryTimeWindowIsSet_itShouldBeDoneCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s").setDeliveryTimeWindow(TimeWindow.newInstance(1, 2)) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); - assertEquals(1.0, s.getDeliveryActivity().getSingleTimeWindow().getStart(), - 0.01); - assertEquals(2.0, s.getDeliveryActivity().getSingleTimeWindow().getEnd(), - 0.01); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + assertEquals(1.0, s.getDeliveryActivity().getTimeWindows().iterator().next().getStart(), + 0.01); + assertEquals(2.0, s.getDeliveryActivity().getTimeWindows().iterator().next().getEnd(), + 0.01); } @Test public void whenUsingAddDeliveryTimeWindow_itShouldBeDoneCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s").addDeliveryTimeWindow(TimeWindow.newInstance(1, 2)) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); - assertEquals(1.0, s.getDeliveryActivity().getSingleTimeWindow().getStart(), - 0.01); - assertEquals(2.0, s.getDeliveryActivity().getSingleTimeWindow().getEnd(), - 0.01); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + assertEquals(1.0, s.getDeliveryActivity().getTimeWindows().iterator().next().getStart(), + 0.01); + assertEquals(2.0, s.getDeliveryActivity().getTimeWindows().iterator().next().getEnd(), + 0.01); } @Test public void whenUsingAddDeliveryTimeWindow2_itShouldBeDoneCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s").addDeliveryTimeWindow(1, 2) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); - assertEquals(1.0, s.getDeliveryActivity().getSingleTimeWindow().getStart(), - 0.01); - assertEquals(2.0, s.getDeliveryActivity().getSingleTimeWindow().getEnd(), - 0.01); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + assertEquals(1.0, s.getDeliveryActivity().getTimeWindows().iterator().next().getStart(), + 0.01); + assertEquals(2.0, s.getDeliveryActivity().getTimeWindows().iterator().next().getEnd(), + 0.01); } @Test @@ -273,7 +273,7 @@ public void whenAddingMultipleDeliveryTimeWindows_itShouldBeDoneCorrectly() { TimeWindow tw1 = TimeWindow.newInstance(1, 2); TimeWindow tw2 = TimeWindow.newInstance(4, 5); ShipmentJob s = new ShipmentJob.Builder("s").addDeliveryTimeWindow(tw1).addDeliveryTimeWindow(tw2) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); assertEquals(s.getDeliveryActivity().getTimeWindows().size(), 2); assertThat(s.getDeliveryActivity().getTimeWindows(), hasItem(is(tw1))); assertThat(s.getDeliveryActivity().getTimeWindows(), hasItem(is(tw2))); @@ -281,31 +281,31 @@ public void whenAddingMultipleDeliveryTimeWindows_itShouldBeDoneCorrectly() { @Test(expected = IllegalArgumentException.class) public void whenAddingMultipleOverlappingDeliveryTimeWindows_itShouldThrowException() { - ShipmentJob s = new ShipmentJob.Builder("s").addDeliveryTimeWindow(1, 3).addDeliveryTimeWindow(2, 5) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); - assertEquals(1.0, s.getDeliveryActivity().getSingleTimeWindow().getStart(), - 0.01); - assertEquals(2.0, s.getDeliveryActivity().getSingleTimeWindow().getEnd(), - 0.01); + ShipmentJob s = new ShipmentJob.Builder("s") + .addDeliveryTimeWindow(1, 3) + .addDeliveryTimeWindow(2, 5) + .setDeliveryLocation(TestUtils.loc("delLoc")) + .setPickupLocation(Location.newInstance("pickLoc")) + .build(); } @Test public void whenUsingAddPickupTimeWindow_itShouldBeDoneCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s").addPickupTimeWindow(TimeWindow.newInstance(1, 2)) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); - assertEquals(1.0, s.getPickupActivity().getSingleTimeWindow().getStart(), - 0.01); - assertEquals(2.0, s.getPickupActivity().getSingleTimeWindow().getEnd(), 0.01); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + assertEquals(1.0, s.getPickupActivity().getTimeWindows().iterator().next().getStart(), + 0.01); + assertEquals(2.0, s.getPickupActivity().getTimeWindows().iterator().next().getEnd(), 0.01); } @Test public void whenUsingAddPickupTimeWindow2_itShouldBeDoneCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s").addPickupTimeWindow(1, 2) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); - assertEquals(1.0, s.getPickupActivity().getSingleTimeWindow().getStart(), - 0.01); - assertEquals(2.0, s.getPickupActivity().getSingleTimeWindow().getEnd(), 0.01); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + assertEquals(1.0, s.getPickupActivity().getTimeWindows().iterator().next().getStart(), + 0.01); + assertEquals(2.0, s.getPickupActivity().getTimeWindows().iterator().next().getEnd(), 0.01); } @Test @@ -313,7 +313,7 @@ public void whenAddingMultiplePickupTimeWindows_itShouldBeDoneCorrectly() { TimeWindow tw1 = TimeWindow.newInstance(1, 2); TimeWindow tw2 = TimeWindow.newInstance(4, 5); ShipmentJob s = new ShipmentJob.Builder("s").addPickupTimeWindow(tw1).addPickupTimeWindow(tw2) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); + .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); assertEquals(s.getPickupActivity().getTimeWindows().size(), 2); assertThat(s.getPickupActivity().getTimeWindows(), hasItem(is(tw1))); assertThat(s.getPickupActivity().getTimeWindows(), hasItem(is(tw2))); @@ -321,10 +321,11 @@ public void whenAddingMultiplePickupTimeWindows_itShouldBeDoneCorrectly() { @Test(expected = IllegalArgumentException.class) public void whenAddingMultipleOverlappingPickupTimeWindows_itShouldThrowException() { - ShipmentJob s = new ShipmentJob.Builder("s").addPickupTimeWindow(1, 3).addPickupTimeWindow(2, 5) - .setDeliveryLocation(TestUtils.loc("delLoc")).setPickupLocation(Location.Builder.newInstance().setId("pickLoc").build()).build(); - assertEquals(1.0, s.getPickupActivity().getSingleTimeWindow().getStart(), 0.01); - assertEquals(2.0, s.getPickupActivity().getSingleTimeWindow().getEnd(), 0.01); + ShipmentJob s = new ShipmentJob.Builder("s") + .addPickupTimeWindow(1, 3) + .addPickupTimeWindow(2, 5) + .setDeliveryLocation(TestUtils.loc("delLoc")) + .setPickupLocation(Location.newInstance("pickLoc")).build(); } @@ -340,18 +341,18 @@ public void whenShipmentHasNegativeCapacityVal_throwIllegalStateExpception() { @Test public void whenAddingTwoCapDimension_nuOfDimsShouldBeTwo() { ShipmentJob one = new ShipmentJob.Builder("s").setPickupLocation(Location.Builder.newInstance().setId("foo").build()) - .setDeliveryLocation(TestUtils.loc("foofoo")) - .addSizeDimension(0, 2) - .addSizeDimension(1, 4) - .build(); + .setDeliveryLocation(TestUtils.loc("foofoo")) + .addSizeDimension(0, 2) + .addSizeDimension(1, 4) + .build(); assertEquals(2, one.getSize().getNuOfDimensions()); } @Test public void whenShipmentIsBuiltWithoutSpecifyingCapacity_itShouldHvCapWithOneDimAndDimValOfZero() { ShipmentJob one = new ShipmentJob.Builder("s") - .setPickupLocation(Location.Builder.newInstance().setId("foo").setCoordinate(Coordinate.newInstance(0, 0)).build()) - .setDeliveryLocation(TestUtils.loc("foofoo")).build(); + .setPickupLocation(Location.Builder.newInstance().setId("foo").setCoordinate(Coordinate.newInstance(0, 0)).build()) + .setDeliveryLocation(TestUtils.loc("foofoo")).build(); assertEquals(1, one.getSize().getNuOfDimensions()); assertEquals(0, one.getSize().get(0)); } @@ -359,8 +360,8 @@ public void whenShipmentIsBuiltWithoutSpecifyingCapacity_itShouldHvCapWithOneDim @Test public void whenShipmentIsBuiltWithConstructorWhereSizeIsSpecified_capacityShouldBeSetCorrectly() { ShipmentJob one = new ShipmentJob.Builder("s").addSizeDimension(0, 1) - .setPickupLocation(Location.Builder.newInstance().setId("foo").setCoordinate(Coordinate.newInstance(0, 0)).build()) - .setDeliveryLocation(TestUtils.loc("foofoo")).build(); + .setPickupLocation(Location.Builder.newInstance().setId("foo").setCoordinate(Coordinate.newInstance(0, 0)).build()) + .setDeliveryLocation(TestUtils.loc("foofoo")).build(); assertEquals(1, one.getSize().getNuOfDimensions()); assertEquals(1, one.getSize().get(0)); } @@ -368,8 +369,8 @@ public void whenShipmentIsBuiltWithConstructorWhereSizeIsSpecified_capacityShoul @Test public void whenAddingSkills_theyShouldBeAddedCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s").setPickupLocation(Location.Builder.newInstance().setId("loc").build()) - .setDeliveryLocation(TestUtils.loc("delLoc")) - .addRequiredSkill("drill").addRequiredSkill("screwdriver").build(); + .setDeliveryLocation(TestUtils.loc("delLoc")) + .addRequiredSkill("drill").addRequiredSkill("screwdriver").build(); assertTrue(s.getRequiredSkills().containsSkill("drill")); assertTrue(s.getRequiredSkills().containsSkill("drill")); assertTrue(s.getRequiredSkills().containsSkill("ScrewDriver")); @@ -378,9 +379,9 @@ public void whenAddingSkills_theyShouldBeAddedCorrectly() { @Test public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s") - .setPickupLocation(Location.Builder.newInstance().setId("pick").build()) - .setDeliveryLocation(TestUtils.loc("del")) - .addRequiredSkill("DriLl").addRequiredSkill("screwDriver").build(); + .setPickupLocation(Location.Builder.newInstance().setId("pick").build()) + .setDeliveryLocation(TestUtils.loc("del")) + .addRequiredSkill("DriLl").addRequiredSkill("screwDriver").build(); assertTrue(s.getRequiredSkills().containsSkill("drill")); assertTrue(s.getRequiredSkills().containsSkill("drilL")); } @@ -388,8 +389,8 @@ public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly() { @Test public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s").setPickupLocation(Location.Builder.newInstance().setId("loc").build()) - .setDeliveryLocation(TestUtils.loc("del")) - .addRequiredSkill("screwDriver").build(); + .setDeliveryLocation(TestUtils.loc("del")) + .addRequiredSkill("screwDriver").build(); assertFalse(s.getRequiredSkills().containsSkill("drill")); assertFalse(s.getRequiredSkills().containsSkill("drilL")); } @@ -397,15 +398,15 @@ public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly() { @Test public void nameShouldBeAssigned() { ShipmentJob s = new ShipmentJob.Builder("s").setPickupLocation(Location.Builder.newInstance().setId("loc").build()) - .setDeliveryLocation(TestUtils.loc("del")) - .setName("name").build(); + .setDeliveryLocation(TestUtils.loc("del")) + .setName("name").build(); assertEquals("name", s.getName()); } @Test public void whenSettingLocation_itShouldWork() { ShipmentJob s = new ShipmentJob.Builder("s").setPickupLocation(Location.Builder.newInstance().setId("loc").build()) - .setDeliveryLocation(Location.Builder.newInstance().setId("del").build()).build(); + .setDeliveryLocation(Location.Builder.newInstance().setId("del").build()).build(); assertEquals("loc", s.getPickupActivity().getLocation().getId()); assertEquals("loc", s.getPickupActivity().getLocation().getId()); assertEquals("del", s.getDeliveryActivity().getLocation().getId()); @@ -415,24 +416,24 @@ public void whenSettingLocation_itShouldWork() { @Test public void whenSettingPriorities_itShouldBeSetCorrectly() { ShipmentJob s = new ShipmentJob.Builder("s").setPickupLocation(Location.newInstance("loc")) - .setDeliveryLocation(Location.newInstance("loc")) - .setPriority(1).build(); + .setDeliveryLocation(Location.newInstance("loc")) + .setPriority(1).build(); assertEquals(1, s.getPriority()); } @Test public void whenSettingPriorities_itShouldBeSetCorrectly2() { ShipmentJob s = new ShipmentJob.Builder("s").setPickupLocation(Location.newInstance("loc")) - .setDeliveryLocation(Location.newInstance("loc")) - .setPriority(3).build(); + .setDeliveryLocation(Location.newInstance("loc")) + .setPriority(3).build(); assertEquals(3, s.getPriority()); } @Test public void whenNotSettingPriorities_defaultShouldBe2() { ShipmentJob s = new ShipmentJob.Builder("s").setPickupLocation(Location.newInstance("loc")) - .setDeliveryLocation(Location.newInstance("loc")) - .build(); + .setDeliveryLocation(Location.newInstance("loc")) + .build(); assertEquals(2, s.getPriority()); } diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java index 159267649..96fef67d6 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java @@ -37,7 +37,7 @@ public class VehicleRouteBuilderTest { @Test(expected = IllegalArgumentException.class) public void whenDeliveryIsAddedBeforePickup_throwsException() { ShipmentJob s = new ShipmentJob.Builder("s") - .setDeliveryLocation(Location.newInstance("loc1")).build(); + .setDeliveryLocation(Location.newInstance("loc1")).build(); VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(mock(Vehicle.class), mock(Driver.class)); builder.addDelivery(s); } @@ -92,7 +92,7 @@ public void whenBuildingClosedRoute_routeEndShouldHaveLocationOfVehicle() { ShipmentJob s2 = createStandardShipment("s2").build(); Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("vehLoc")).setEndLocation(Location.newInstance("vehLoc")) - .build(); + .build(); VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)); builder.addPickup(s); @@ -118,7 +118,7 @@ public void whenBuildingOpenRoute_routeEndShouldHaveLocationOfLastActivity() { builder.addDelivery(s2); VehicleRoute route = builder.build(); assertEquals(route.getEnd().getLocation().getId(), - s2.getDeliveryActivity().getLocation().getId()); + s2.getDeliveryActivity().getLocation().getId()); } private Location loc(String delLoc) { @@ -148,11 +148,11 @@ protected Builder createStandardShipment(String name) { Location loc = Location.Builder.newInstance().setId("delLoc").build(); TimeWindow tw = TimeWindow.newInstance(0, 10); return new ShipmentJob.Builder(name) - .addSizeDimension(0, 10) - .setPickupTimeWindow(tw) - .setDeliveryTimeWindow(tw) - .setPickupLocation(loc) - .setDeliveryLocation(loc); + .addSizeDimension(0, 10) + .setPickupTimeWindow(tw) + .setDeliveryTimeWindow(tw) + .setPickupLocation(loc) + .setDeliveryLocation(loc); } diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/activity/BreakActivityTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/activity/BreakActivityTest.java index d572c76d4..07429e1eb 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/activity/BreakActivityTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/activity/BreakActivityTest.java @@ -40,13 +40,13 @@ public class BreakActivityTest { @Before public void doBefore() { Builder breakBuilder = new Break.Builder("service") - .setTimeWindow(TimeWindow.newInstance(1., 2.)).setServiceTime(3); + .setTimeWindow(TimeWindow.newInstance(1., 2.)).setServiceTime(3); service = breakBuilder.build(); serviceActivity = BreakActivity.newInstance(service, breakBuilder); serviceActivity.setTheoreticalEarliestOperationStartTime( - service.getActivity().getTimeWindow().getStart()); + service.getActivity().getBreakTimeWindow().getStart()); serviceActivity.setTheoreticalLatestOperationStartTime( - service.getActivity().getTimeWindow().getEnd()); + service.getActivity().getBreakTimeWindow().getEnd()); } @Test @@ -99,11 +99,11 @@ public void whenTwoDeliveriesHaveTheSameUnderlyingJob_theyAreEqual() { ServiceJob s1 = new ServiceJob.Builder("s").setLocation(loc).build(); ServiceJob s2 = new ServiceJob.Builder("s").setLocation(loc).build(); ServiceActivity d1 = new ServiceActivity(s1, "s1", - loc, 0d, SizeDimension.EMPTY, - TimeWindows.ANY_TIME.getTimeWindows()); + loc, 0d, SizeDimension.EMPTY, + TimeWindows.ANY_TIME.getTimeWindows()); ServiceActivity d2 = new ServiceActivity(s2, "s2", - loc, 0d, SizeDimension.EMPTY, - TimeWindows.ANY_TIME.getTimeWindows()); + loc, 0d, SizeDimension.EMPTY, + TimeWindows.ANY_TIME.getTimeWindows()); assertTrue(d1.equals(d2)); } @@ -114,11 +114,11 @@ public void whenTwoDeliveriesHaveTheDifferentUnderlyingJob_theyAreNotEqual() { ServiceJob s1 = new ServiceJob.Builder("s").setLocation(loc).build(); ServiceJob s2 = new ServiceJob.Builder("s2").setLocation(loc).build(); ServiceActivity d1 = new ServiceActivity(s1, "s1", - loc, 0d, SizeDimension.EMPTY, - TimeWindows.ANY_TIME.getTimeWindows()); + loc, 0d, SizeDimension.EMPTY, + TimeWindows.ANY_TIME.getTimeWindows()); ServiceActivity d2 = new ServiceActivity(s2, "s2", - loc, 0d, SizeDimension.EMPTY, - TimeWindows.ANY_TIME.getTimeWindows()); + loc, 0d, SizeDimension.EMPTY, + TimeWindows.ANY_TIME.getTimeWindows()); assertFalse(d1.equals(d2)); } diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/activity/JobActivityTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/activity/JobActivityTest.java index 658179a06..348043b7a 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/activity/JobActivityTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/solution/route/activity/JobActivityTest.java @@ -33,9 +33,9 @@ public void createActivity(AbstractSingleActivityJob service) { this.service = service; activity = service.getActivity(); activity.setTheoreticalEarliestOperationStartTime( - activity.getSingleTimeWindow().getStart()); + activity.getTimeWindows().iterator().next().getStart()); activity.setTheoreticalLatestOperationStartTime( - activity.getSingleTimeWindow().getEnd()); + activity.getTimeWindows().iterator().next().getEnd()); } @Test diff --git a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImplTest.java b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImplTest.java index 0834cacfb..208aa8ffd 100644 --- a/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImplTest.java +++ b/jsprit-core/src/test/java/com/graphhopper/jsprit/core/problem/vehicle/VehicleImplTest.java @@ -45,10 +45,10 @@ public void whenAddingDriverBreak_itShouldBeAddedCorrectly() { VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build(); Break aBreak = new Break.Builder("break").setTimeWindow(TimeWindow.newInstance(100, 200)).setServiceTime(30).build(); Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")) - .setType(type1).setEndLocation(Location.newInstance("start")) - .setBreak(aBreak).build(); + .setType(type1).setEndLocation(Location.newInstance("start")) + .setBreak(aBreak).build(); assertNotNull(v.getBreak()); - TimeWindow timeWindow = v.getBreak().getActivity().getSingleTimeWindow(); + TimeWindow timeWindow = v.getBreak().getActivity().getBreakTimeWindow(); assertEquals(100., timeWindow.getStart(), 0.1); assertEquals(200., timeWindow.getEnd(), 0.1); assertEquals(30., v.getBreak().getActivity().getOperationTime(), 0.1); @@ -59,7 +59,7 @@ public void whenAddingDriverBreak_itShouldBeAddedCorrectly() { public void whenAddingSkills_theyShouldBeAddedCorrectly() { VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build(); Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")).setType(type1).setEndLocation(Location.newInstance("start")) - .addSkill("drill").addSkill("screwdriver").build(); + .addSkill("drill").addSkill("screwdriver").build(); assertTrue(v.getSkills().containsSkill("drill")); assertTrue(v.getSkills().containsSkill("drill")); assertTrue(v.getSkills().containsSkill("screwdriver")); @@ -69,7 +69,7 @@ public void whenAddingSkills_theyShouldBeAddedCorrectly() { public void whenAddingSkillsCaseSens_theyShouldBeAddedCorrectly() { VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build(); Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")).setType(type1).setEndLocation(Location.newInstance("start")) - .addSkill("drill").addSkill("screwdriver").build(); + .addSkill("drill").addSkill("screwdriver").build(); assertTrue(v.getSkills().containsSkill("drill")); assertTrue(v.getSkills().containsSkill("dRill")); assertTrue(v.getSkills().containsSkill("ScrewDriver")); @@ -238,7 +238,7 @@ public void whenTwoVehiclesHaveTheSameId_theyShouldBeEqual() { public void whenAddingSkillsCaseSensV2_theyShouldBeAddedCorrectly() { VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("type").build(); Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance("start")).setType(type1).setEndLocation(Location.newInstance("start")) - .addSkill("drill").build(); + .addSkill("drill").build(); assertFalse(v.getSkills().containsSkill("ScrewDriver")); } diff --git a/jsprit-instances/src/main/java/com/graphhopper/jsprit/instance/reader/LopezIbanezBlumReader.java b/jsprit-instances/src/main/java/com/graphhopper/jsprit/instance/reader/LopezIbanezBlumReader.java index 807dec90f..f2e231d2b 100644 --- a/jsprit-instances/src/main/java/com/graphhopper/jsprit/instance/reader/LopezIbanezBlumReader.java +++ b/jsprit-instances/src/main/java/com/graphhopper/jsprit/instance/reader/LopezIbanezBlumReader.java @@ -91,6 +91,10 @@ public void read(String instanceFile) { close(reader); } + private static TimeWindow getFirstTimeWindow(ServiceJob job) { + return job.getActivity().getTimeWindows().iterator().next(); + } + public static void main(String[] args) { VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); new LopezIbanezBlumReader(builder).read("input/Dumas/n20w20.001.txt"); @@ -99,12 +103,12 @@ public static void main(String[] args) { System.out.println("0->20: " + vrp.getTransportCosts().getTransportCost(Location.newInstance(0), Location.newInstance(20), 0, null, null)); System.out.println("4->18: " + vrp.getTransportCosts().getTransportCost(Location.newInstance(4), Location.newInstance(18), 0, null, null)); System.out.println("20->8: " + vrp.getTransportCosts().getTransportCost(Location.newInstance(20), Location.newInstance(8), 0, null, null)); - System.out.println("18: " + ((ServiceJob) vrp.getJobs().get("" + 18)).getActivity().getSingleTimeWindow().getStart() + " " - + ((ServiceJob) vrp.getJobs().get("" + 18)).getActivity().getSingleTimeWindow().getEnd()); - System.out.println("20: " + ((ServiceJob) vrp.getJobs().get("" + 20)).getActivity().getSingleTimeWindow().getStart() + " " - + ((ServiceJob) vrp.getJobs().get("" + 20)).getActivity().getSingleTimeWindow().getEnd()); - System.out.println("1: " + ((ServiceJob) vrp.getJobs().get("" + 1)).getActivity().getSingleTimeWindow().getStart() + " " - + ((ServiceJob) vrp.getJobs().get("" + 1)).getActivity().getSingleTimeWindow().getEnd()); + System.out.println("18: " + getFirstTimeWindow(((ServiceJob) vrp.getJobs().get("" + 18))).getStart() + " " + + getFirstTimeWindow(((ServiceJob) vrp.getJobs().get("" + 18))).getEnd()); + System.out.println("20: " + getFirstTimeWindow(((ServiceJob) vrp.getJobs().get("" + 20))).getStart() + " " + + getFirstTimeWindow(((ServiceJob) vrp.getJobs().get("" + 20))).getEnd()); + System.out.println("1: " + getFirstTimeWindow(((ServiceJob) vrp.getJobs().get("" + 1))).getStart() + " " + + getFirstTimeWindow(((ServiceJob) vrp.getJobs().get("" + 1))).getEnd()); } private void close(BufferedReader reader) { diff --git a/jsprit-instances/src/test/java/com/graphhopper/jsprit/instance/reader/SolomonReaderTest.java b/jsprit-instances/src/test/java/com/graphhopper/jsprit/instance/reader/SolomonReaderTest.java index 4fd684545..344afadef 100644 --- a/jsprit-instances/src/test/java/com/graphhopper/jsprit/instance/reader/SolomonReaderTest.java +++ b/jsprit-instances/src/test/java/com/graphhopper/jsprit/instance/reader/SolomonReaderTest.java @@ -41,9 +41,8 @@ public void whenReadingSolomonInstance_nuOfCustomersIsCorrect() { private String getPath() { URL resource = getClass().getClassLoader().getResource("C101_solomon.txt"); - if (resource == null) { + if (resource == null) throw new IllegalStateException("file C101_solomon.txt does not exist"); - } return resource.getPath(); } @@ -97,7 +96,9 @@ public void whenReadingSolomonInstance_earliestServiceStartTimeOfCustomerSixtyTw VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); new SolomonReader(builder).read(getPath()); VehicleRoutingProblem vrp = builder.build(); - assertEquals(262.0, ((ServiceJob) vrp.getJobs().get("62")).getActivity().getSingleTimeWindow().getStart(), 0.1); + assertEquals(262.0, + ((ServiceJob) vrp.getJobs().get("62")).getActivity().getTimeWindows().iterator().next().getStart(), + 0.1); } @Test @@ -105,7 +106,8 @@ public void whenReadingSolomonInstance_latestServiceStartTimeOfCustomerEightySev VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); new SolomonReader(builder).read(getPath()); VehicleRoutingProblem vrp = builder.build(); - assertEquals(144.0, ((ServiceJob) vrp.getJobs().get("87")).getActivity().getSingleTimeWindow().getEnd(), 0.1); + assertEquals(144.0, + ((ServiceJob) vrp.getJobs().get("87")).getActivity().getTimeWindows().iterator().next().getEnd(), 0.1); } diff --git a/jsprit-io/src/test/java/com/graphhopper/jsprit/io/problem/VrpXMLReaderTest.java b/jsprit-io/src/test/java/com/graphhopper/jsprit/io/problem/VrpXMLReaderTest.java index 28189552e..3197dc485 100644 --- a/jsprit-io/src/test/java/com/graphhopper/jsprit/io/problem/VrpXMLReaderTest.java +++ b/jsprit-io/src/test/java/com/graphhopper/jsprit/io/problem/VrpXMLReaderTest.java @@ -146,15 +146,14 @@ public void whenReadingVehicles_nuSkillsOfV2ShouldBeCorrect() { private Vehicle getVehicle(String string, Collection vehicles) { for (Vehicle v : vehicles) { - if (string.equals(v.getId())) { + if (string.equals(v.getId())) return v; - } } return null; } private boolean idsInCollection(List asList, Collection vehicles) { - List ids = new ArrayList(asList); + List ids = new ArrayList<>(asList); for (Vehicle v : vehicles) { if (ids.contains(v.getId())) { ids.remove(v.getId()); @@ -311,7 +310,7 @@ public void whenReadingServices_twOfService1IsReadCorrectly() { new VrpXMLReader(builder, null).read(inputStream); VehicleRoutingProblem vrp = builder.build(); ServiceJob s1 = (ServiceJob) vrp.getJobs().get("1"); - TimeWindow tw = s1.getActivity().getSingleTimeWindow(); + TimeWindow tw = s1.getActivity().getTimeWindows().iterator().next(); assertEquals(0.0, tw.getStart(), 0.01); assertEquals(4000.0, tw.getEnd(), 0.01); } @@ -474,7 +473,7 @@ public void whenReadingJobs_pickupTimeWindowOfShipment3IsReadCorrectly() { new VrpXMLReader(builder, null).read(inputStream); VehicleRoutingProblem vrp = builder.build(); ShipmentJob s = (ShipmentJob) vrp.getJobs().get("3"); - TimeWindow tw = s.getPickupActivity().getSingleTimeWindow(); + TimeWindow tw = s.getPickupActivity().getTimeWindows().iterator().next(); assertEquals(1000.0, tw.getStart(), 0.01); assertEquals(4000.0, tw.getEnd(), 0.01); } @@ -485,7 +484,7 @@ public void whenReadingJobs_deliveryTimeWindowOfShipment3IsReadCorrectly() { new VrpXMLReader(builder, null).read(inputStream); VehicleRoutingProblem vrp = builder.build(); ShipmentJob s = (ShipmentJob) vrp.getJobs().get("3"); - TimeWindow tw = s.getDeliveryActivity().getSingleTimeWindow(); + TimeWindow tw = s.getDeliveryActivity().getTimeWindows().iterator().next(); assertEquals(6000.0, tw.getStart(), 0.01); assertEquals(10000.0, tw.getEnd(), 0.01); } @@ -624,7 +623,7 @@ public void whenReadingInitialRoute_nuActivitiesShouldBeCorrect() { @Test public void testRead_ifReaderIsCalled_itReadsSuccessfullyV2() { VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); - ArrayList solutions = new ArrayList(); + ArrayList solutions = new ArrayList<>(); new VrpXMLReader(vrpBuilder, solutions).read(getClass().getResourceAsStream("finiteVrpWithShipmentsAndSolution.xml")); VehicleRoutingProblem vrp = vrpBuilder.build(); assertEquals(4, vrp.getJobs().size()); @@ -642,7 +641,7 @@ public void testRead_ifReaderIsCalled_itReadsSuccessfullyV2() { @Test public void testRead_ifReaderIsCalled_itReadsSuccessfully() { new VrpXMLReader(VehicleRoutingProblem.Builder.newInstance(), new ArrayList()) - .read(getClass().getResourceAsStream("lui-shen-solution.xml")); + .read(getClass().getResourceAsStream("lui-shen-solution.xml")); assertTrue(true); } @@ -650,7 +649,7 @@ public void testRead_ifReaderIsCalled_itReadsSuccessfully() { @Test public void unassignedJobShouldBeRead() { VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); - ArrayList solutions = new ArrayList(); + ArrayList solutions = new ArrayList<>(); new VrpXMLReader(vrpBuilder, solutions).read(getClass().getResourceAsStream("finiteVrpWithShipmentsAndSolution.xml")); VehicleRoutingProblemSolution solution = Solutions.bestOf(solutions); diff --git a/jsprit-io/src/test/java/com/graphhopper/jsprit/io/problem/VrpXMLWriterTest.java b/jsprit-io/src/test/java/com/graphhopper/jsprit/io/problem/VrpXMLWriterTest.java index 9d2d59cc5..1af90352e 100644 --- a/jsprit-io/src/test/java/com/graphhopper/jsprit/io/problem/VrpXMLWriterTest.java +++ b/jsprit-io/src/test/java/com/graphhopper/jsprit/io/problem/VrpXMLWriterTest.java @@ -251,7 +251,8 @@ public void whenWritingShipments_readingThemAgainMustReturnTheWrittenPickupTimeW VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); assertEquals(2, readVrp.getJobs().size()); - TimeWindow tw = ((ShipmentJob) readVrp.getJobs().get("1")).getPickupActivity().getSingleTimeWindow(); + TimeWindow tw = ((ShipmentJob) readVrp.getJobs().get("1")).getPickupActivity().getTimeWindows().iterator() + .next(); assertEquals(1.0, tw.getStart(), 0.01); assertEquals(2.0, tw.getEnd(), 0.01); } @@ -286,7 +287,8 @@ public void whenWritingShipments_readingThemAgainMustReturnTheWrittenDeliveryTim VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); assertEquals(2, readVrp.getJobs().size()); - TimeWindow tw = ((ShipmentJob) readVrp.getJobs().get("1")).getDeliveryActivity().getSingleTimeWindow(); + TimeWindow tw = ((ShipmentJob) readVrp.getJobs().get("1")).getDeliveryActivity().getTimeWindows().iterator() + .next(); assertEquals(3.0, tw.getStart(), 0.01); assertEquals(4.0, tw.getEnd(), 0.01); } @@ -455,9 +457,8 @@ public void whenWritingVehicles_vehShouldHave0Skills() { private Vehicle getVehicle(String v1, VehicleRoutingProblem readVrp) { for (Vehicle v : readVrp.getVehicles()) { - if (v.getId().equals(v1)) { + if (v.getId().equals(v1)) return v; - } } return null; } @@ -899,9 +900,8 @@ public void whenWritingVehicleWithSeveralCapacityDimensions_itShouldBeWrittenAnd private Vehicle getVehicle(String string, Collection vehicles) { for (Vehicle v : vehicles) { - if (string.equals(v.getId())) { + if (string.equals(v.getId())) return v; - } } return null; } @@ -920,16 +920,16 @@ public void solutionWithoutUnassignedJobsShouldBeWrittenCorrectly() { VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); VehicleRoute route = VehicleRoute.Builder.newInstance(v1).addService(s1).addService(s2).build(); - List routes = new ArrayList(); + List routes = new ArrayList<>(); routes.add(route); VehicleRoutingProblemSolution solution = new VehicleRoutingProblemSolution(routes, 10.); - List solutions = new ArrayList(); + List solutions = new ArrayList<>(); solutions.add(solution); new VrpXMLWriter(vrp, solutions).write(infileName); VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); - List solutionsToRead = new ArrayList(); + List solutionsToRead = new ArrayList<>(); new VrpXMLReader(vrpToReadBuilder, solutionsToRead).read(infileName); assertEquals(1, solutionsToRead.size()); @@ -951,17 +951,17 @@ public void solutionWithUnassignedJobsShouldBeWrittenCorrectly() { VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); VehicleRoute route = VehicleRoute.Builder.newInstance(v1).addService(s1).build(); - List routes = new ArrayList(); + List routes = new ArrayList<>(); routes.add(route); VehicleRoutingProblemSolution solution = new VehicleRoutingProblemSolution(routes, 10.); solution.getUnassignedJobs().add(s2); - List solutions = new ArrayList(); + List solutions = new ArrayList<>(); solutions.add(solution); new VrpXMLWriter(vrp, solutions).write(infileName); VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); - List solutionsToRead = new ArrayList(); + List solutionsToRead = new ArrayList<>(); new VrpXMLReader(vrpToReadBuilder, solutionsToRead).read(infileName); assertEquals(1, solutionsToRead.size());