diff --git a/README.md b/README.md index 22d84746..52b4ed68 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ reading classical VRP instances to benchmark your algorithm. It is fit for chang ##In Development - continues improvement of code, handling and performance -- soft constraints +- simplifying management of soft and hard constraints - various capacity dimensions and multiple time-windows - large scale instances @@ -59,5 +59,3 @@ It is mainly inspired by my research group at [KIT-ECON](http://netze.econ.kit.e If you have questions or if you use jsprit, it would be great you give feedback and let me know your experience: Email: jsprit.vehicle.routing@gmail.com - -[![](https://cruel-carlota.pagodabox.com/ba53806a8cc8ff439c1a51d152245dee "githalytics.com")](http://githalytics.com/jsprit/jsprit) diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStreamViewer.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStreamViewer.java index 16928de8..67a5f21f 100644 --- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStreamViewer.java +++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/GraphStreamViewer.java @@ -214,7 +214,6 @@ public class GraphStreamViewer { //start rendering graph render(g,view); - } private void render(Graph g, View view) { @@ -385,17 +384,27 @@ public class GraphStreamViewer { } private void renderVehicle(Graph g, Vehicle vehicle, Label label) { - Node n = g.addNode(makeId(vehicle.getId(),vehicle.getLocationId())); - if(label.equals(Label.ID)) n.addAttribute("ui.label", "depot"); + Node vehicleStart = g.addNode(makeId(vehicle.getId(),vehicle.getStartLocationId())); + if(label.equals(Label.ID)) vehicleStart.addAttribute("ui.label", "depot"); // if(label.equals(Label.ACTIVITY)) n.addAttribute("ui.label", "start"); - n.addAttribute("x", vehicle.getCoord().getX()); - n.addAttribute("y", vehicle.getCoord().getY()); - n.setAttribute("ui.class", "depot"); + vehicleStart.addAttribute("x", vehicle.getStartLocationCoordinate().getX()); + vehicleStart.addAttribute("y", vehicle.getStartLocationCoordinate().getY()); + vehicleStart.setAttribute("ui.class", "depot"); + + if(!vehicle.getStartLocationId().equals(vehicle.getEndLocationId())){ + Node vehicleEnd = g.addNode(makeId(vehicle.getId(),vehicle.getEndLocationId())); + if(label.equals(Label.ID)) vehicleEnd.addAttribute("ui.label", "depot"); +// if(label.equals(Label.ACTIVITY)) n.addAttribute("ui.label", "start"); + vehicleEnd.addAttribute("x", vehicle.getEndLocationCoordinate().getX()); + vehicleEnd.addAttribute("y", vehicle.getEndLocationCoordinate().getY()); + vehicleEnd.setAttribute("ui.class", "depot"); + + } } private void renderRoute(Graph g, VehicleRoute route, int routeId, long renderDelay_in_ms, Label label) { int vehicle_edgeId = 1; - String prevIdentifier = makeId(route.getVehicle().getId(),route.getVehicle().getLocationId()); + String prevIdentifier = makeId(route.getVehicle().getId(),route.getVehicle().getStartLocationId()); if(label.equals(Label.ACTIVITY)){ Node n = g.getNode(prevIdentifier); n.addAttribute("ui.label", "start"); @@ -414,7 +423,7 @@ public class GraphStreamViewer { sleep(renderDelay_in_ms); } if(route.getVehicle().isReturnToDepot()){ - String lastIdentifier = makeId(route.getVehicle().getId(),route.getVehicle().getLocationId()); + String lastIdentifier = makeId(route.getVehicle().getId(),route.getVehicle().getEndLocationId()); g.addEdge(makeEdgeId(routeId,vehicle_edgeId), prevIdentifier, lastIdentifier, true); } } diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java index 38e8fbcf..44535d05 100644 --- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java +++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java @@ -404,9 +404,15 @@ public class Plotter { XYSeriesCollection coll = new XYSeriesCollection(); XYSeries vehicleSeries = new XYSeries("depot", false, true); for(Vehicle v : vehicles){ - Coordinate coord = v.getCoord(); - if(coord == null) throw new NoLocationFoundException(); - vehicleSeries.add(coord.getX(),coord.getY()); + Coordinate startCoord = v.getStartLocationCoordinate(); + if(startCoord == null) throw new NoLocationFoundException(); + vehicleSeries.add(startCoord.getX(),startCoord.getY()); + + if(!v.getStartLocationId().equals(v.getEndLocationId())){ + Coordinate endCoord = v.getEndLocationCoordinate(); + if(endCoord == null) throw new NoLocationFoundException(); + vehicleSeries.add(endCoord.getX(),endCoord.getY()); + } } coll.addSeries(vehicleSeries); @@ -473,11 +479,18 @@ public class Plotter { private Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException { final Map locs = new HashMap(); for(Vehicle v : vrp.getVehicles()){ - String locationId = v.getLocationId(); - if(locationId == null) throw new NoLocationFoundException(); - Coordinate coord = v.getCoord(); - if(coord == null) throw new NoLocationFoundException(); - locs.put(locationId, coord); + String startLocationId = v.getStartLocationId(); + if(startLocationId == null) throw new NoLocationFoundException(); + Coordinate startCoord = v.getStartLocationCoordinate(); + if(startCoord == null) throw new NoLocationFoundException(); + locs.put(startLocationId, startCoord); + + String endLocationId = v.getEndLocationId(); + if(!startLocationId.equals(endLocationId)){ + Coordinate endCoord = v.getEndLocationCoordinate(); + if(endCoord == null) throw new NoLocationFoundException(); + locs.put(endLocationId, endCoord); + } } for(Job j : vrp.getJobs().values()){ if(j instanceof Service){ diff --git a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/SolutionPlotter.java b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/SolutionPlotter.java index 141c8c22..c86a6266 100644 --- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/SolutionPlotter.java +++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/SolutionPlotter.java @@ -75,8 +75,10 @@ public class SolutionPlotter { * @param vrp * @param pngFile target path with filename. - * @see VehicleRoutingProblem, VehicleRoutingProblemSolution + * @see VehicleRoutingProblem, VehicleRoutingProblemSolution + * @deprecated use Plotter.java instead (this plotter is not maintained anymore and might plot incorrectly) */ + @Deprecated public static void plotVrpAsPNG(VehicleRoutingProblem vrp, String pngFile, String title){ String filename = pngFile; if(!pngFile.endsWith(".png")) filename += ".png"; @@ -102,7 +104,9 @@ public class SolutionPlotter { * @param pngFile target path with filename. * @param plotTitle * @see VehicleRoute + * @deprecated use Plotter.java instead (this plotter is not maintained anymore and might plot incorrectly) */ + @Deprecated public static void plotRoutesAsPNG(Collection routes, Locations locations, String pngFile, String title) { String filename = pngFile; if(!pngFile.endsWith(".png")) filename += ".png"; @@ -130,8 +134,10 @@ public class SolutionPlotter { * @param vrp * @param solution * @param pngFile target path with filename. - * @see VehicleRoutingProblem, VehicleRoutingProblemSolution + * @see VehicleRoutingProblem, VehicleRoutingProblemSolution + * @deprecated use Plotter.java instead (this plotter is not maintained anymore and might plot incorrectly) */ + @Deprecated public static void plotSolutionAsPNG(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution, String pngFile, String title){ String filename = pngFile; if(!pngFile.endsWith(".png")) filename += ".png"; @@ -294,7 +300,7 @@ public class SolutionPlotter { XYSeriesCollection coll = new XYSeriesCollection(); XYSeries vehicleSeries = new XYSeries("depot", false, true); for(Vehicle v : vehicles){ - Coordinate coord = v.getCoord(); + Coordinate coord = v.getStartLocationCoordinate(); if(coord == null) throw new NoLocationFoundException(); vehicleSeries.add(coord.getX(),coord.getY()); } @@ -353,11 +359,11 @@ public class SolutionPlotter { private static Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException { final Map locs = new HashMap(); for(Vehicle v : vrp.getVehicles()){ - String locationId = v.getLocationId(); - if(locationId == null) throw new NoLocationFoundException(); - Coordinate coord = v.getCoord(); + String startLocationId = v.getStartLocationId(); + if(startLocationId == null) throw new NoLocationFoundException(); + Coordinate coord = v.getStartLocationCoordinate(); if(coord == null) throw new NoLocationFoundException(); - locs.put(locationId, coord); + locs.put(startLocationId, coord); } for(Job j : vrp.getJobs().values()){ if(j instanceof Service){ diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/io/InsertionFactory.java b/jsprit-core/src/main/java/jsprit/core/algorithm/io/InsertionFactory.java index 00a18fe3..9a4f49a5 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/io/InsertionFactory.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/io/InsertionFactory.java @@ -86,9 +86,15 @@ class InsertionFactory { String weight = config.getString("considerFixedCosts[@weight]"); if(weight == null) weight = config.getString("considerFixedCost[@weight]"); if(weight != null) fixedCostWeight = Double.parseDouble(weight); - else log.warn("parameter considerFixedCosts[@weight] is missing. by default, it is 0.5."); + else throw new IllegalStateException("fixedCostsParameter 'weight' must be set, e.g. true.\n" + + "this has to be changed in algorithm-config-xml-file."); iBuilder.considerFixedCosts(fixedCostWeight); } + else if(val.equals("false")){ + + } + else throw new IllegalStateException("considerFixedCosts must either be true or false, i.e. true or \nfalse. " + + "if latter, you can also omit the tag. this has to be changed in algorithm-config-xml-file"); } String timeSliceString = config.getString("experimental[@timeSlice]"); String neighbors = config.getString("experimental[@neighboringSlices]"); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java index 0a636235..428f0276 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java @@ -481,9 +481,6 @@ public class VehicleRoutingAlgorithms { @Override public void finish() { - if(firstAct){ - assert vehicle.getLocationId() == end.getLocationId() : "route end and last activity are not equal even route is open. this should not be."; - } firstAct = true; } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AdditionalAccessEgressCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AdditionalAccessEgressCalculator.java new file mode 100644 index 00000000..f4a5135f --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AdditionalAccessEgressCalculator.java @@ -0,0 +1,60 @@ +package jsprit.core.algorithm.recreate; + +import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.driver.Driver; +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.vehicle.Vehicle; + +/** + * Estimates additional access/egress costs when operating route with a new vehicle that has different start/end-location. + * + *

If two vehicles have the same start/end-location and departure-time .getCosts(...) must return zero. + * + * @author schroeder + * + */ +class AdditionalAccessEgressCalculator { + + private VehicleRoutingTransportCosts routingCosts; + + /** + * Constructs the estimator that estimates additional access/egress costs when operating route with a new vehicle that has different start/end-location. + * + *

If two vehicles have the same start/end-location and departure-time .getCosts(...) must return zero. + * + * @author schroeder + * + */ + public AdditionalAccessEgressCalculator(VehicleRoutingTransportCosts routingCosts) { + this.routingCosts = routingCosts; + } + + public double getCosts(JobInsertionContext insertionContext){ + double delta_access = 0.0; + double delta_egress = 0.0; + VehicleRoute currentRoute = insertionContext.getRoute(); + Vehicle newVehicle = insertionContext.getNewVehicle(); + Driver newDriver = insertionContext.getNewDriver(); + double newVehicleDepartureTime = insertionContext.getNewDepTime(); + if(!currentRoute.isEmpty()){ + double accessTransportCostNew = routingCosts.getTransportCost(newVehicle.getStartLocationId(), currentRoute.getActivities().get(0).getLocationId(), newVehicleDepartureTime, newDriver, newVehicle); + double accessTransportCostOld = routingCosts.getTransportCost(currentRoute.getStart().getLocationId(), currentRoute.getActivities().get(0).getLocationId(), currentRoute.getDepartureTime(), currentRoute.getDriver(), currentRoute.getVehicle()); + + delta_access = accessTransportCostNew - accessTransportCostOld; + + if(newVehicle.isReturnToDepot()){ + TourActivity lastActivityBeforeEndOfRoute = currentRoute.getActivities().get(currentRoute.getActivities().size()-1); + double lastActivityEndTimeWithOldVehicleAndDepartureTime = lastActivityBeforeEndOfRoute.getEndTime(); + double lastActivityEndTimeEstimationWithNewVehicleAndNewDepartureTime = Math.max(0.0, lastActivityEndTimeWithOldVehicleAndDepartureTime + (newVehicleDepartureTime - currentRoute.getDepartureTime())); + double egressTransportCostNew = routingCosts.getTransportCost(lastActivityBeforeEndOfRoute.getLocationId(), newVehicle.getEndLocationId() , lastActivityEndTimeEstimationWithNewVehicleAndNewDepartureTime, newDriver, newVehicle); + double egressTransportCostOld = routingCosts.getTransportCost(lastActivityBeforeEndOfRoute.getLocationId(), currentRoute.getEnd().getLocationId(), lastActivityEndTimeWithOldVehicleAndDepartureTime, currentRoute.getDriver(), currentRoute.getVehicle()); + + delta_egress = egressTransportCostNew - egressTransportCostOld; + } + } + return delta_access + delta_egress; + } + +} \ No newline at end of file diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/CalculatorBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/CalculatorBuilder.java index 32ec036a..bbac87d2 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/CalculatorBuilder.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/CalculatorBuilder.java @@ -252,8 +252,8 @@ class CalculatorBuilder { actInsertionCalc = activityInsertionCostCalculator; } - ShipmentInsertionCalculator shipmentInsertion = new ShipmentInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager, constraintManager); - ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager, constraintManager); + ShipmentInsertionCalculator shipmentInsertion = new ShipmentInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager); + ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager); JobCalculatorSwitcher switcher = new JobCalculatorSwitcher(); switcher.put(Shipment.class, shipmentInsertion); @@ -263,8 +263,6 @@ class CalculatorBuilder { PenalyzeInsertionCostsWithPenaltyVehicle penalyzeInsertionCosts = new PenalyzeInsertionCostsWithPenaltyVehicle(switcher); -// JobInsertionCostsCalculator standardServiceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager, constraintManager); -// ((ServiceInsertionCalculator) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood()); CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(penalyzeInsertionCosts); return calcPlusListeners; diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java index c7f2a593..2a2c5fd0 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/Inserter.java @@ -60,13 +60,13 @@ class Inserter { @Override public void handleJobInsertion(Job job, InsertionData iData, VehicleRoute route) { if(job instanceof Service){ + route.setVehicleAndDepartureTime(iData.getSelectedVehicle(),iData.getVehicleDepartureTime()); if(!iData.getSelectedVehicle().isReturnToDepot()){ if(iData.getDeliveryInsertionIndex()>=route.getTourActivities().getActivities().size()){ setEndLocation(route,(Service)job); } } route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), this.activityFactory.createActivity((Service)job)); - route.setDepartureTime(iData.getVehicleDepartureTime()); } else delegator.handleJobInsertion(job, iData, route); } @@ -92,6 +92,7 @@ class Inserter { if(job instanceof Shipment){ TourActivity pickupShipment = this.activityFactory.createPickup((Shipment)job); TourActivity deliverShipment = this.activityFactory.createDelivery((Shipment)job); + route.setVehicleAndDepartureTime(iData.getSelectedVehicle(),iData.getVehicleDepartureTime()); if(!iData.getSelectedVehicle().isReturnToDepot()){ if(iData.getDeliveryInsertionIndex()>=route.getActivities().size()){ setEndLocation(route,(Shipment)job); @@ -99,7 +100,6 @@ class Inserter { } route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), deliverShipment); route.getTourActivities().addActivity(iData.getPickupInsertionIndex(), pickupShipment); - route.setDepartureTime(iData.getVehicleDepartureTime()); } else delegator.handleJobInsertion(job, iData, route); } @@ -132,8 +132,7 @@ class Inserter { if(job == null) throw new IllegalStateException("cannot insert null-job"); if(!(vehicleRoute.getVehicle().getId().toString().equals(insertionData.getSelectedVehicle().getId().toString()))){ insertionListeners.informVehicleSwitched(vehicleRoute, vehicleRoute.getVehicle(), insertionData.getSelectedVehicle()); -// log.debug("vehicle switched from " + vehicleRoute.getVehicle().getId() + " to " + insertionData.getSelectedVehicle().getId()); - vehicleRoute.setVehicle(insertionData.getSelectedVehicle(), insertionData.getVehicleDepartureTime()); + vehicleRoute.setVehicleAndDepartureTime(insertionData.getSelectedVehicle(), insertionData.getVehicleDepartureTime()); } jobInsertionHandler.handleJobInsertion(job, insertionData, vehicleRoute); insertionListeners.informJobInserted(job, vehicleRoute, insertionData.getInsertionCost(), insertionData.getAdditionalTime()); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java index 1a1ead9c..5c70869e 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionCalculator.java @@ -17,9 +17,12 @@ package jsprit.core.algorithm.recreate; import jsprit.core.algorithm.recreate.ActivityInsertionCostsCalculator.ActivityInsertionCosts; +import jsprit.core.problem.constraint.ConstraintManager; import jsprit.core.problem.constraint.HardActivityStateLevelConstraint; import jsprit.core.problem.constraint.HardActivityStateLevelConstraint.ConstraintsStatus; import jsprit.core.problem.constraint.HardRouteStateLevelConstraint; +import jsprit.core.problem.constraint.SoftActivityConstraint; +import jsprit.core.problem.constraint.SoftRouteConstraint; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.driver.Driver; import jsprit.core.problem.job.Job; @@ -34,48 +37,45 @@ import jsprit.core.problem.solution.route.activity.TourActivityFactory; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl.NoVehicle; import jsprit.core.util.CalculationUtils; -import jsprit.core.util.Neighborhood; import org.apache.log4j.Logger; - - - +/** + * Calculator that calculates the best insertion position for a {@link Service}. + * + * @author schroeder + * + */ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{ - + private static final Logger logger = Logger.getLogger(ServiceInsertionCalculator.class); private HardRouteStateLevelConstraint hardRouteLevelConstraint; private HardActivityStateLevelConstraint hardActivityLevelConstraint; - private Neighborhood neighborhood = new Neighborhood() { - - @Override - public boolean areNeighbors(String location1, String location2) { - return true; - } - }; + private SoftRouteConstraint softRouteConstraint; - private ActivityInsertionCostsCalculator activityInsertionCostsCalculator; + private SoftActivityConstraint softActivityConstraint; private VehicleRoutingTransportCosts transportCosts; + private ActivityInsertionCostsCalculator additionalTransportCostsCalculator; + private TourActivityFactory activityFactory; - public void setNeighborhood(Neighborhood neighborhood) { - this.neighborhood = neighborhood; - logger.info("initialise neighborhood " + neighborhood); - } - + private AdditionalAccessEgressCalculator additionalAccessEgressCalculator; - public ServiceInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteStateLevelConstraint hardRouteLevelConstraint, HardActivityStateLevelConstraint hardActivityLevelConstraint) { + public ServiceInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator additionalTransportCostsCalculator, ConstraintManager constraintManager) { super(); - this.activityInsertionCostsCalculator = activityInsertionCostsCalculator; - this.hardRouteLevelConstraint = hardRouteLevelConstraint; - this.hardActivityLevelConstraint = hardActivityLevelConstraint; this.transportCosts = routingCosts; + hardRouteLevelConstraint = constraintManager; + hardActivityLevelConstraint = constraintManager; + softActivityConstraint = constraintManager; + softRouteConstraint = constraintManager; + this.additionalTransportCostsCalculator = additionalTransportCostsCalculator; activityFactory = new DefaultTourActivityFactory(); + additionalAccessEgressCalculator = new AdditionalAccessEgressCalculator(routingCosts); logger.info("initialise " + this); } @@ -100,36 +100,39 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{ } double bestCost = bestKnownCosts; - ActivityInsertionCosts bestMarginals = null; + + //from job2insert induced costs at route level + double additionalICostsAtRouteLevel = softRouteConstraint.getCosts(insertionContext); + additionalICostsAtRouteLevel += additionalAccessEgressCalculator.getCosts(insertionContext); + Service service = (Service)jobToInsert; int insertionIndex = InsertionData.NO_INDEX; TourActivity deliveryAct2Insert = activityFactory.createActivity(service); - Start start = Start.newInstance(newVehicle.getLocationId(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival()); + Start start = Start.newInstance(newVehicle.getStartLocationId(), newVehicle.getEarliestDeparture(), Double.MAX_VALUE); start.setEndTime(newVehicleDepartureTime); - End end = End.newInstance(newVehicle.getLocationId(), 0.0, newVehicle.getLatestArrival()); + End end = End.newInstance(newVehicle.getEndLocationId(), 0.0, newVehicle.getLatestArrival()); TourActivity prevAct = start; double prevActStartTime = newVehicleDepartureTime; int actIndex = 0; boolean loopBroken = false; for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){ - if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){ - ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); - if(status.equals(ConstraintsStatus.FULFILLED)){ - ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); - if(mc.getAdditionalCosts() < bestCost){ - bestCost = mc.getAdditionalCosts(); - bestMarginals = mc; - insertionIndex = actIndex; - } - } - else if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){ - loopBroken = true; - break; + ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); + if(status.equals(ConstraintsStatus.FULFILLED)){ + //from job2insert induced costs at activity level + double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); + ActivityInsertionCosts additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); + if(additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts.getAdditionalCosts() < bestCost){ + bestCost = additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts.getAdditionalCosts(); + insertionIndex = actIndex; } } + else if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){ + loopBroken = true; + break; + } double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocationId(), nextAct.getLocationId(), prevActStartTime, newDriver, newVehicle); double nextActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct); prevActStartTime = nextActEndTime; @@ -138,29 +141,22 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{ } End nextAct = end; if(!loopBroken){ - if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){ - ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); - if(status.equals(ConstraintsStatus.FULFILLED)){ - ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); - if(mc.getAdditionalCosts() < bestCost){ - bestCost = mc.getAdditionalCosts(); - bestMarginals = mc; - insertionIndex = actIndex; - } + ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); + if(status.equals(ConstraintsStatus.FULFILLED)){ + double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime); + ActivityInsertionCosts additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); + if(additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts.getAdditionalCosts() < bestCost){ + bestCost = additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts.getAdditionalCosts(); + insertionIndex = actIndex; } } } - if(insertionIndex == InsertionData.NO_INDEX) { return InsertionData.createEmptyInsertionData(); } InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver); insertionData.setVehicleDepartureTime(newVehicleDepartureTime); - insertionData.setAdditionalTime(bestMarginals.getAdditionalTime()); return insertionData; } - public ActivityInsertionCosts calculate(JobInsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double departureTimeAtPrevAct) { - return activityInsertionCostsCalculator.getCosts(iFacts, prevAct, nextAct, newAct, departureTimeAtPrevAct); - } } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionOnRouteLevelCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionOnRouteLevelCalculator.java index f5dc6b79..272400cb 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionOnRouteLevelCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ServiceInsertionOnRouteLevelCalculator.java @@ -314,22 +314,22 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC */ private void initialiseStartAndEnd(final Vehicle newVehicle, double newVehicleDepartureTime) { if(start == null){ - start = Start.newInstance(newVehicle.getLocationId(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival()); + start = Start.newInstance(newVehicle.getStartLocationId(), newVehicle.getEarliestDeparture(), Double.MAX_VALUE); start.setEndTime(newVehicleDepartureTime); } else{ - start.setLocationId(newVehicle.getLocationId()); + start.setLocationId(newVehicle.getStartLocationId()); start.setTheoreticalEarliestOperationStartTime(newVehicle.getEarliestDeparture()); - start.setTheoreticalLatestOperationStartTime(newVehicle.getLatestArrival()); + start.setTheoreticalLatestOperationStartTime(Double.MAX_VALUE); start.setEndTime(newVehicleDepartureTime); } if(end == null){ - end = End.newInstance(newVehicle.getLocationId(), 0.0, newVehicle.getLatestArrival()); + end = End.newInstance(newVehicle.getEndLocationId(), 0.0, newVehicle.getLatestArrival()); } else{ - end.setLocationId(newVehicle.getLocationId()); - end.setTheoreticalEarliestOperationStartTime(newVehicleDepartureTime); + end.setLocationId(newVehicle.getEndLocationId()); + end.setTheoreticalEarliestOperationStartTime(0.0); end.setTheoreticalLatestOperationStartTime(newVehicle.getLatestArrival()); } } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java index 8a98d517..fe29fb62 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculator.java @@ -19,7 +19,10 @@ package jsprit.core.algorithm.recreate; import java.util.List; import jsprit.core.algorithm.recreate.ActivityInsertionCostsCalculator.ActivityInsertionCosts; +import jsprit.core.problem.constraint.ConstraintManager; import jsprit.core.problem.constraint.HardActivityStateLevelConstraint; +import jsprit.core.problem.constraint.SoftActivityConstraint; +import jsprit.core.problem.constraint.SoftRouteConstraint; import jsprit.core.problem.constraint.HardActivityStateLevelConstraint.ConstraintsStatus; import jsprit.core.problem.constraint.HardRouteStateLevelConstraint; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; @@ -36,7 +39,6 @@ import jsprit.core.problem.solution.route.activity.TourShipmentActivityFactory; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl.NoVehicle; import jsprit.core.util.CalculationUtils; -import jsprit.core.util.Neighborhood; import org.apache.log4j.Logger; @@ -51,23 +53,28 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{ private HardActivityStateLevelConstraint hardActivityLevelConstraint; + private SoftRouteConstraint softRouteConstraint; + + private SoftActivityConstraint softActivityConstraint; + private ActivityInsertionCostsCalculator activityInsertionCostsCalculator; private VehicleRoutingTransportCosts transportCosts; private TourShipmentActivityFactory activityFactory; - public void setNeighborhood(Neighborhood neighborhood) { - logger.info("initialise neighborhood " + neighborhood); - } + private AdditionalAccessEgressCalculator additionalAccessEgressCalculator; - public ShipmentInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteStateLevelConstraint hardRouteLevelConstraint, HardActivityStateLevelConstraint hardActivityLevelConstraint) { + public ShipmentInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, ConstraintManager constraintManager) { super(); this.activityInsertionCostsCalculator = activityInsertionCostsCalculator; - this.hardRouteLevelConstraint = hardRouteLevelConstraint; - this.hardActivityLevelConstraint = hardActivityLevelConstraint; + this.hardRouteLevelConstraint = constraintManager; + this.hardActivityLevelConstraint = constraintManager; + this.softActivityConstraint = constraintManager; + this.softRouteConstraint = constraintManager; this.transportCosts = routingCosts; activityFactory = new DefaultShipmentActivityFactory(); + additionalAccessEgressCalculator = new AdditionalAccessEgressCalculator(routingCosts); logger.info("initialise " + this); } @@ -93,6 +100,10 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{ } double bestCost = bestKnownCosts; + + double additionalICostsAtRouteLevel = softRouteConstraint.getCosts(insertionContext); + additionalICostsAtRouteLevel += additionalAccessEgressCalculator.getCosts(insertionContext); + Shipment shipment = (Shipment)jobToInsert; TourActivity pickupShipment = activityFactory.createPickup(shipment); TourActivity deliverShipment = activityFactory.createDelivery(shipment); @@ -100,10 +111,10 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{ int pickupInsertionIndex = InsertionData.NO_INDEX; int deliveryInsertionIndex = InsertionData.NO_INDEX; - Start start = Start.newInstance(newVehicle.getLocationId(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival()); + Start start = Start.newInstance(newVehicle.getStartLocationId(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival()); start.setEndTime(newVehicleDepartureTime); - End end = End.newInstance(newVehicle.getLocationId(), 0.0, newVehicle.getLatestArrival()); + End end = End.newInstance(newVehicle.getEndLocationId(), 0.0, newVehicle.getLatestArrival()); TourActivity prevAct = start; double prevActEndTime = newVehicleDepartureTime; @@ -122,6 +133,7 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{ pickupShipmentLoopBroken = true; break; } + double additionalPickupICosts = softActivityConstraint.getCosts(insertionContext, prevAct, pickupShipment, activities.get(i), prevActEndTime); ActivityInsertionCosts pickupAIC = calculate(insertionContext,prevAct,pickupShipment,activities.get(i),prevActEndTime); TourActivity prevAct_deliveryLoop = pickupShipment; double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocationId(), pickupShipment.getLocationId(), prevActEndTime, newDriver, newVehicle); @@ -132,8 +144,10 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{ for(int j=i;j locTypeKeys = new HashSet(); List uniqueVehicles = new ArrayList(); for(Vehicle v : vehicles){ - LocTypeKey key = new LocTypeKey(v.getLocationId(),v.getType().getTypeId()); + LocTypeKey key = new LocTypeKey(v.getStartLocationId(),v.getType().getTypeId()); if(!locTypeKeys.contains(key)){ uniqueVehicles.add(v); locTypeKeys.add(key); @@ -390,9 +394,10 @@ public class VehicleRoutingProblem { .setFixedCost(fixed) .build(); PenaltyVehicleType penType = new PenaltyVehicleType(t,penaltyFactor); - String vehicleId = "penaltyVehicle_" + v.getLocationId() + "_" + t.getTypeId(); + String vehicleId = "penaltyVehicle_" + v.getStartLocationId() + "_" + t.getTypeId(); Vehicle penVehicle = VehicleImpl.Builder.newInstance(vehicleId).setEarliestStart(v.getEarliestDeparture()) - .setLatestArrival(v.getLatestArrival()).setLocationCoord(v.getCoord()).setLocationId(v.getLocationId()) + .setLatestArrival(v.getLatestArrival()).setStartLocationCoordinate(v.getStartLocationCoordinate()).setStartLocationId(v.getStartLocationId()) + .setEndLocationId(v.getEndLocationId()).setEndLocationCoordinate(v.getEndLocationCoordinate()) .setReturnToDepot(v.isReturnToDepot()).setType(penType).build(); addVehicle(penVehicle); } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/AdditionalTransportationCosts.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/AdditionalTransportationCosts.java new file mode 100644 index 00000000..b11885c0 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/AdditionalTransportationCosts.java @@ -0,0 +1,70 @@ +package jsprit.core.problem.constraint; + +import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.route.activity.End; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.util.CalculationUtils; + +/** + * Calculates additional transportation costs induced by inserting newAct. + * + * @author schroeder + * + */ +class AdditionalTransportationCosts implements SoftActivityConstraint{ + + private VehicleRoutingTransportCosts routingCosts; + + /** + * Constructs the calculator that calculates additional transportation costs induced by inserting new activity. + * + *

It is calculated at local level, i.e. the additional costs of inserting act_new between act_i and act_j is c(act_i,act_new,newVehicle)+c(act_new,act_j,newVehicle)-c(act_i,act_j,oldVehicle) + *

If newVehicle.isReturnToDepot == false then the additional costs of inserting act_new between act_i and end is c(act_i,act_new) [since act_new is then the new end-of-route] + * + * @param routingCosts + */ + public AdditionalTransportationCosts(VehicleRoutingTransportCosts routingCosts) { + super(); + this.routingCosts = routingCosts; + } + + /** + * Returns additional transportation costs induced by inserting newAct. + * + *

It is calculated at local level, i.e. the additional costs of inserting act_new between act_i and act_j is c(act_i,act_new,newVehicle)+c(act_new,act_j,newVehicle)-c(act_i,act_j,oldVehicle) + *

If newVehicle.isReturnToDepot == false then the additional costs of inserting act_new between act_i and end is c(act_i,act_new) [since act_new is then the new end-of-route] + */ + @Override + public double getCosts(JobInsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double depTimeAtPrevAct) { + double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); + double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); + + double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct; + double newAct_endTime = CalculationUtils.getActivityEndTime(newAct_arrTime, newAct); + + //open routes + if(nextAct instanceof End){ + if(!iFacts.getNewVehicle().isReturnToDepot()){ + return tp_costs_prevAct_newAct; + } + } + + double tp_costs_newAct_nextAct = routingCosts.getTransportCost(newAct.getLocationId(), nextAct.getLocationId(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); + double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct; + + double oldCosts; + if(iFacts.getRoute().isEmpty()){ + double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocationId(), nextAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); + oldCosts = tp_costs_prevAct_nextAct; + } + else{ + double tp_costs_prevAct_nextAct = routingCosts.getTransportCost(prevAct.getLocationId(), nextAct.getLocationId(), prevAct.getEndTime(), iFacts.getRoute().getDriver(), iFacts.getRoute().getVehicle()); + oldCosts = tp_costs_prevAct_nextAct; + } + + double additionalCosts = totalCosts - oldCosts; + return additionalCosts; + } + +} diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java index 6c2dc332..fd6545c4 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java @@ -14,7 +14,7 @@ import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter; import org.apache.log4j.Logger; @SuppressWarnings("deprecation") -public class ConstraintManager implements HardActivityStateLevelConstraint, HardRouteStateLevelConstraint{ +public class ConstraintManager implements HardActivityStateLevelConstraint, HardRouteStateLevelConstraint, SoftActivityConstraint, SoftRouteConstraint{ public static enum Priority { CRITICAL, HIGH, LOW @@ -26,6 +26,10 @@ public class ConstraintManager implements HardActivityStateLevelConstraint, Hard private HardRouteLevelConstraintManager routeLevelConstraintManager = new HardRouteLevelConstraintManager(); + private SoftActivityConstraintManager softActivityConstraintManager = new SoftActivityConstraintManager(); + + private SoftRouteConstraintManager softRouteConstraintManager = new SoftRouteConstraintManager(); + private VehicleRoutingProblem vrp; private RouteAndActivityStateGetter stateManager; @@ -56,6 +60,14 @@ public class ConstraintManager implements HardActivityStateLevelConstraint, Hard routeLevelConstraintManager.addConstraint((HardRouteStateLevelConstraint) c); constraintTypeKnown = true; } + if(c instanceof SoftRouteConstraint){ + softRouteConstraintManager.addConstraint((SoftRouteConstraint)c); + constraintTypeKnown = true; + } + if(c instanceof SoftActivityConstraint){ + softActivityConstraintManager.addConstraint((SoftActivityConstraint)c); + constraintTypeKnown = true; + } if(!constraintTypeKnown){ log.warn("constraint " + c + " unknown thus ignores the constraint. currently, a constraint must implement either HardActivityStateLevelConstraint or HardRouteStateLevelConstraint"); } @@ -82,6 +94,8 @@ public class ConstraintManager implements HardActivityStateLevelConstraint, Hard } } +// public void add + public void addConstraint(HardActivityStateLevelConstraint actLevelConstraint, Priority priority){ actLevelConstraintManager.addConstraint(actLevelConstraint,priority); } @@ -90,6 +104,14 @@ public class ConstraintManager implements HardActivityStateLevelConstraint, Hard routeLevelConstraintManager.addConstraint(routeLevelConstraint); } + public void addConstraint(SoftActivityConstraint softActivityConstraint){ + softActivityConstraintManager.addConstraint(softActivityConstraint); + } + + public void addConstraint(SoftRouteConstraint softRouteConstraint){ + softRouteConstraintManager.addConstraint(softRouteConstraint); + } + @Override public boolean fulfilled(JobInsertionContext insertionContext) { return routeLevelConstraintManager.fulfilled(insertionContext); @@ -104,7 +126,19 @@ public class ConstraintManager implements HardActivityStateLevelConstraint, Hard List constraints = new ArrayList(); constraints.addAll(actLevelConstraintManager.getAllConstraints()); constraints.addAll(routeLevelConstraintManager.getConstraints()); + constraints.addAll(softActivityConstraintManager.getConstraints()); + constraints.addAll(softRouteConstraintManager.getConstraints()); return Collections.unmodifiableCollection(constraints); } + + @Override + public double getCosts(JobInsertionContext insertionContext) { + return softRouteConstraintManager.getCosts(insertionContext); + } + + @Override + public double getCosts(JobInsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double prevActDepTime) { + return softActivityConstraintManager.getCosts(iFacts, prevAct, newAct, nextAct, prevActDepTime); + } } \ No newline at end of file diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftActivityConstraint.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftActivityConstraint.java new file mode 100644 index 00000000..8817b2ad --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftActivityConstraint.java @@ -0,0 +1,10 @@ +package jsprit.core.problem.constraint; + +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.route.activity.TourActivity; + +public interface SoftActivityConstraint extends SoftConstraint{ + + public double getCosts(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime); + +} diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftActivityConstraintManager.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftActivityConstraintManager.java new file mode 100644 index 00000000..bb8a1106 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftActivityConstraintManager.java @@ -0,0 +1,29 @@ +package jsprit.core.problem.constraint; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.route.activity.TourActivity; + +class SoftActivityConstraintManager implements SoftActivityConstraint{ + + private Collection softConstraints = new ArrayList(); + + public void addConstraint(SoftActivityConstraint constraint){ + softConstraints.add(constraint); + } + + Collection getConstraints(){ return Collections.unmodifiableCollection(softConstraints); } + + @Override + public double getCosts(JobInsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double prevActDepTime) { + double sumCosts = 0.0; + for(SoftActivityConstraint c : softConstraints){ + sumCosts += c.getCosts(iFacts, prevAct, newAct, nextAct, prevActDepTime); + } + return sumCosts; + } + +} diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftRouteConstraint.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftRouteConstraint.java new file mode 100644 index 00000000..1cc1d6e5 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftRouteConstraint.java @@ -0,0 +1,9 @@ +package jsprit.core.problem.constraint; + +import jsprit.core.problem.misc.JobInsertionContext; + +public interface SoftRouteConstraint extends SoftConstraint{ + + public double getCosts(JobInsertionContext insertionContext); + +} diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftRouteConstraintManager.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftRouteConstraintManager.java new file mode 100644 index 00000000..311ac857 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/SoftRouteConstraintManager.java @@ -0,0 +1,28 @@ +package jsprit.core.problem.constraint; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import jsprit.core.problem.misc.JobInsertionContext; + +class SoftRouteConstraintManager implements SoftRouteConstraint{ + + private Collection softConstraints = new ArrayList(); + + public void addConstraint(SoftRouteConstraint constraint){ + softConstraints.add(constraint); + } + + Collection getConstraints(){ return Collections.unmodifiableCollection(softConstraints); } + + @Override + public double getCosts(JobInsertionContext insertionContext) { + double sumCosts = 0.0; + for(SoftRouteConstraint c : softConstraints){ + sumCosts += c.getCosts(insertionContext); + } + return sumCosts; + } + +} diff --git a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java index e0445815..40f5d2fb 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java @@ -492,20 +492,45 @@ public class VrpXMLReader{ if(type == null) throw new IllegalStateException("vehicleType with typeId " + typeId + " is missing."); builder.setType(type); String locationId = vehicleConfig.getString("location.id"); + if(locationId == null) { + locationId = vehicleConfig.getString("startLocation.id"); + } if(locationId == null) throw new IllegalStateException("location.id is missing."); - builder.setLocationId(locationId); + builder.setStartLocationId(locationId); String coordX = vehicleConfig.getString("location.coord[@x]"); String coordY = vehicleConfig.getString("location.coord[@y]"); if(coordX == null || coordY == null) { + coordX = vehicleConfig.getString("startLocation.coord[@x]"); + coordY = vehicleConfig.getString("startLocation.coord[@y]"); + } + if(coordX == null || coordY == null) { + if(!doNotWarnAgain) { + logger.warn("location.coord is missing. will not warn you again."); + doNotWarnAgain = true; + } + } + else{ + Coordinate coordinate = Coordinate.newInstance(Double.parseDouble(coordX), Double.parseDouble(coordY)); + builder.setStartLocationCoordinate(coordinate); + + } + + String endLocationId = vehicleConfig.getString("endLocation.id"); + if(endLocationId != null) builder.setEndLocationId(endLocationId); + String endCoordX = vehicleConfig.getString("endLocation.coord[@x]"); + String endCoordY = vehicleConfig.getString("endLocation.coord[@y]"); + if(endCoordX == null || endCoordY == null) { if(!doNotWarnAgain) { - logger.warn("location.coord is missing. do not warn you again."); + logger.warn("endLocation.coord is missing. will not warn you again."); doNotWarnAgain = true; } } else{ - Coordinate coordinate = Coordinate.newInstance(Double.parseDouble(coordX), Double.parseDouble(coordY)); - builder.setLocationCoord(coordinate); + Coordinate coordinate = Coordinate.newInstance(Double.parseDouble(endCoordX), Double.parseDouble(endCoordY)); + builder.setEndLocationCoordinate(coordinate); } + + String start = vehicleConfig.getString("timeSchedule.start"); String end = vehicleConfig.getString("timeSchedule.end"); if(start != null) builder.setEarliestStart(Double.parseDouble(start)); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLWriter.java b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLWriter.java index 231779d1..01bba935 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLWriter.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLWriter.java @@ -236,10 +236,15 @@ public class VrpXMLWriter { } xmlConfig.setProperty(vehiclePathString + "("+counter+").id", vehicle.getId()); xmlConfig.setProperty(vehiclePathString + "("+counter+").typeId", vehicle.getType().getTypeId()); - xmlConfig.setProperty(vehiclePathString + "("+counter+").location.id", vehicle.getLocationId()); - if(vehicle.getCoord() != null){ - xmlConfig.setProperty(vehiclePathString + "("+counter+").location.coord[@x]", vehicle.getCoord().getX()); - xmlConfig.setProperty(vehiclePathString + "("+counter+").location.coord[@y]", vehicle.getCoord().getY()); + xmlConfig.setProperty(vehiclePathString + "("+counter+").startLocation.id", vehicle.getStartLocationId()); + if(vehicle.getStartLocationCoordinate() != null){ + xmlConfig.setProperty(vehiclePathString + "("+counter+").startLocation.coord[@x]", vehicle.getStartLocationCoordinate().getX()); + xmlConfig.setProperty(vehiclePathString + "("+counter+").startLocation.coord[@y]", vehicle.getStartLocationCoordinate().getY()); + } + xmlConfig.setProperty(vehiclePathString + "("+counter+").endLocation.id", vehicle.getEndLocationId()); + if(vehicle.getEndLocationCoordinate() != null){ + xmlConfig.setProperty(vehiclePathString + "("+counter+").endLocation.coord[@x]", vehicle.getEndLocationCoordinate().getX()); + xmlConfig.setProperty(vehiclePathString + "("+counter+").endLocation.coord[@y]", vehicle.getEndLocationCoordinate().getY()); } xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.start", vehicle.getEarliestDeparture()); xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.end", vehicle.getLatestArrival()); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java index e1c3083f..2a099724 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java @@ -64,8 +64,10 @@ public class VehicleRoute { * @param tour * @param driver * @param vehicle - * @return + * @return VehicleRoute + * @deprecated use VehicleRoute.Builder instead */ + @Deprecated public static VehicleRoute newInstance(TourActivities tour, Driver driver, Vehicle vehicle) { return new VehicleRoute(tour,driver,vehicle); } @@ -78,7 +80,7 @@ public class VehicleRoute { * @return */ public static VehicleRoute emptyRoute() { - return new VehicleRoute(TourActivities.emptyTour(), DriverImpl.noDriver(), VehicleImpl.createNoVehicle()); + return Builder.newInstance(VehicleImpl.createNoVehicle(), DriverImpl.noDriver()).build(); } /** @@ -92,11 +94,19 @@ public class VehicleRoute { /** * Returns new instance of this builder. * + *

Construction-settings of vehicleRoute: + *

startLocation == vehicle.getStartLocationId() + *

endLocation == vehicle.getEndLocationId() + *

departureTime == vehicle.getEarliestDepartureTime() + *

latestStart == Double.MAX_VALUE + *

earliestEnd == 0.0 + * * @param vehicle * @param driver * @return this builder */ public static Builder newInstance(Vehicle vehicle, Driver driver){ + if(vehicle == null || driver == null) throw new IllegalArgumentException("null arguments not accepted. ini emptyRoute with VehicleImpl.createNoVehicle() and DriverImpl.noDriver()"); return new Builder(vehicle,driver); } @@ -141,9 +151,11 @@ public class VehicleRoute { /** * Constructs the route-builder. * - *

Default startLocation is vehicle.getLocationId()
- * Default departureTime is vehicle.getEarliestDeparture()
- * Default endLocation is either vehicle.getLocationId() or (if !vehicle.isReturnToDepot()) last specified activityLocation + *

startLocation == vehicle.getStartLocationId() + *

endLocation == vehicle.getEndLocationId() + *

departureTime == vehicle.getEarliestDepartureTime() + *

latestStart == Double.MAX_VALUE + *

earliestEnd == 0.0 * @param vehicle * @param driver */ @@ -151,18 +163,22 @@ public class VehicleRoute { super(); this.vehicle = vehicle; this.driver = driver; - start = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); + start = Start.newInstance(vehicle.getStartLocationId(), vehicle.getEarliestDeparture(), Double.MAX_VALUE); start.setEndTime(vehicle.getEarliestDeparture()); - end = End.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); + end = End.newInstance(vehicle.getEndLocationId(), 0.0, vehicle.getLatestArrival()); } /** * 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. + * * @param departureTime - * @return + * @return builder + * @throws IllegalArgumentException if departureTime < vehicle.getEarliestDeparture() */ public Builder setDepartureTime(double departureTime){ + if(departureTime < start.getEndTime()) throw new IllegalArgumentException("departureTime < vehicle.getEarliestDepartureTime(). this must not be."); start.setEndTime(departureTime); return this; } @@ -172,8 +188,10 @@ public class VehicleRoute { * * @param endTime * @return this builder + * @throws IllegalArgumentException if endTime > vehicle.getLatestArrival() */ public Builder setRouteEndArrivalTime(double endTime){ + if(endTime > vehicle.getLatestArrival()) throw new IllegalArgumentException("endTime > vehicle.getLatestArrival(). this must not be."); end.setArrTime(endTime); return this; } @@ -306,6 +324,11 @@ public class VehicleRoute { private End end; + /** + * Copy constructor copying a route. + * + * @param route + */ private VehicleRoute(VehicleRoute route){ this.start = Start.copyOf(route.getStart()); this.end = End.copyOf(route.getEnd()); @@ -314,6 +337,7 @@ public class VehicleRoute { this.driver = route.getDriver(); } + @Deprecated private VehicleRoute(TourActivities tour, Driver driver, Vehicle vehicle) { super(); verify(tour, driver, vehicle); @@ -323,7 +347,11 @@ public class VehicleRoute { setStartAndEnd(vehicle, vehicle.getEarliestDeparture()); } - + /** + * Constructs route. + * + * @param builder + */ private VehicleRoute(Builder builder){ this.tourActivities = builder.tourActivities; this.vehicle = builder.vehicle; @@ -332,6 +360,14 @@ public class VehicleRoute { this.end = builder.end; } + /** + * + * @param tour + * @param driver + * @param vehicle + * @deprecated verification is a task of VehicleRoute.Builder + */ + @Deprecated private void verify(TourActivities tour, Driver driver, Vehicle vehicle) { if(tour == null || driver == null || vehicle == null) throw new IllegalStateException("null is not allowed for tour, driver or vehicle. use emptyRoute. use Tour.emptyTour, DriverImpl.noDriver() and VehicleImpl.noVehicle() instead." + "\n\tor make it easier and use VehicleRoute.emptyRoute()"); @@ -349,6 +385,11 @@ public class VehicleRoute { return Collections.unmodifiableList(tourActivities.getActivities()); } + /** + * Returns TourActivities. + * + * @return {@link TourActivities} + */ public TourActivities getTourActivities() { return tourActivities; } @@ -372,19 +413,42 @@ public class VehicleRoute { } /** - * Sets the vehicle and its departureTime. + * Sets the vehicle and its departureTime from vehicle.getStartLocationId(). * *

This implies the following:
* if start and end are null, new start and end activities are created.
- *

startActivity is initialized with the location of the specified vehicle. the time-window of this activity is initialized - * as follows: [time-window.start = vehicle.getEarliestDeparture()][time-window.end = vehicle.getLatestArrival()] - *

endActivity is initialized with the location of the specified vehicle as well. time-window of this activity:[time-window.start = vehicle.getEarliestDeparture()][time-window.end = vehicle.getLatestArrival()] - *

start.endTime is set to the specified departureTime - *

Note that start end end-locations are always initialized with the location of the specified vehicle. (this will change soon, then there will be start and end location of vehicle which can be different, 23.01.14) + *

startActivity is initialized with the start-location of the specified vehicle (vehicle.getStartLocationId()). the time-window of this activity is initialized + * such that [startActivity.getTheoreticalEarliestOperationStartTime() = vehicle.getEarliestDeparture()][startActivity.getTheoreticalLatestOperationStartTime() = vehicle.getLatestArrival()] + *

endActivity is initialized with the end-location of the specified vehicle (vehicle.getEndLocationId()). The time-window of the + * endActivity is initialized such that [endActivity.getTheoreticalEarliestOperationStartTime() = vehicle.getEarliestDeparture()][endActivity.getTheoreticalLatestOperationStartTime() = vehicle.getLatestArrival()] + *

startActivity.endTime (startActivity.getEndTime()) is set to max{vehicle.getEarliestDeparture(), vehicleDepTime}. + * thus, vehicle.getEarliestDeparture() is a physical constraint that has to be met. * * @param vehicle * @param vehicleDepTime */ + public void setVehicleAndDepartureTime(Vehicle vehicle, double vehicleDepTime){ + this.vehicle = vehicle; + setStartAndEnd(vehicle, vehicleDepTime); + } + + /** + * Sets the vehicle and its departureTime from vehicle.getStartLocationId(). + * + *

This implies the following:
+ * if start and end are null, new start and end activities are created.
+ *

startActivity is initialized with the start-location of the specified vehicle (vehicle.getStartLocationId()). the time-window of this activity is initialized + * such that [startActivity.getTheoreticalEarliestOperationStartTime() = vehicle.getEarliestDeparture()][startActivity.getTheoreticalLatestOperationStartTime() = vehicle.getLatestArrival()] + *

endActivity is initialized with the end-location of the specified vehicle (vehicle.getEndLocationId()). The time-window of the + * endActivity is initialized such that [endActivity.getTheoreticalEarliestOperationStartTime() = vehicle.getEarliestDeparture()][endActivity.getTheoreticalLatestOperationStartTime() = vehicle.getLatestArrival()] + *

startActivity.endTime (startActivity.getEndTime()) is set to max{vehicle.getEarliestDeparture(), vehicleDepTime}. + * thus, vehicle.getEarliestDeparture() is a physical constraint that has to be met. + * + * @param vehicle + * @param vehicleDepTime + * @deprecated use .setVehicleAndDepartureTime(Vehicle vehicle, double vehicleDepTime) instead + */ + @Deprecated public void setVehicle(Vehicle vehicle, double vehicleDepTime){ this.vehicle = vehicle; setStartAndEnd(vehicle, vehicleDepTime); @@ -393,14 +457,14 @@ public class VehicleRoute { private void setStartAndEnd(Vehicle vehicle, double vehicleDepTime) { if(!(vehicle instanceof NoVehicle)){ if(start == null && end == null){ - start = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); - end = End.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); + start = Start.newInstance(vehicle.getStartLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); + end = End.newInstance(vehicle.getEndLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); } - start.setEndTime(vehicleDepTime); + start.setEndTime(Math.max(vehicleDepTime, vehicle.getEarliestDeparture())); start.setTheoreticalEarliestOperationStartTime(vehicle.getEarliestDeparture()); start.setTheoreticalLatestOperationStartTime(vehicle.getLatestArrival()); - start.setLocationId(vehicle.getLocationId()); - end.setLocationId(vehicle.getLocationId()); + start.setLocationId(vehicle.getStartLocationId()); + end.setLocationId(vehicle.getEndLocationId()); end.setTheoreticalEarliestOperationStartTime(vehicle.getEarliestDeparture()); end.setTheoreticalLatestOperationStartTime(vehicle.getLatestArrival()); } @@ -411,14 +475,17 @@ public class VehicleRoute { * Sets departureTime of this route, i.e. the time the vehicle departs from its start-location. * * @param vehicleDepTime + * @deprecated use .setVehicleAndDepartureTime(...) instead (vehicle requires departureTime and the other way around, and earliestDepartureTime + * of a vehicle is a physical constraint of the vehicle and cannot be broken. Using this method might break this constraint.) */ + @Deprecated public void setDepartureTime(double vehicleDepTime){ if(start == null) throw new IllegalStateException("cannot set departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead."); start.setEndTime(vehicleDepTime); } /** - * Returns the departureTime of this vehicle. + * Returns the departureTime of this vehicle in this route. * * @return departureTime * @throws IllegalStateException if start is null @@ -431,7 +498,7 @@ public class VehicleRoute { /** * Returns tour if tour-activity-sequence is empty, i.e. to activity on the tour yet. * - * @return + * @return true if route is empty */ public boolean isEmpty() { return tourActivities.isEmpty(); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/InfiniteVehicles.java b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/InfiniteVehicles.java index 6cba846f..f46d6ce3 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/InfiniteVehicles.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/InfiniteVehicles.java @@ -45,7 +45,7 @@ class InfiniteVehicles implements VehicleFleetManager{ private void extractTypes(Collection vehicles) { for(Vehicle v : vehicles){ - VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(),v.getLocationId()); + VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(), v.getStartLocationId(),v.getEndLocationId()); types.put(typeKey,v); sortedTypes.add(typeKey); @@ -79,10 +79,26 @@ class InfiniteVehicles implements VehicleFleetManager{ return types.values(); } + /** + * @deprecated use getAvailableVehicles(Vehicle withoutThisType) instead + */ @Override + @Deprecated public Collection getAvailableVehicles(String withoutThisType, String locationId) { Collection vehicles = new ArrayList(); - VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType,locationId); + VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType, locationId,locationId); + for(VehicleTypeKey key : types.keySet()){ + if(!key.equals(thisKey)){ + vehicles.add(types.get(key)); + } + } + return vehicles; + } + + @Override + public Collection getAvailableVehicles(Vehicle withoutThisType) { + Collection vehicles = new ArrayList(); + VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType.getType().getTypeId(), withoutThisType.getStartLocationId(), withoutThisType.getEndLocationId()); for(VehicleTypeKey key : types.keySet()){ if(!key.equals(thisKey)){ vehicles.add(types.get(key)); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/Vehicle.java b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/Vehicle.java index ba24cd92..c73cfb24 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/Vehicle.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/Vehicle.java @@ -47,7 +47,9 @@ public interface Vehicle { *

Consequently, it should be the end-location of this vehicle, if returnToDepot is true. * * @return location-id of this vehicle + * @deprecated use getStartLocationId() instead */ + @Deprecated public abstract String getLocationId(); /** @@ -56,7 +58,9 @@ public interface Vehicle { *

Consequently, it should be the coordinate of the end-location, if returnToDepot is true. * * @return coordinate of this vehicle + * @deprecated use getStartLocationCoordinate() instead */ + @Deprecated public abstract Coordinate getCoord(); /** @@ -86,5 +90,25 @@ public interface Vehicle { * @return true if isReturnToDepot */ public abstract boolean isReturnToDepot(); - + + /** + * Returns the start-locationId of this vehicle. + */ + public abstract String getStartLocationId(); + + /** + * Returns the start-locationCoord of this vehicle. + */ + public abstract Coordinate getStartLocationCoordinate(); + + /** + * Returns the end-locationId of this vehicle. + * + */ + public abstract String getEndLocationId(); + + /** + * Returns the end-locationCoord of this vehicle. + */ + public abstract Coordinate getEndLocationCoordinate(); } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleFleetManager.java b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleFleetManager.java index 6d545e42..6eeee1ae 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleFleetManager.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleFleetManager.java @@ -31,6 +31,16 @@ public interface VehicleFleetManager { public abstract Collection getAvailableVehicles(); + /** + * + * @param withoutThisType + * @param locationId + * @return + * @deprecated use .getAvailableVehicles(Vehicle without) instead. this might ignore withoutType and returns all available vehicles + */ + @Deprecated public Collection getAvailableVehicles(String withoutThisType, String locationId); + + public Collection getAvailableVehicles(Vehicle withoutThisType); } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleFleetManagerImpl.java b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleFleetManagerImpl.java index 31ee75c4..8e1d303e 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleFleetManagerImpl.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleFleetManagerImpl.java @@ -132,11 +132,11 @@ class VehicleFleetManagerImpl implements VehicleFleetManager { } String typeId = v.getType().getTypeId(); if(v.getType() instanceof PenaltyVehicleType){ - VehicleTypeKey typeKey = new VehicleTypeKey(typeId,v.getLocationId()); + VehicleTypeKey typeKey = new VehicleTypeKey(typeId, v.getStartLocationId(), v.getEndLocationId()); penaltyVehicles.put(typeKey, v); } else{ - VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(),v.getLocationId()); + VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(), v.getStartLocationId(), v.getEndLocationId()); if(!typeMapOfAvailableVehicles.containsKey(typeKey)){ typeMapOfAvailableVehicles.put(typeKey, new TypeContainer(typeKey)); } @@ -147,7 +147,7 @@ class VehicleFleetManagerImpl implements VehicleFleetManager { private void removeVehicle(Vehicle v){ //it might be better to introduce a class PenaltyVehicle if(!(v.getType() instanceof PenaltyVehicleType)){ - VehicleTypeKey key = new VehicleTypeKey(v.getType().getTypeId(),v.getLocationId()); + VehicleTypeKey key = new VehicleTypeKey(v.getType().getTypeId(), v.getStartLocationId(), v.getEndLocationId()); if(typeMapOfAvailableVehicles.containsKey(key)){ typeMapOfAvailableVehicles.get(key).remove(v); } @@ -186,11 +186,13 @@ class VehicleFleetManagerImpl implements VehicleFleetManager { * @param typeId to specify the typeId that should not be the returned collection * @param locationId to specify the locationId that should not be in the returned collection * @return collection of available vehicles without the vehicles that have the typeId 'withoutThisType' AND the locationId 'withThisLocation'. + * @deprecated use .getAvailableVehicles(Vehicle without) instead - this might ignore withoutThisType and returns all available vehicles */ @Override + @Deprecated public Collection getAvailableVehicles(String withoutThisType, String withThisLocationId) { List vehicles = new ArrayList(); - VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType,withThisLocationId); + VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType, withThisLocationId, withThisLocationId); for(VehicleTypeKey key : typeMapOfAvailableVehicles.keySet()){ if(key.equals(thisKey)) continue; if(!typeMapOfAvailableVehicles.get(key).isEmpty()){ @@ -207,6 +209,24 @@ class VehicleFleetManagerImpl implements VehicleFleetManager { + @Override + public Collection getAvailableVehicles(Vehicle withoutThisType) { + List vehicles = new ArrayList(); + VehicleTypeKey thisKey = new VehicleTypeKey(withoutThisType.getType().getTypeId(), withoutThisType.getStartLocationId(), withoutThisType.getEndLocationId()); + for(VehicleTypeKey key : typeMapOfAvailableVehicles.keySet()){ + if(key.equals(thisKey)) continue; + if(!typeMapOfAvailableVehicles.get(key).isEmpty()){ + vehicles.add(typeMapOfAvailableVehicles.get(key).getVehicle()); + } + else{ + if(penaltyVehicles.containsKey(key)){ + vehicles.add(penaltyVehicles.get(key)); + } + } + } + return vehicles; + } + /* (non-Javadoc) * @see org.matsim.contrib.freight.vrp.basics.VehicleFleetManager#lock(org.matsim.contrib.freight.vrp.basics.Vehicle) */ diff --git a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java index 3f40b3f1..92e69358 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java @@ -79,6 +79,12 @@ public class VehicleImpl implements Vehicle { private double earliestStart = 0.0; private double latestArrival = Double.MAX_VALUE; + private String startLocationId; + private Coordinate startLocationCoord; + + private String endLocationId; + private Coordinate endLocationCoord; + private boolean returnToDepot = true; private VehicleType type = VehicleTypeImpl.Builder.newInstance("default", 0).build(); @@ -109,6 +115,12 @@ public class VehicleImpl implements Vehicle { /** * Sets the flag whether the vehicle must return to depot or not. * + *

If returnToDepot is true, the vehicle must return to specified end-location. If you + * omit specifying the end-location, vehicle returns to start-location (that must to be set). If + * you specify it, it returns to specified end-location. + * + *

If returnToDepot is false, the end-location of the vehicle is endogenous. + * * @param returnToDepot * @return this builder */ @@ -124,9 +136,12 @@ public class VehicleImpl implements Vehicle { * * @param id * @return this builder + * @deprecated use setStartLocationId(..) instead */ + @Deprecated public Builder setLocationId(String id){ this.locationId = id; + this.startLocationId = id; return this; } @@ -137,9 +152,60 @@ public class VehicleImpl implements Vehicle { * * @param coord * @return this builder + * @deprecated use setStartLocationCoordinate(...) instead */ + @Deprecated public Builder setLocationCoord(Coordinate coord){ this.locationCoord = coord; + this.startLocationCoord = coord; + return this; + } + + /** + * Sets the start-location of this vehicle. + * + * @param startLocationId + * @return this builder + * @throws IllegalArgumentException if startLocationId is null + */ + public Builder setStartLocationId(String startLocationId){ + if(startLocationId == null) throw new IllegalArgumentException("startLocationId cannot be null"); + this.startLocationId = startLocationId; + this.locationId = startLocationId; + return this; + } + + /** + * Sets the start-coordinate of this vehicle. + * + * @param coord + * @return this builder + */ + public Builder setStartLocationCoordinate(Coordinate coord){ + this.startLocationCoord = coord; + this.locationCoord = coord; + return this; + } + + /** + * Sets the end-locationId of this vehicle. + * + * @param endLocationId + * @return this builder + */ + public Builder setEndLocationId(String endLocationId){ + this.endLocationId = endLocationId; + return this; + } + + /** + * Sets the end-coordinate of this vehicle. + * + * @param coord + * @return this builder + */ + public Builder setEndLocationCoordinate(Coordinate coord){ + this.endLocationCoord = coord; return this; } @@ -171,13 +237,33 @@ public class VehicleImpl implements Vehicle { *

if {@link VehicleType} is not set, default vehicle-type is set with id="default" and * capacity=0 * + *

if startLocationId || locationId is null (=> startLocationCoordinate || locationCoordinate must be set) then startLocationId=startLocationCoordinate.toString() + * and locationId=locationCoordinate.toString() [coord.toString() --> [x=x_val][y=y_val]) + *

if endLocationId is null and endLocationCoordinate is set then endLocationId=endLocationCoordinate.toString() + *

if endLocationId==null AND endLocationCoordinate==null then endLocationId=startLocationId AND endLocationCoord=startLocationCoord + * Thus endLocationId can never be null even returnToDepot is false. + * * @return vehicle - * @throw IllegalStateException if both locationId and locationCoord is not set + * @throws IllegalStateException if both locationId and locationCoord is not set or (endLocationCoord!=null AND returnToDepot=false) + * or (endLocationId!=null AND returnToDepot=false) */ public VehicleImpl build(){ - if(locationId == null && locationCoord != null) locationId = locationCoord.toString(); + if((locationId == null && locationCoord == null) && (startLocationId == null && startLocationCoord == null)){ + throw new IllegalStateException("vehicle requires startLocation. but neither locationId nor locationCoord nor startLocationId nor startLocationCoord has been set"); + } + if(locationId == null && locationCoord != null) { + locationId = locationCoord.toString(); + startLocationId = locationCoord.toString(); + } if(locationId == null && locationCoord == null) throw new IllegalStateException("locationId and locationCoord is missing."); if(locationCoord == null) log.warn("locationCoord for vehicle " + id + " is missing."); + if(endLocationId == null && endLocationCoord != null) endLocationId = endLocationCoord.toString(); + if(endLocationId == null && endLocationCoord == null) { + endLocationId = startLocationId; + endLocationCoord = startLocationCoord; + } + if( !startLocationId.equals(endLocationId) && returnToDepot == false) throw new IllegalStateException("this must not be. you specified both endLocationId and open-routes. this is contradictory.
" + + "if you set endLocation, returnToDepot must be true. if returnToDepot is false, endLocationCoord must not be specified."); return new VehicleImpl(this); } @@ -216,6 +302,14 @@ public class VehicleImpl implements Vehicle { private final boolean returnToDepot; + private final Coordinate endLocationCoord; + + private final String endLocationId; + + private final Coordinate startLocationCoord; + + private final String startLocationId; + private VehicleImpl(Builder builder){ id = builder.id; type = builder.type; @@ -224,6 +318,10 @@ public class VehicleImpl implements Vehicle { earliestDeparture = builder.earliestStart; latestArrival = builder.latestArrival; returnToDepot = builder.returnToDepot; + startLocationId = builder.startLocationId; + startLocationCoord = builder.startLocationCoord; + endLocationId = builder.endLocationId; + endLocationCoord = builder.endLocationCoord; } /** @@ -236,6 +334,10 @@ public class VehicleImpl implements Vehicle { return "[id="+id+"][type="+type+"][locationId="+locationId+"][coord=" + coord + "][isReturnToDepot=" + isReturnToDepot() + "]"; } + /** + * @deprecated use getStartLocationCoordinate() instead + */ + @Deprecated public Coordinate getCoord() { return coord; } @@ -250,6 +352,10 @@ public class VehicleImpl implements Vehicle { return latestArrival; } + /** + * @deprecated use getStartLocationId() instead + */ + @Deprecated @Override public String getLocationId() { return locationId; @@ -273,5 +379,25 @@ public class VehicleImpl implements Vehicle { public boolean isReturnToDepot() { return returnToDepot; } + + @Override + public String getStartLocationId() { + return this.startLocationId; + } + + @Override + public Coordinate getStartLocationCoordinate() { + return this.startLocationCoord; + } + + @Override + public String getEndLocationId() { + return this.endLocationId; + } + + @Override + public Coordinate getEndLocationCoordinate() { + return this.endLocationCoord; + } } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleTypeKey.java b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleTypeKey.java index a39907df..7a9e82dd 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleTypeKey.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleTypeKey.java @@ -1,26 +1,45 @@ package jsprit.core.problem.vehicle; +/** + * Key to identify different vehicles + * + *

Two vehicles are equal if they share the same type and location. + *

Note that earliestStart and latestArrival are ignored by this key (this might change in future) + * + * @author stefan + * + */ class VehicleTypeKey { public final String type; - public final String locationId; + public final String startLocationId; + public final String endLocationId; - VehicleTypeKey(String typeId, String locationId) { + VehicleTypeKey(String typeId, String startLocationId, String endLocationId) { super(); this.type = typeId; - this.locationId = locationId; + this.startLocationId = startLocationId; + this.endLocationId = endLocationId; } + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result - + ((locationId == null) ? 0 : locationId.hashCode()); + + ((endLocationId == null) ? 0 : endLocationId.hashCode()); + result = prime * result + + ((startLocationId == null) ? 0 : startLocationId.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); return result; } + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ @Override public boolean equals(Object obj) { if (this == obj) @@ -30,10 +49,15 @@ class VehicleTypeKey { if (getClass() != obj.getClass()) return false; VehicleTypeKey other = (VehicleTypeKey) obj; - if (locationId == null) { - if (other.locationId != null) + if (endLocationId == null) { + if (other.endLocationId != null) return false; - } else if (!locationId.equals(other.locationId)) + } else if (!endLocationId.equals(other.endLocationId)) + return false; + if (startLocationId == null) { + if (other.startLocationId != null) + return false; + } else if (!startLocationId.equals(other.startLocationId)) return false; if (type == null) { if (other.type != null) @@ -43,6 +67,6 @@ class VehicleTypeKey { return true; } - + } \ No newline at end of file diff --git a/jsprit-core/src/main/java/jsprit/core/util/NeighborhoodImpl.java b/jsprit-core/src/main/java/jsprit/core/util/NeighborhoodImpl.java index 393289dc..61fdbaf9 100644 --- a/jsprit-core/src/main/java/jsprit/core/util/NeighborhoodImpl.java +++ b/jsprit-core/src/main/java/jsprit/core/util/NeighborhoodImpl.java @@ -62,7 +62,7 @@ public class NeighborhoodImpl implements Neighborhood{ for(Service i : services){ Set neigh = new HashSet(); for(Vehicle v : vehicles){ - double dist2depot = EuclideanDistanceCalculator.calculateDistance(v.getCoord(), i.getCoord()); + double dist2depot = EuclideanDistanceCalculator.calculateDistance(v.getStartLocationCoordinate(), i.getCoord()); if(dist2depot <= threshold){ neighborsToAll.add(((Service)i).getLocationId()); } @@ -80,7 +80,7 @@ public class NeighborhoodImpl implements Neighborhood{ private void makeNeighborsToAll(Collection vehicles) { for(Vehicle v : vehicles){ - neighborsToAll.add(v.getLocationId()); + neighborsToAll.add(v.getStartLocationId()); } } diff --git a/jsprit-core/src/main/java/jsprit/core/util/VrpVerifier.java b/jsprit-core/src/main/java/jsprit/core/util/VrpVerifier.java index 783e428b..3e6b9309 100644 --- a/jsprit-core/src/main/java/jsprit/core/util/VrpVerifier.java +++ b/jsprit-core/src/main/java/jsprit/core/util/VrpVerifier.java @@ -21,15 +21,21 @@ import java.util.Collection; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.listener.AlgorithmStartsListener; import jsprit.core.problem.VehicleRoutingProblem; -import jsprit.core.problem.driver.DriverImpl; import jsprit.core.problem.job.Job; -import jsprit.core.problem.job.Service; import jsprit.core.problem.solution.VehicleRoutingProblemSolution; import jsprit.core.problem.vehicle.Vehicle; import org.apache.log4j.Logger; - +/** + * Verifies whether vrp can be solved. + * + *

Checks
+ * - capacities, i.e. whether all job at least fit into the biggest vehicle + * + * @author stefan + * + */ public class VrpVerifier implements AlgorithmStartsListener{ private static Logger log = Logger.getLogger(VrpVerifier.class); @@ -47,26 +53,26 @@ public class VrpVerifier implements AlgorithmStartsListener{ } } log.info("ok"); - log.info("check vehicles can manage shuttle tours ..."); - for(Job j : problem.getJobs().values()){ - Service s = (Service)j; - boolean jobCanBeRoutedWithinTimeWindow = false; - for(Vehicle v : problem.getVehicles()){ - double transportTime = problem.getTransportCosts().getTransportTime(v.getLocationId(), s.getLocationId(), v.getEarliestDeparture(), DriverImpl.noDriver(), v); - if(transportTime+v.getEarliestDeparture() < s.getTimeWindow().getEnd()){ - jobCanBeRoutedWithinTimeWindow = true; - break; - } - else{ - log.warn("vehicle " + v + " needs " + transportTime + " time-units to get to " + s.getLocationId() + ". latestOperationStartTime however is " + s.getTimeWindow().getEnd()); - } - - } - if(!jobCanBeRoutedWithinTimeWindow){ - throw new IllegalStateException("no vehicle is able to cover the distance from depot to " + s.getLocationId() + " to meet the time-window " + s.getTimeWindow() + "."); - } - } - log.info("ok"); +// log.info("check vehicles can manage shuttle tours ..."); +// for(Job j : problem.getJobs().values()){ +// Service s = (Service)j; +// boolean jobCanBeRoutedWithinTimeWindow = false; +// for(Vehicle v : problem.getVehicles()){ +// double transportTime = problem.getTransportCosts().getTransportTime(v.getStartLocationId(), s.getLocationId(), v.getEarliestDeparture(), DriverImpl.noDriver(), v); +// if(transportTime+v.getEarliestDeparture() < s.getTimeWindow().getEnd()){ +// jobCanBeRoutedWithinTimeWindow = true; +// break; +// } +// else{ +// log.warn("vehicle " + v + " needs " + transportTime + " time-units to get to " + s.getLocationId() + ". latestOperationStartTime however is " + s.getTimeWindow().getEnd()); +// } +// +// } +// if(!jobCanBeRoutedWithinTimeWindow){ +// throw new IllegalStateException("no vehicle is able to cover the distance from depot to " + s.getLocationId() + " to meet the time-window " + s.getTimeWindow() + "."); +// } +// } +// log.info("ok"); log.info("verifying done"); } diff --git a/jsprit-core/src/main/resources/algorithm_schema.xsd b/jsprit-core/src/main/resources/algorithm_schema.xsd index 6ea5d966..b2a80039 100644 --- a/jsprit-core/src/main/resources/algorithm_schema.xsd +++ b/jsprit-core/src/main/resources/algorithm_schema.xsd @@ -226,7 +226,8 @@ - + + diff --git a/jsprit-core/src/main/resources/vrp_xml_schema.xsd b/jsprit-core/src/main/resources/vrp_xml_schema.xsd index 421e9574..b0452e62 100644 --- a/jsprit-core/src/main/resources/vrp_xml_schema.xsd +++ b/jsprit-core/src/main/resources/vrp_xml_schema.xsd @@ -37,18 +37,29 @@ - + - - - - - - + + + + + + + + + + + + + + + + + + - diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/BuildCVRPAlgoFromScratch_IT.java b/jsprit-core/src/test/java/jsprit/core/algorithm/BuildCVRPAlgoFromScratch_IT.java index 9c3a63da..c1094738 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/BuildCVRPAlgoFromScratch_IT.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/BuildCVRPAlgoFromScratch_IT.java @@ -67,6 +67,7 @@ public class BuildCVRPAlgoFromScratch_IT { ConstraintManager cManager = new ConstraintManager(vrp, stateManager); cManager.addLoadConstraint(); cManager.addTimeWindowConstraint(); + VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager(); @@ -102,11 +103,7 @@ public class BuildCVRPAlgoFromScratch_IT { vra = new VehicleRoutingAlgorithm(vrp, strategyManager); vra.addListener(stateManager); vra.addListener(new RemoveEmptyVehicles(fleetManager)); - -// vra.getAlgorithmListeners().addListener(stateManager); -// vra.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager); -// vra.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager)); - + VehicleRoutingProblemSolution iniSolution = new InsertionInitialSolutionFactory(bestInsertion, solutionCostCalculator).createSolution(vrp); vra.addInitialSolution(iniSolution); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollectionWithCostsHigherThanTimesAndFiniteFleet_IT.java b/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollectionWithCostsHigherThanTimesAndFiniteFleet_IT.java index 3a012aef..6bbeab9c 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollectionWithCostsHigherThanTimesAndFiniteFleet_IT.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollectionWithCostsHigherThanTimesAndFiniteFleet_IT.java @@ -142,7 +142,7 @@ public class RefuseCollectionWithCostsHigherThanTimesAndFiniteFleet_IT { VehicleTypeImpl bigType = typeBuilder.build(); VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationId("1"); + vehicleBuilder.setStartLocationId("1"); vehicleBuilder.setType(bigType); vehicleBuilder.setLatestArrival(220); Vehicle bigVehicle = vehicleBuilder.build(); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollection_IT.java b/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollection_IT.java index abd5e244..d29155b4 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollection_IT.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollection_IT.java @@ -155,7 +155,7 @@ public class RefuseCollection_IT { VehicleTypeImpl bigType = typeBuilder.build(); VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationId("1"); + vehicleBuilder.setStartLocationId("1"); vehicleBuilder.setType(bigType); Vehicle bigVehicle = vehicleBuilder.build(); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/CalcVehicleTypeDependentServiceInsertionTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/CalcVehicleTypeDependentServiceInsertionTest.java index b7d775ab..a1495182 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/CalcVehicleTypeDependentServiceInsertionTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/CalcVehicleTypeDependentServiceInsertionTest.java @@ -53,8 +53,8 @@ public class CalcVehicleTypeDependentServiceInsertionTest { veh2 = mock(Vehicle.class); when(veh1.getType()).thenReturn(VehicleTypeImpl.Builder.newInstance("type1", 0).build()); when(veh2.getType()).thenReturn(VehicleTypeImpl.Builder.newInstance("type2", 0).build()); - when(veh1.getLocationId()).thenReturn("loc1"); - when(veh2.getLocationId()).thenReturn("loc2"); + when(veh1.getStartLocationId()).thenReturn("loc1"); + when(veh2.getStartLocationId()).thenReturn("loc2"); fleetManager = mock(VehicleFleetManager.class); service = mock(Service.class); vehicleRoute = mock(VehicleRoute.class); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/CalcWithTimeSchedulingTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/CalcWithTimeSchedulingTest.java index 8c175cf2..05338448 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/CalcWithTimeSchedulingTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/CalcWithTimeSchedulingTest.java @@ -43,7 +43,7 @@ public class CalcWithTimeSchedulingTest { public void timeScheduler(){ VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); Vehicle vehicle = VehicleImpl.Builder.newInstance("myVehicle").setEarliestStart(0.0).setLatestArrival(100.0). - setLocationCoord(Coordinate.newInstance(0, 0)).setLocationId("0,0") + setStartLocationCoordinate(Coordinate.newInstance(0, 0)).setStartLocationId("0,0") .setType(VehicleTypeImpl.Builder.newInstance("myType", 20).setCostPerDistance(1.0).build()).build(); vrpBuilder.addVehicle(vehicle); vrpBuilder.addJob(Service.Builder.newInstance("myService", 2).setLocationId("0,20").setCoord(Coordinate.newInstance(0, 20)).build()); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ServiceInsertionAndLoadConstraintsTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ServiceInsertionAndLoadConstraintsTest.java index 20093453..1b3ba1a6 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ServiceInsertionAndLoadConstraintsTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ServiceInsertionAndLoadConstraintsTest.java @@ -28,6 +28,7 @@ import jsprit.core.problem.job.Shipment; import jsprit.core.problem.misc.JobInsertionContext; import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl; import jsprit.core.problem.vehicle.VehicleType; @@ -91,13 +92,15 @@ public class ServiceInsertionAndLoadConstraintsTest { }; routingCosts = new ManhattanCosts(locations); VehicleType type = VehicleTypeImpl.Builder.newInstance("t", 2).setCostPerDistance(1).build(); - vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("0,0").setType(type).build(); + vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("0,0").setType(type).build(); activityInsertionCostsCalculator = new LocalActivityInsertionCostsCalculator(routingCosts, activityCosts); createInsertionCalculator(hardRouteLevelConstraint); } private void createInsertionCalculator(HardRouteStateLevelConstraint hardRouteLevelConstraint) { - insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, hardActivityLevelConstraint); + ConstraintManager constraintManager = new ConstraintManager(mock(VehicleRoutingProblem.class), mock(RouteAndActivityStateGetter.class)); + constraintManager.addConstraint(hardRouteLevelConstraint); + insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); } @Test @@ -106,10 +109,10 @@ public class ServiceInsertionAndLoadConstraintsTest { Pickup pickup = (Pickup) Pickup.Builder.newInstance("pick", 15).setLocationId("0,10").build(); VehicleType type = VehicleTypeImpl.Builder.newInstance("t", 50).setCostPerDistance(1).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("0,0").setType(type).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("0,0").setType(type).build(); VehicleRoute route = VehicleRoute.emptyRoute(); - route.setVehicle(vehicle, 0.0); + route.setVehicleAndDepartureTime(vehicle, 0.0); Inserter inserter = new Inserter(new InsertionListeners()); @@ -136,8 +139,8 @@ public class ServiceInsertionAndLoadConstraintsTest { stateManager.informInsertionStarts(Arrays.asList(route), null); JobCalculatorSwitcher switcher = new JobCalculatorSwitcher(); - ServiceInsertionCalculator serviceInsertionCalc = new ServiceInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, constraintManager); - ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, constraintManager); + ServiceInsertionCalculator serviceInsertionCalc = new ServiceInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); + ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); switcher.put(Pickup.class, serviceInsertionCalc); switcher.put(Delivery.class, serviceInsertionCalc); switcher.put(Shipment.class, insertionCalculator); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculatorTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculatorTest.java index 0937f9ee..0745c63e 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculatorTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/ShipmentInsertionCalculatorTest.java @@ -24,6 +24,7 @@ import jsprit.core.problem.job.Shipment; import jsprit.core.problem.misc.JobInsertionContext; import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.solution.route.state.RouteAndActivityStateGetter; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl; import jsprit.core.problem.vehicle.VehicleType; @@ -87,13 +88,15 @@ public class ShipmentInsertionCalculatorTest { }; routingCosts = new ManhattanCosts(locations); VehicleType type = VehicleTypeImpl.Builder.newInstance("t", 2).setCostPerDistance(1).build(); - vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("0,0").setType(type).build(); + vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("0,0").setType(type).build(); activityInsertionCostsCalculator = new LocalActivityInsertionCostsCalculator(routingCosts, activityCosts); createInsertionCalculator(hardRouteLevelConstraint); } private void createInsertionCalculator(HardRouteStateLevelConstraint hardRouteLevelConstraint) { - insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, hardActivityLevelConstraint); + ConstraintManager constraintManager = new ConstraintManager(mock(VehicleRoutingProblem.class), mock(RouteAndActivityStateGetter.class)); + constraintManager.addConstraint(hardRouteLevelConstraint); + insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); } @Test @@ -181,7 +184,7 @@ public class ShipmentInsertionCalculatorTest { VehicleRoute route = VehicleRoute.emptyRoute(); - route.setVehicle(vehicle, 0.0); + route.setVehicleAndDepartureTime(vehicle, 0.0); Inserter inserter = new Inserter(new InsertionListeners()); @@ -199,7 +202,7 @@ public class ShipmentInsertionCalculatorTest { constraintManager.addConstraint(new ShipmentPickupsFirstConstraint(),Priority.CRITICAL); ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, - hardRouteLevelConstraint, constraintManager); + constraintManager); InsertionData iData = insertionCalculator.getInsertionData(route, shipment3, vehicle, 0.0, DriverImpl.noDriver(), Double.MAX_VALUE); @@ -212,7 +215,7 @@ public class ShipmentInsertionCalculatorTest { Shipment shipment = Shipment.Builder.newInstance("s", 1).setPickupLocation("0,10").setDeliveryLocation("0,0").build(); Shipment shipment2 = Shipment.Builder.newInstance("s2", 1).setPickupLocation("10,10").setDeliveryLocation("0,0").build(); VehicleRoute route = VehicleRoute.emptyRoute(); - route.setVehicle(vehicle, 0.0); + route.setVehicleAndDepartureTime(vehicle, 0.0); Inserter inserter = new Inserter(new InsertionListeners()); @@ -240,8 +243,8 @@ public class ShipmentInsertionCalculatorTest { stateManager.informInsertionStarts(Arrays.asList(route), null); JobCalculatorSwitcher switcher = new JobCalculatorSwitcher(); - ServiceInsertionCalculator serviceInsertionCalc = new ServiceInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, constraintManager); - ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, hardRouteLevelConstraint, constraintManager); + ServiceInsertionCalculator serviceInsertionCalc = new ServiceInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); + ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator, constraintManager); switcher.put(Pickup.class, serviceInsertionCalc); switcher.put(Shipment.class, insertionCalculator); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java index 675bcb98..570d447c 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertion.java @@ -23,22 +23,32 @@ import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; -import jsprit.core.algorithm.ExampleActivityCostFunction; import jsprit.core.algorithm.state.StateManager; import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.constraint.ConstraintManager; +import jsprit.core.problem.cost.AbstractForwardVehicleRoutingTransportCosts; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.driver.Driver; import jsprit.core.problem.driver.DriverImpl; import jsprit.core.problem.driver.DriverImpl.NoDriver; import jsprit.core.problem.job.Job; import jsprit.core.problem.job.Service; +import jsprit.core.problem.misc.JobInsertionContext; import jsprit.core.problem.solution.route.VehicleRoute; -import jsprit.core.problem.solution.route.activity.ServiceActivity; import jsprit.core.problem.solution.route.activity.TimeWindow; -import jsprit.core.problem.solution.route.activity.TourActivities; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.Vehicle; +import jsprit.core.problem.vehicle.VehicleImpl; +import jsprit.core.problem.vehicle.VehicleType; +import jsprit.core.problem.vehicle.VehicleTypeImpl; +import jsprit.core.util.Coordinate; +import jsprit.core.util.EuclideanDistanceCalculator; +import jsprit.core.util.Locations; +import jsprit.core.util.ManhattanDistanceCalculator; import org.apache.log4j.Level; import org.apache.log4j.Logger; @@ -60,10 +70,10 @@ public class TestCalculatesServiceInsertion { private Service first; - private Service second; - private Service third; + private Service second; + private StateManager states; private NoDriver driver; @@ -74,87 +84,47 @@ public class TestCalculatesServiceInsertion { public void setup(){ Logger.getRootLogger().setLevel(Level.DEBUG); - costs = mock(VehicleRoutingTransportCosts.class); - vehicle = mock(Vehicle.class); - when(vehicle.getCapacity()).thenReturn(1000); - when(vehicle.getLocationId()).thenReturn("depot"); - when(vehicle.getEarliestDeparture()).thenReturn(0.0); - when(vehicle.getLatestArrival()).thenReturn(100.0); - when(vehicle.isReturnToDepot()).thenReturn(true); + VehicleType t1 = VehicleTypeImpl.Builder.newInstance("t1", 1000).setCostPerDistance(1.0).build(); + vehicle = VehicleImpl.Builder.newInstance("vehicle").setLatestArrival(100.0).setStartLocationId("0,0").setType(t1).build(); - newVehicle = mock(Vehicle.class); - when(newVehicle.getCapacity()).thenReturn(1000); - when(newVehicle.getLocationId()).thenReturn("depot"); - when(newVehicle.getEarliestDeparture()).thenReturn(0.0); - when(newVehicle.getLatestArrival()).thenReturn(100.0); - when(newVehicle.isReturnToDepot()).thenReturn(true); + VehicleType t2 = VehicleTypeImpl.Builder.newInstance("t2", 1000).setCostPerDistance(2.0).build(); + newVehicle = VehicleImpl.Builder.newInstance("newVehicle").setLatestArrival(100.0).setStartLocationId("0,0").setType(t2).build(); driver = DriverImpl.noDriver(); - when(costs.getTransportCost("depot", "1", 0.0, driver, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("depot", "2", 0.0, driver, vehicle)).thenReturn(20.0); - when(costs.getTransportCost("depot", "3", 0.0, driver, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("1", "2", 0.0, driver, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("1", "3", 0.0, driver, vehicle)).thenReturn(20.0); - when(costs.getTransportCost("2", "3", 0.0, driver, vehicle)).thenReturn(10.0); + final Locations locations = new Locations(){ + + @Override + public Coordinate getCoord(String id) { + //assume: locationId="x,y" + String[] splitted = id.split(","); + return Coordinate.newInstance(Double.parseDouble(splitted[0]), + Double.parseDouble(splitted[1])); + } + + }; + costs = new AbstractForwardVehicleRoutingTransportCosts() { + + @Override + public double getTransportTime(String fromId, String toId,double departureTime, Driver driver, Vehicle vehicle) { + return ManhattanDistanceCalculator.calculateDistance(locations.getCoord(fromId), locations.getCoord(toId)); + } + + @Override + public double getTransportCost(String fromId, String toId, double departureTime, Driver driver, Vehicle vehicle) { + return vehicle.getType().getVehicleCostParams().perDistanceUnit*ManhattanDistanceCalculator.calculateDistance(locations.getCoord(fromId), locations.getCoord(toId)); + } + }; + - when(costs.getTransportCost("1", "depot", 0.0, driver, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("2", "depot", 0.0, driver, vehicle)).thenReturn(20.0); - when(costs.getTransportCost("3", "depot", 0.0, driver, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("2", "1", 0.0, driver, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("3", "1", 0.0, driver, vehicle)).thenReturn(20.0); - when(costs.getTransportCost("3", "2", 0.0, driver, vehicle)).thenReturn(10.0); + first = Service.Builder.newInstance("1", 0).setLocationId("0,10").setTimeWindow(TimeWindow.newInstance(0.0, 100.0)).build(); + second = Service.Builder.newInstance("2", 0).setLocationId("10,10").setTimeWindow(TimeWindow.newInstance(0.0, 100.0)).build(); + third = Service.Builder.newInstance("3", 0).setLocationId("10,0").setTimeWindow(TimeWindow.newInstance(0.0, 100.0)).build(); - when(costs.getTransportCost("depot", "1", 0.0, driver, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("depot", "2", 0.0, driver, newVehicle)).thenReturn(40.0); - when(costs.getTransportCost("depot", "3", 0.0, driver, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("1", "2", 0.0, driver, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("1", "3", 0.0, driver, newVehicle)).thenReturn(40.0); - when(costs.getTransportCost("2", "3", 0.0, driver, newVehicle)).thenReturn(20.0); - - when(costs.getTransportCost("1", "depot", 0.0, driver, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("2", "depot", 0.0, driver, newVehicle)).thenReturn(40.0); - when(costs.getTransportCost("3", "depot", 0.0, driver, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("2", "1", 0.0, driver, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("3", "1", 0.0, driver, newVehicle)).thenReturn(40.0); - when(costs.getTransportCost("3", "2", 0.0, driver, newVehicle)).thenReturn(20.0); - - when(costs.getTransportCost("depot", "1", 0.0, null, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("depot", "2", 0.0, null, vehicle)).thenReturn(20.0); - when(costs.getTransportCost("depot", "3", 0.0, null, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("1", "2", 0.0, null, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("1", "3", 0.0, null, vehicle)).thenReturn(20.0); - when(costs.getTransportCost("2", "3", 0.0, null, vehicle)).thenReturn(10.0); - - when(costs.getTransportCost("1", "depot", 0.0, null, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("2", "depot", 0.0, null, vehicle)).thenReturn(20.0); - when(costs.getTransportCost("3", "depot", 0.0, null, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("2", "1", 0.0, null, vehicle)).thenReturn(10.0); - when(costs.getTransportCost("3", "1", 0.0, null, vehicle)).thenReturn(20.0); - when(costs.getTransportCost("3", "2", 0.0, null, vehicle)).thenReturn(10.0); - - when(costs.getTransportCost("depot", "1", 0.0, null, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("depot", "2", 0.0, null, newVehicle)).thenReturn(40.0); - when(costs.getTransportCost("depot", "3", 0.0, null, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("1", "2", 0.0, null, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("1", "3", 0.0, null, newVehicle)).thenReturn(40.0); - when(costs.getTransportCost("2", "3", 0.0, null, newVehicle)).thenReturn(20.0); - - when(costs.getTransportCost("1", "depot", 0.0, null, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("2", "depot", 0.0, null, newVehicle)).thenReturn(40.0); - when(costs.getTransportCost("3", "depot", 0.0, null, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("2", "1", 0.0, null, newVehicle)).thenReturn(20.0); - when(costs.getTransportCost("3", "1", 0.0, null, newVehicle)).thenReturn(40.0); - when(costs.getTransportCost("3", "2", 0.0, null, newVehicle)).thenReturn(20.0); - - - first = Service.Builder.newInstance("1", 0).setLocationId("1").setTimeWindow(TimeWindow.newInstance(0.0, 100.0)).build(); - second = Service.Builder.newInstance("3", 0).setLocationId("3").setTimeWindow(TimeWindow.newInstance(0.0, 100.0)).build(); - third = Service.Builder.newInstance("2", 0).setLocationId("2").setTimeWindow(TimeWindow.newInstance(0.0, 100.0)).build(); Collection jobs = new ArrayList(); jobs.add(first); - jobs.add(second); jobs.add(third); + jobs.add(second); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addAllJobs(jobs).addVehicle(vehicle).setRoutingCost(costs).build(); @@ -166,13 +136,9 @@ public class TestCalculatesServiceInsertion { cManager.addLoadConstraint(); cManager.addTimeWindowConstraint(); - ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction(); - - - serviceInsertion = new ServiceInsertionCalculator(costs, new LocalActivityInsertionCostsCalculator(costs, activityCosts), cManager, cManager); - + VehicleRoutingActivityCosts actCosts = mock(VehicleRoutingActivityCosts.class); -// stateUpdater = new UpdateStates(states, costs, activityCosts); + serviceInsertion = new ServiceInsertionCalculator(costs, new LocalActivityInsertionCostsCalculator(costs, actCosts), cManager); } @@ -184,12 +150,9 @@ public class TestCalculatesServiceInsertion { @Test public void whenInsertingTheFirstJobInAnEmptyTourWithVehicle_itCalculatesMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).build(); states.informInsertionStarts(Arrays.asList(route), null); -// stateUpdater.update(route); - + InsertionData iData = serviceInsertion.getInsertionData(route, first, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); assertEquals(20.0, iData.getInsertionCost(), 0.2); assertEquals(0, iData.getDeliveryInsertionIndex()); @@ -197,75 +160,106 @@ public class TestCalculatesServiceInsertion { @Test public void whenInsertingTheSecondJobInAnNonEmptyTourWithVehicle_itCalculatesMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(first)); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).build(); states.informInsertionStarts(Arrays.asList(route), null); - InsertionData iData = serviceInsertion.getInsertionData(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); + InsertionData iData = serviceInsertion.getInsertionData(route, third, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); assertEquals(20.0, iData.getInsertionCost(), 0.2); assertEquals(0, iData.getDeliveryInsertionIndex()); } @Test public void whenInsertingThirdJobWithVehicle_itCalculatesMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(first)); - tour.addActivity(ServiceActivity.newInstance(second)); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(third).build(); states.informInsertionStarts(Arrays.asList(route), null); - InsertionData iData = serviceInsertion.getInsertionData(route, third, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); + InsertionData iData = serviceInsertion.getInsertionData(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); assertEquals(0.0, iData.getInsertionCost(), 0.2); assertEquals(1, iData.getDeliveryInsertionIndex()); } @Test public void whenInsertingThirdJobWithNewVehicle_itCalculatesMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(first)); - tour.addActivity(ServiceActivity.newInstance(second)); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(third).build(); states.informInsertionStarts(Arrays.asList(route), null); - InsertionData iData = serviceInsertion.getInsertionData(route, third, newVehicle, newVehicle.getEarliestDeparture(), null, Double.MAX_VALUE); - assertEquals(20.0, iData.getInsertionCost(), 0.2); + InsertionData iData = serviceInsertion.getInsertionData(route, second, newVehicle, newVehicle.getEarliestDeparture(), null, Double.MAX_VALUE); + assertEquals(40.0, iData.getInsertionCost(), 0.2); assertEquals(1, iData.getDeliveryInsertionIndex()); } @Test public void whenInsertingASecondJobWithAVehicle_itCalculatesLocalMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(first)); - tour.addActivity(ServiceActivity.newInstance(third)); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(second).build(); states.informInsertionStarts(Arrays.asList(route), null); - InsertionData iData = serviceInsertion.getInsertionData(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); + InsertionData iData = serviceInsertion.getInsertionData(route, third, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); assertEquals(0.0, iData.getInsertionCost(), 0.2); assertEquals(2, iData.getDeliveryInsertionIndex()); } @Test public void whenInsertingASecondJobWithANewVehicle_itCalculatesLocalMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(first)); - tour.addActivity(ServiceActivity.newInstance(third)); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); -// route.addActivity(states.getActivity(first,true)); -// route.addActivity(states.getActivity(third,true)); + + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(second).build(); + states.informInsertionStarts(Arrays.asList(route), null); - InsertionData iData = serviceInsertion.getInsertionData(route, second, newVehicle, newVehicle.getEarliestDeparture(), null, Double.MAX_VALUE); - assertEquals(20.0, iData.getInsertionCost(), 0.2); + InsertionData iData = serviceInsertion.getInsertionData(route, third, newVehicle, newVehicle.getEarliestDeparture(), null, Double.MAX_VALUE); + assertEquals(50.0, iData.getInsertionCost(), 0.2); assertEquals(2, iData.getDeliveryInsertionIndex()); } + @Test + public void whenInsertingJobAndCurrRouteIsEmpty_accessEggressCalcShouldReturnZero(){ + VehicleRoute route = VehicleRoute.Builder.newInstance(VehicleImpl.createNoVehicle(), DriverImpl.noDriver()).build(); + AdditionalAccessEgressCalculator accessEgressCalc = new AdditionalAccessEgressCalculator(costs); + Job job = Service.Builder.newInstance("1", 0).setLocationId("1").setTimeWindow(TimeWindow.newInstance(0.0, 100.0)).build(); + JobInsertionContext iContex = new JobInsertionContext(route, job, newVehicle, mock(Driver.class), 0.0); + assertEquals(0.0, accessEgressCalc.getCosts(iContex),0.01); + } + @Test + public void whenInsertingJobAndCurrRouteAndVehicleHaveTheSameLocation_accessEggressCalcShouldReturnZero(){ + VehicleRoute route = VehicleRoute.Builder.newInstance(newVehicle, DriverImpl.noDriver()) + .addService(first) + .build(); + + AdditionalAccessEgressCalculator accessEgressCalc = new AdditionalAccessEgressCalculator(costs); + JobInsertionContext iContex = new JobInsertionContext(route, first, newVehicle, mock(Driver.class), 0.0); + assertEquals(0.0, accessEgressCalc.getCosts(iContex),0.01); + } + @Test + public void whenInsertingJobAndCurrRouteAndNewVehicleHaveDifferentLocations_accessEggressCostsMustBeCorrect(){ + final Map coords = new HashMap(); + coords.put("oldV", Coordinate.newInstance(1, 0)); + coords.put("newV", Coordinate.newInstance(5, 0)); + coords.put("service", Coordinate.newInstance(0, 0)); + + AbstractForwardVehicleRoutingTransportCosts routingCosts = new AbstractForwardVehicleRoutingTransportCosts() { + + @Override + public double getTransportTime(String fromId, String toId,double departureTime, Driver driver, Vehicle vehicle) { + return getTransportCost(fromId, toId, departureTime, driver, vehicle); + } + + @Override + public double getTransportCost(String fromId, String toId,double departureTime, Driver driver, Vehicle vehicle) { + return EuclideanDistanceCalculator.calculateDistance(coords.get(fromId), coords.get(toId)); + } + }; + Vehicle oldVehicle = VehicleImpl.Builder.newInstance("oldV").setStartLocationId("oldV").build(); + + VehicleRoute route = VehicleRoute.Builder.newInstance(oldVehicle, DriverImpl.noDriver()) + .addService(Service.Builder.newInstance("service", 0).setLocationId("service").build()) + .build(); + + Vehicle newVehicle = VehicleImpl.Builder.newInstance("newV").setStartLocationId("newV").build(); + + AdditionalAccessEgressCalculator accessEgressCalc = new AdditionalAccessEgressCalculator(routingCosts); + Job job = Service.Builder.newInstance("service2", 0).setLocationId("service").build(); + JobInsertionContext iContex = new JobInsertionContext(route, job, newVehicle, mock(Driver.class), 0.0); + assertEquals(8.0, accessEgressCalc.getCosts(iContex),0.01); + } } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java index b8e45474..02d2119a 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestCalculatesServiceInsertionOnRouteLevel.java @@ -79,14 +79,16 @@ public class TestCalculatesServiceInsertionOnRouteLevel { costs = mock(VehicleRoutingTransportCosts.class); vehicle = mock(Vehicle.class); when(vehicle.getCapacity()).thenReturn(1000); - when(vehicle.getLocationId()).thenReturn("0,0"); + when(vehicle.getStartLocationId()).thenReturn("0,0"); + when(vehicle.getEndLocationId()).thenReturn("0,0"); when(vehicle.getEarliestDeparture()).thenReturn(0.0); when(vehicle.getLatestArrival()).thenReturn(100.0); when(vehicle.isReturnToDepot()).thenReturn(true); newVehicle = mock(Vehicle.class); when(newVehicle.getCapacity()).thenReturn(1000); - when(newVehicle.getLocationId()).thenReturn("0,0"); + when(newVehicle.getStartLocationId()).thenReturn("0,0"); + when(newVehicle.getEndLocationId()).thenReturn("0,0"); when(newVehicle.getEarliestDeparture()).thenReturn(0.0); when(newVehicle.getLatestArrival()).thenReturn(100.0); when(newVehicle.isReturnToDepot()).thenReturn(true); @@ -175,9 +177,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel { @Test public void whenInsertingTheFirstJobInAnEmptyTourWithVehicle_itCalculatesMarginalCostChanges(){ - TourActivities tour = new TourActivities(); - - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, first, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -191,7 +191,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel { tour.addActivity(ServiceActivity.newInstance(first)); tour.addActivity(ServiceActivity.newInstance(second)); - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(second).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, third, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -205,7 +205,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel { tour.addActivity(ServiceActivity.newInstance(first)); tour.addActivity(ServiceActivity.newInstance(second)); - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(second).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, third, newVehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -219,7 +219,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel { tour.addActivity(ServiceActivity.newInstance(first)); tour.addActivity(ServiceActivity.newInstance(third)); - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(third).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, second, vehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); @@ -233,7 +233,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel { tour.addActivity(ServiceActivity.newInstance(first)); tour.addActivity(ServiceActivity.newInstance(third)); - VehicleRoute route = VehicleRoute.newInstance(tour,driver,vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).addService(first).addService(third).build(); states.informInsertionStarts(Arrays.asList(route), null); InsertionData iData = serviceInsertion.getInsertionData(route, second, newVehicle, vehicle.getEarliestDeparture(), null, Double.MAX_VALUE); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestDepartureTimeOpt.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestDepartureTimeOpt.java index a83b58a7..2aa213e5 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestDepartureTimeOpt.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestDepartureTimeOpt.java @@ -45,7 +45,7 @@ public class TestDepartureTimeOpt { public void whenSettingOneCustWithTWAnd_NO_DepTimeChoice_totalCostsShouldBe50(){ TimeWindow timeWindow = TimeWindow.newInstance(40, 45); Service service = Service.Builder.newInstance("s", 0).setLocationId("servLoc").setCoord(Coordinate.newInstance(0, 10)).setTimeWindow(timeWindow).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("vehLoc").setLocationCoord(Coordinate.newInstance(0, 0)) + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("vehLoc").setStartLocationCoordinate(Coordinate.newInstance(0, 0)) .setType(VehicleTypeImpl.Builder.newInstance("vType", 0).build()).build(); Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); @@ -72,7 +72,7 @@ public class TestDepartureTimeOpt { public void whenSettingOneCustWithTWAnd_NO_DepTimeChoice_depTimeShouldBe0(){ TimeWindow timeWindow = TimeWindow.newInstance(40, 45); Service service = Service.Builder.newInstance("s", 0).setLocationId("servLoc").setCoord(Coordinate.newInstance(0, 10)).setTimeWindow(timeWindow).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("vehLoc").setLocationCoord(Coordinate.newInstance(0, 0)) + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("vehLoc").setStartLocationCoordinate(Coordinate.newInstance(0, 0)) .setType(VehicleTypeImpl.Builder.newInstance("vType", 0).build()).build(); Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); @@ -99,7 +99,7 @@ public class TestDepartureTimeOpt { public void whenSettingOneCustWithTWAndDepTimeChoice_totalCostsShouldBe50(){ TimeWindow timeWindow = TimeWindow.newInstance(40, 45); Service service = Service.Builder.newInstance("s", 0).setLocationId("servLoc").setCoord(Coordinate.newInstance(0, 10)).setTimeWindow(timeWindow).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("vehLoc").setLocationCoord(Coordinate.newInstance(0, 0)) + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("vehLoc").setStartLocationCoordinate(Coordinate.newInstance(0, 0)) .setType(VehicleTypeImpl.Builder.newInstance("vType", 0).build()).build(); Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); @@ -127,7 +127,7 @@ public class TestDepartureTimeOpt { public void whenSettingOneCustWithTWAndDepTimeChoice_depTimeShouldBe0(){ TimeWindow timeWindow = TimeWindow.newInstance(40, 45); Service service = Service.Builder.newInstance("s", 0).setLocationId("servLoc").setCoord(Coordinate.newInstance(0, 10)).setTimeWindow(timeWindow).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("vehLoc").setLocationCoord(Coordinate.newInstance(0, 0)) + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("vehLoc").setStartLocationCoordinate(Coordinate.newInstance(0, 0)) .setType(VehicleTypeImpl.Builder.newInstance("vType", 0).build()).build(); Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); @@ -159,7 +159,7 @@ public class TestDepartureTimeOpt { Service service2 = Service.Builder.newInstance("s2", 0).setLocationId("servLoc2").setCoord(Coordinate.newInstance(0, 20)). setTimeWindow(TimeWindow.newInstance(30, 40)).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("vehLoc").setLocationCoord(Coordinate.newInstance(0, 0)) + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("vehLoc").setStartLocationCoordinate(Coordinate.newInstance(0, 0)) .setType(VehicleTypeImpl.Builder.newInstance("vType", 0).build()).build(); Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); @@ -191,7 +191,7 @@ public class TestDepartureTimeOpt { Service service2 = Service.Builder.newInstance("s2", 0).setLocationId("servLoc2").setCoord(Coordinate.newInstance(0, 20)). setTimeWindow(TimeWindow.newInstance(30, 40)).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("vehLoc").setLocationCoord(Coordinate.newInstance(0, 0)) + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("vehLoc").setStartLocationCoordinate(Coordinate.newInstance(0, 0)) .setType(VehicleTypeImpl.Builder.newInstance("vType", 0).build()).build(); Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java index 00bbd067..74a90766 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java @@ -22,7 +22,8 @@ public class TestInserter { public void whenInsertingServiceAndRouteIsClosed_itInsertsCorrectly(){ Service service = mock(Service.class); Vehicle vehicle = mock(Vehicle.class); - when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.getStartLocationId()).thenReturn("vehLoc"); + when(vehicle.getEndLocationId()).thenReturn("vehLoc"); when(vehicle.isReturnToDepot()).thenReturn(true); when(vehicle.getId()).thenReturn("vehId"); @@ -40,14 +41,15 @@ public class TestInserter { assertEquals(2,route.getTourActivities().getActivities().size()); assertEquals(route.getTourActivities().getActivities().get(1).getLocationId(),serviceToInsert.getLocationId()); - assertEquals(route.getEnd().getLocationId(),vehicle.getLocationId()); + assertEquals(route.getEnd().getLocationId(),vehicle.getEndLocationId()); } @Test public void whenInsertingServiceAndRouteIsOpen_itInsertsCorrectlyAndSwitchesEndLocation(){ Service service = mock(Service.class); Vehicle vehicle = mock(Vehicle.class); - when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.getStartLocationId()).thenReturn("vehLoc"); + when(vehicle.getEndLocationId()).thenReturn("vehLoc"); when(vehicle.isReturnToDepot()).thenReturn(false); when(vehicle.getId()).thenReturn("vehId"); @@ -72,7 +74,8 @@ public class TestInserter { public void whenInsertingShipmentAndRouteIsClosed_itInsertsCorrectly(){ Shipment shipment = mock(Shipment.class); Vehicle vehicle = mock(Vehicle.class); - when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.getStartLocationId()).thenReturn("vehLoc"); + when(vehicle.getEndLocationId()).thenReturn("vehLoc"); when(vehicle.isReturnToDepot()).thenReturn(true); when(vehicle.getId()).thenReturn("vehId"); @@ -92,14 +95,13 @@ public class TestInserter { assertEquals(4,route.getTourActivities().getActivities().size()); assertEquals(route.getTourActivities().getActivities().get(2).getLocationId(),shipmentToInsert.getPickupLocation()); assertEquals(route.getTourActivities().getActivities().get(3).getLocationId(),shipmentToInsert.getDeliveryLocation()); - assertEquals(route.getEnd().getLocationId(),vehicle.getLocationId()); + assertEquals(route.getEnd().getLocationId(),vehicle.getEndLocationId()); } @Test public void whenInsertingShipmentAndRouteIsOpen_itInsertsCorrectlyAndSwitchesEndLocation(){ Shipment shipment = mock(Shipment.class); Vehicle vehicle = mock(Vehicle.class); - when(vehicle.getLocationId()).thenReturn("vehLoc"); when(vehicle.isReturnToDepot()).thenReturn(false); when(vehicle.getId()).thenReturn("vehId"); @@ -125,8 +127,8 @@ public class TestInserter { @Test public void whenSwitchingVehicleAndRouteIsClosed_newStartAndEndShouldBeTheLocationOfNewVehicle(){ Shipment shipment = mock(Shipment.class); - Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setLocationId("vehLoc").setType(mock(VehicleType.class)).build(); - Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setLocationId("newVehLoc").setType(mock(VehicleType.class)).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setStartLocationId("vehLoc").setType(mock(VehicleType.class)).build(); + Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setStartLocationId("newVehLoc").setType(mock(VehicleType.class)).build(); VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build(); //start - pick(shipment) - del(shipment) - end @@ -142,14 +144,14 @@ public class TestInserter { Inserter inserter = new Inserter(mock(InsertionListeners.class)); inserter.insertJob(shipmentToInsert, iData, route); - assertEquals(newVehicle.getLocationId(),route.getEnd().getLocationId()); + assertEquals(route.getEnd().getLocationId(),newVehicle.getEndLocationId()); } @Test public void whenSwitchingVehicleAndRouteIsOpen_endLocationShouldBeTheLocationOfTheLastActivity(){ Shipment shipment = mock(Shipment.class); - Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setReturnToDepot(false).setLocationId("vehLoc").setType(mock(VehicleType.class)).build(); - Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setReturnToDepot(false).setLocationId("newVehLoc").setType(mock(VehicleType.class)).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setReturnToDepot(false).setStartLocationId("vehLoc").setType(mock(VehicleType.class)).build(); + Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setReturnToDepot(false).setStartLocationId("newVehLoc").setType(mock(VehicleType.class)).build(); VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build(); //start - pick(shipment) - del(shipment) - end @@ -172,8 +174,8 @@ public class TestInserter { public void whenInsertingShipmentAtBeginningAndSwitchingVehicleAndRouteIsOpen_endLocationShouldBeTheLocationOfTheLastActivity(){ Shipment shipment = mock(Shipment.class); when(shipment.getDeliveryLocation()).thenReturn("oldShipmentDelLoc"); - Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setReturnToDepot(false).setLocationId("vehLoc").setType(mock(VehicleType.class)).build(); - Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setReturnToDepot(false).setLocationId("newVehLoc").setType(mock(VehicleType.class)).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("vehId").setReturnToDepot(false).setStartLocationId("vehLoc").setType(mock(VehicleType.class)).build(); + Vehicle newVehicle = VehicleImpl.Builder.newInstance("newVehId").setReturnToDepot(false).setStartLocationId("newVehLoc").setType(mock(VehicleType.class)).build(); VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build(); //start - pick(shipment) - del(shipment) - end diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestMixedServiceAndShipmentsProblemOnRouteLevel.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestMixedServiceAndShipmentsProblemOnRouteLevel.java index 7cbf8fa3..042901a1 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestMixedServiceAndShipmentsProblemOnRouteLevel.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestMixedServiceAndShipmentsProblemOnRouteLevel.java @@ -36,7 +36,7 @@ public class TestMixedServiceAndShipmentsProblemOnRouteLevel { * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" */ Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); + vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); vehicleBuilder.setType(vehicleType); Vehicle vehicle = vehicleBuilder.build(); @@ -101,7 +101,7 @@ public class TestMixedServiceAndShipmentsProblemOnRouteLevel { * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" */ Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); + vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); vehicleBuilder.setType(vehicleType); Vehicle vehicle = vehicleBuilder.build(); diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/state/TestTourStateUpdaterWithService.java b/jsprit-core/src/test/java/jsprit/core/algorithm/state/TestTourStateUpdaterWithService.java index 83ec3285..ed15514b 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/state/TestTourStateUpdaterWithService.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/state/TestTourStateUpdaterWithService.java @@ -59,6 +59,10 @@ public class TestTourStateUpdaterWithService { private VehicleRoute vehicleRoute; + private ServiceActivity act1; + + private ServiceActivity act2; + @Before public void setUp() { @@ -103,7 +107,7 @@ public class TestTourStateUpdaterWithService { services.add(secondService); VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("test", 10).build(); - vehicle = VehicleImpl.Builder.newInstance("testvehicle").setType(type).setLocationId("0,0") + vehicle = VehicleImpl.Builder.newInstance("testvehicle").setType(type).setStartLocationId("0,0") .setEarliestStart(0.0).setLatestArrival(50.0).build(); @@ -115,11 +119,12 @@ public class TestTourStateUpdaterWithService { states.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), states)); states.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts())); - tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(firstService)); - tour.addActivity(ServiceActivity.newInstance(secondService)); - - vehicleRoute = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),vehicle); + act1 = ServiceActivity.newInstance(firstService); + act2 = ServiceActivity.newInstance(secondService); + + vehicleRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build();//.newInstance(tour,DriverImpl.noDriver(),vehicle); + vehicleRoute.getTourActivities().addActivity(act1); + vehicleRoute.getTourActivities().addActivity(act2); } @Test @@ -133,29 +138,26 @@ public class TestTourStateUpdaterWithService { public void testStatesOfAct0(){ states.informInsertionStarts(Arrays.asList(vehicleRoute), null); assertEquals(0.0, vehicleRoute.getStart().getEndTime(),0.05); - assertEquals(vehicleRoute.getVehicle().getLocationId(), vehicleRoute.getStart().getLocationId()); + assertEquals(vehicleRoute.getVehicle().getStartLocationId(), vehicleRoute.getStart().getLocationId()); assertEquals(vehicleRoute.getVehicle().getEarliestDeparture(), vehicleRoute.getStart().getTheoreticalEarliestOperationStartTime(),0.05); - assertEquals(vehicleRoute.getVehicle().getLatestArrival(), vehicleRoute.getStart().getTheoreticalLatestOperationStartTime(),0.05); + assertEquals(Double.MAX_VALUE, vehicleRoute.getStart().getTheoreticalLatestOperationStartTime(),0.05); } @Test public void testStatesOfAct1(){ states.informInsertionStarts(Arrays.asList(vehicleRoute), null); - assertEquals(10.0, states.getActivityState(tour.getActivities().get(0), StateFactory.COSTS).toDouble(),0.05); - assertEquals(5.0, states.getActivityState(tour.getActivities().get(0), StateFactory.LOAD).toDouble(),0.05); -// assertEquals(10.0, states.getActivityState(tour.getActivities().get(0), StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); - assertEquals(20.0, states.getActivityState(tour.getActivities().get(0), StateFactory.LATEST_OPERATION_START_TIME).toDouble(),0.05); + assertEquals(10.0, states.getActivityState(act1, StateFactory.COSTS).toDouble(),0.05); + assertEquals(5.0, states.getActivityState(act1, StateFactory.LOAD).toDouble(),0.05); + assertEquals(20.0, states.getActivityState(act1, StateFactory.LATEST_OPERATION_START_TIME).toDouble(),0.05); } @Test public void testStatesOfAct2(){ states.informInsertionStarts(Arrays.asList(vehicleRoute), null); - - assertEquals(30.0, states.getActivityState(tour.getActivities().get(1), StateFactory.COSTS).toDouble(),0.05); - assertEquals(10.0, states.getActivityState(tour.getActivities().get(1), StateFactory.LOAD).toDouble(),0.05); -// assertEquals(10.0, states.getActivityState(tour.getActivities().get(0), StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); - assertEquals(40.0, states.getActivityState(tour.getActivities().get(1), StateFactory.LATEST_OPERATION_START_TIME).toDouble(),0.05); + assertEquals(30.0, states.getActivityState(act2, StateFactory.COSTS).toDouble(),0.05); + assertEquals(10.0, states.getActivityState(act2, StateFactory.LOAD).toDouble(),0.05); + assertEquals(40.0, states.getActivityState(act2, StateFactory.LATEST_OPERATION_START_TIME).toDouble(),0.05); } @Test diff --git a/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java b/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java index fb2ce5b2..0261aec2 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java @@ -66,10 +66,10 @@ public class VehicleRoutingProblemTest { public void whenBuildingWithFourVehicles_vrpShouldContainTheCorrectNuOfVehicles(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); - Vehicle v1 = mock(VehicleImpl.class); - Vehicle v2 = mock(VehicleImpl.class); - Vehicle v3 = mock(VehicleImpl.class); - Vehicle v4 = mock(VehicleImpl.class); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("start").build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("start").build(); + Vehicle v3 = VehicleImpl.Builder.newInstance("v3").setStartLocationId("start").build(); + Vehicle v4 = VehicleImpl.Builder.newInstance("v4").setStartLocationId("start").build(); builder.addVehicle(v1).addVehicle(v2).addVehicle(v3).addVehicle(v4); @@ -82,10 +82,10 @@ public class VehicleRoutingProblemTest { public void whenAddingFourVehiclesAllAtOnce_vrpShouldContainTheCorrectNuOfVehicles(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); - Vehicle v1 = mock(VehicleImpl.class); - Vehicle v2 = mock(VehicleImpl.class); - Vehicle v3 = mock(VehicleImpl.class); - Vehicle v4 = mock(VehicleImpl.class); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("start").build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("start").build(); + Vehicle v3 = VehicleImpl.Builder.newInstance("v3").setStartLocationId("start").build(); + Vehicle v4 = VehicleImpl.Builder.newInstance("v4").setStartLocationId("start").build(); builder.addAllVehicles(Arrays.asList(v1,v2,v3,v4)); @@ -101,10 +101,10 @@ public class VehicleRoutingProblemTest { VehicleTypeImpl type1 = mock(VehicleTypeImpl.class); VehicleTypeImpl type2 = mock(VehicleTypeImpl.class); - Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setLocationId("yo").setType(type1).build(); - Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setLocationId("yo").setType(type1).build(); - Vehicle v3 = VehicleImpl.Builder.newInstance("v3").setLocationId("yo").setType(type2).build(); - Vehicle v4 = VehicleImpl.Builder.newInstance("v4").setLocationId("yo").setType(type2).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("yo").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("yo").setType(type1).build(); + Vehicle v3 = VehicleImpl.Builder.newInstance("v3").setStartLocationId("yo").setType(type2).build(); + Vehicle v4 = VehicleImpl.Builder.newInstance("v4").setStartLocationId("yo").setType(type2).build(); builder.addVehicle(v1).addVehicle(v2).addVehicle(v3).addVehicle(v4); @@ -286,7 +286,7 @@ public class VehicleRoutingProblemTest { public void whenAddingAVehicle_getAddedVehicleTypesShouldReturnItsType(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(type).build(); builder.addVehicle(vehicle); assertEquals(1,builder.getAddedVehicleTypes().size()); @@ -298,8 +298,8 @@ public class VehicleRoutingProblemTest { public void whenAddingTwoVehicleWithSameType_getAddedVehicleTypesShouldReturnOnlyOneType(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build(); - Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(type).build(); + Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(type).build(); builder.addVehicle(vehicle); builder.addVehicle(vehicle2); @@ -314,8 +314,8 @@ public class VehicleRoutingProblemTest { VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build(); VehicleType type2 = VehicleTypeImpl.Builder.newInstance("type2", 0).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build(); - Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type2).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(type).build(); + Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(type2).build(); builder.addVehicle(vehicle); builder.addVehicle(vehicle2); @@ -328,7 +328,7 @@ public class VehicleRoutingProblemTest { public void whenSettingAddPenaltyVehicleOptions_itShouldAddPenaltyVehicle(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(type).build(); builder.addVehicle(vehicle); builder.setFleetSize(FleetSize.FINITE); @@ -350,7 +350,7 @@ public class VehicleRoutingProblemTest { public void whenSettingAddPenaltyVehicleOptionsAndFleetSizeIsInfinite_noPenaltyVehicleIsAdded(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(type).build(); builder.addVehicle(vehicle); builder.addPenaltyVehicles(3.0); @@ -371,8 +371,8 @@ public class VehicleRoutingProblemTest { public void whenSettingAddPenaltyVehicleOptionsAndTwoVehiclesWithSameLocationAndType_onlyOnePenaltyVehicleIsAdded(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build(); - Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc").setType(type).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(type).build(); + Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type).build(); builder.addVehicle(vehicle); builder.addVehicle(vehicle2); @@ -395,8 +395,8 @@ public class VehicleRoutingProblemTest { public void whenSettingAddPenaltyVehicleOptionsWithAbsoluteFixedCostsAndTwoVehiclesWithSameLocationAndType_onePenaltyVehicleIsAddedWithTheCorrectPenaltyFixedCosts(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build(); - Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc").setType(type).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(type).build(); + Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type).build(); builder.addVehicle(vehicle); builder.addVehicle(vehicle2); @@ -421,8 +421,8 @@ public class VehicleRoutingProblemTest { public void whenSettingAddPenaltyVehicleOptionsAndTwoVehiclesWithDiffLocationAndType_twoPenaltyVehicleIsAdded(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build(); - Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc2").setType(type).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(type).build(); + Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc2").setType(type).build(); builder.addVehicle(vehicle); builder.addVehicle(vehicle2); @@ -449,8 +449,8 @@ public class VehicleRoutingProblemTest { VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build(); VehicleType type2 = VehicleTypeImpl.Builder.newInstance("type2", 0).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build(); - Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc").setType(type2).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(type).build(); + Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); builder.addVehicle(vehicle); builder.addVehicle(vehicle2); @@ -471,4 +471,22 @@ public class VehicleRoutingProblemTest { assertTrue(anotherPenVehInCollection); } + + @Test + public void whenAddingVehicleWithDiffStartAndEnd_startLocationMustBeRegisteredInLocationMap(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("end").build(); + + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addVehicle(vehicle); + assertTrue(vrpBuilder.getLocationMap().containsKey("start")); + } + + @Test + public void whenAddingVehicleWithDiffStartAndEnd_endLocationMustBeRegisteredInLocationMap(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("end").build(); + + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addVehicle(vehicle); + assertTrue(vrpBuilder.getLocationMap().containsKey("end")); + } } diff --git a/jsprit-core/src/test/java/jsprit/core/problem/constraint/SoftActivityConstraintManagerTest.java b/jsprit-core/src/test/java/jsprit/core/problem/constraint/SoftActivityConstraintManagerTest.java new file mode 100644 index 00000000..2f8b486f --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/problem/constraint/SoftActivityConstraintManagerTest.java @@ -0,0 +1,50 @@ +package jsprit.core.problem.constraint; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.route.activity.TourActivity; + +import org.junit.Test; + +public class SoftActivityConstraintManagerTest { + + @Test + public void whenAddingSoftConstraint_managerShouldHaveIt(){ + SoftActivityConstraint c = mock(SoftActivityConstraint.class); + SoftActivityConstraintManager man = new SoftActivityConstraintManager(); + assertEquals(0,man.getConstraints().size()); + man.addConstraint(c); + assertEquals(1,man.getConstraints().size()); + } + + @Test + public void whenAddingTwoSoftConstraints_managerShouldHaveIt(){ + SoftActivityConstraint c1 = mock(SoftActivityConstraint.class); + SoftActivityConstraint c2 = mock(SoftActivityConstraint.class); + SoftActivityConstraintManager man = new SoftActivityConstraintManager(); + assertEquals(0,man.getConstraints().size()); + man.addConstraint(c1); + man.addConstraint(c2); + assertEquals(2,man.getConstraints().size()); + } + + @Test + public void whenAddingTwoSoftConstrainta_managerShouldSumCostsCorrectly(){ + SoftActivityConstraint c1 = mock(SoftActivityConstraint.class); + JobInsertionContext iContext = mock(JobInsertionContext.class); + TourActivity act_i = mock(TourActivity.class); + TourActivity act_k = mock(TourActivity.class); + TourActivity act_j = mock(TourActivity.class); + when(c1.getCosts(iContext,act_i,act_k,act_j,0.0)).thenReturn(1.0); + SoftActivityConstraint c2 = mock(SoftActivityConstraint.class); + when(c2.getCosts(iContext,act_i,act_k,act_j,0.0)).thenReturn(2.0); + + SoftActivityConstraintManager man = new SoftActivityConstraintManager(); + + man.addConstraint(c1); + man.addConstraint(c2); + assertEquals(3.0,man.getCosts(iContext,act_i,act_k,act_j,0.0),0.01); + } +} diff --git a/jsprit-core/src/test/java/jsprit/core/problem/constraint/SoftRouteConstraintManagerTest.java b/jsprit-core/src/test/java/jsprit/core/problem/constraint/SoftRouteConstraintManagerTest.java new file mode 100644 index 00000000..75dab6b6 --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/problem/constraint/SoftRouteConstraintManagerTest.java @@ -0,0 +1,46 @@ +package jsprit.core.problem.constraint; + +import jsprit.core.problem.misc.JobInsertionContext; + +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class SoftRouteConstraintManagerTest { + + @Test + public void whenAddingSoftRouteConstraint_managerShouldHaveIt(){ + SoftRouteConstraint c = mock(SoftRouteConstraint.class); + SoftRouteConstraintManager man = new SoftRouteConstraintManager(); + assertEquals(0,man.getConstraints().size()); + man.addConstraint(c); + assertEquals(1,man.getConstraints().size()); + } + + @Test + public void whenAddingTwoSoftRouteConstraint_managerShouldHaveIt(){ + SoftRouteConstraint c1 = mock(SoftRouteConstraint.class); + SoftRouteConstraint c2 = mock(SoftRouteConstraint.class); + SoftRouteConstraintManager man = new SoftRouteConstraintManager(); + assertEquals(0,man.getConstraints().size()); + man.addConstraint(c1); + man.addConstraint(c2); + assertEquals(2,man.getConstraints().size()); + } + + @Test + public void whenAddingTwoSoftRouteConstraint_managerShouldSumCostsCorrectly(){ + SoftRouteConstraint c1 = mock(SoftRouteConstraint.class); + JobInsertionContext iContext = mock(JobInsertionContext.class); + when(c1.getCosts(iContext)).thenReturn(1.0); + SoftRouteConstraint c2 = mock(SoftRouteConstraint.class); + when(c2.getCosts(iContext)).thenReturn(2.0); + SoftRouteConstraintManager man = new SoftRouteConstraintManager(); + + man.addConstraint(c1); + man.addConstraint(c2); + assertEquals(3.0,man.getCosts(iContext),0.01); + } +} diff --git a/jsprit-core/src/test/java/jsprit/core/problem/constraint/TestConstraintManager.java b/jsprit-core/src/test/java/jsprit/core/problem/constraint/TestConstraintManager.java index 58c55f22..6f8ec250 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/constraint/TestConstraintManager.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/constraint/TestConstraintManager.java @@ -1,6 +1,6 @@ package jsprit.core.problem.constraint; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import java.util.ArrayList; @@ -30,5 +30,45 @@ public class TestConstraintManager { ConstraintManager cManager = new ConstraintManager(mock(VehicleRoutingProblem.class),mock(RouteAndActivityStateGetter.class),constraints); assertEquals(1,cManager.getConstraints().size()); } + + @Test + public void whenAddingSoftRouteConstraint_managerShouldHaveIt(){ + SoftRouteConstraint c = mock(SoftRouteConstraint.class); + ConstraintManager man = new ConstraintManager(mock(VehicleRoutingProblem.class),mock(RouteAndActivityStateGetter.class)); + assertEquals(0,man.getConstraints().size()); + man.addConstraint(c); + assertEquals(1,man.getConstraints().size()); + } + + @Test + public void whenAddingTwoSoftRouteConstraint_managerShouldHaveIt(){ + SoftRouteConstraint c1 = mock(SoftRouteConstraint.class); + SoftRouteConstraint c2 = mock(SoftRouteConstraint.class); + ConstraintManager man = new ConstraintManager(mock(VehicleRoutingProblem.class),mock(RouteAndActivityStateGetter.class)); + assertEquals(0,man.getConstraints().size()); + man.addConstraint(c1); + man.addConstraint(c2); + assertEquals(2,man.getConstraints().size()); + } + + @Test + public void whenAddingSoftActivityConstraint_managerShouldHaveIt(){ + SoftActivityConstraint c = mock(SoftActivityConstraint.class); + ConstraintManager man = new ConstraintManager(mock(VehicleRoutingProblem.class),mock(RouteAndActivityStateGetter.class)); + assertEquals(0,man.getConstraints().size()); + man.addConstraint(c); + assertEquals(1,man.getConstraints().size()); + } + + @Test + public void whenAddingTwoSoftActivityConstraints_managerShouldHaveIt(){ + SoftActivityConstraint c1 = mock(SoftActivityConstraint.class); + SoftActivityConstraint c2 = mock(SoftActivityConstraint.class); + ConstraintManager man = new ConstraintManager(mock(VehicleRoutingProblem.class),mock(RouteAndActivityStateGetter.class)); + assertEquals(0,man.getConstraints().size()); + man.addConstraint(c1); + man.addConstraint(c2); + assertEquals(2,man.getConstraints().size()); + } } diff --git a/jsprit-core/src/test/java/jsprit/core/problem/io/VrpReaderV2Test.java b/jsprit-core/src/test/java/jsprit/core/problem/io/VrpReaderV2Test.java index 152b772c..19f29541 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/io/VrpReaderV2Test.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/io/VrpReaderV2Test.java @@ -17,6 +17,7 @@ package jsprit.core.problem.io; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -58,7 +59,7 @@ public class VrpReaderV2Test { VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); new VrpXMLReader(builder, null).read(inFileName); VehicleRoutingProblem vrp = builder.build(); - assertEquals(2,vrp.getVehicles().size()); + assertEquals(4,vrp.getVehicles().size()); assertTrue(idsInCollection(Arrays.asList("v1","v2"),vrp.getVehicles())); } @@ -69,9 +70,9 @@ public class VrpReaderV2Test { VehicleRoutingProblem vrp = builder.build(); Vehicle v1 = getVehicle("v1",vrp.getVehicles()); assertEquals(20,v1.getCapacity()); - assertEquals(100.0,v1.getCoord().getX(),0.01); + assertEquals(100.0,v1.getStartLocationCoordinate().getX(),0.01); assertEquals(0.0,v1.getEarliestDeparture(),0.01); - assertEquals("depotLoc2",v1.getLocationId()); + assertEquals("depotLoc2",v1.getStartLocationId()); assertNotNull(v1.getType()); assertEquals("vehType", v1.getType().getTypeId()); assertEquals(1000.0,v1.getLatestArrival(),0.01); @@ -175,7 +176,128 @@ public class VrpReaderV2Test { assertEquals("service",s1.getType()); } + @Test + public void whenReadingFile_v2MustNotReturnToDepot(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v = getVehicle("v2",vrp.getVehicles()); + assertFalse(v.isReturnToDepot()); + } + @Test + public void whenReadingFile_v3HasTheCorrectStartLocation(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v3 = getVehicle("v3",vrp.getVehicles()); + assertEquals("startLoc",v3.getStartLocationId()); + } + + @Test + public void whenReadingFile_v3HasTheCorrectEndLocation(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v3 = getVehicle("v3",vrp.getVehicles()); + assertEquals("endLoc",v3.getEndLocationId()); + } + + @Test + public void whenReadingFile_v3HasTheCorrectEndLocationCoordinate(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v3 = getVehicle("v3",vrp.getVehicles()); + assertEquals(1000.0,v3.getEndLocationCoordinate().getX(),0.01); + assertEquals(2000.0,v3.getEndLocationCoordinate().getY(),0.01); + } + + @Test + public void whenReadingFile_v3HasTheCorrectStartLocationCoordinate(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v3 = getVehicle("v3",vrp.getVehicles()); + assertEquals(10.0,v3.getStartLocationCoordinate().getX(),0.01); + assertEquals(100.0,v3.getStartLocationCoordinate().getY(),0.01); + } + + @Test + public void whenReadingFile_v3HasTheCorrectLocationCoordinate(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v3 = getVehicle("v3",vrp.getVehicles()); + assertEquals(10.0,v3.getStartLocationCoordinate().getX(),0.01); + assertEquals(100.0,v3.getStartLocationCoordinate().getY(),0.01); + } + + @Test + public void whenReadingFile_v3HasTheCorrectLocationId(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v3 = getVehicle("v3",vrp.getVehicles()); + assertEquals("startLoc",v3.getStartLocationId()); + } + + @Test + public void whenReadingFile_v4HasTheCorrectStartLocation(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v = getVehicle("v4",vrp.getVehicles()); + assertEquals("startLoc",v.getStartLocationId()); + } + + @Test + public void whenReadingFile_v4HasTheCorrectEndLocation(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v = getVehicle("v4",vrp.getVehicles()); + assertEquals("endLoc",v.getEndLocationId()); + } + + @Test + public void whenReadingFile_v4HasTheCorrectEndLocationCoordinate(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v = getVehicle("v4",vrp.getVehicles()); + assertEquals(1000.0,v.getEndLocationCoordinate().getX(),0.01); + assertEquals(2000.0,v.getEndLocationCoordinate().getY(),0.01); + } + + @Test + public void whenReadingFile_v4HasTheCorrectStartLocationCoordinate(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v = getVehicle("v4",vrp.getVehicles()); + assertEquals(10.0,v.getStartLocationCoordinate().getX(),0.01); + assertEquals(100.0,v.getStartLocationCoordinate().getY(),0.01); + } + + @Test + public void whenReadingFile_v4HasTheCorrectLocationCoordinate(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v = getVehicle("v4",vrp.getVehicles()); + assertEquals(10.0,v.getStartLocationCoordinate().getX(),0.01); + assertEquals(100.0,v.getStartLocationCoordinate().getY(),0.01); + } + + @Test + public void whenReadingFile_v4HasTheCorrectLocationId(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder, null).read(inFileName); + VehicleRoutingProblem vrp = builder.build(); + Vehicle v = getVehicle("v4",vrp.getVehicles()); + assertEquals("startLoc",v.getStartLocationId()); + } @Test public void whenReadingJobs_capOfShipment3IsReadCorrectly(){ diff --git a/jsprit-core/src/test/java/jsprit/core/problem/io/VrpWriterV2Test.java b/jsprit-core/src/test/java/jsprit/core/problem/io/VrpWriterV2Test.java index 631a0225..6954f1ed 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/io/VrpWriterV2Test.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/io/VrpWriterV2Test.java @@ -17,13 +17,20 @@ package jsprit.core.problem.io; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.util.Collection; + import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem.Builder; import jsprit.core.problem.VehicleRoutingProblem.FleetSize; import jsprit.core.problem.job.Service; +import jsprit.core.problem.job.Shipment; +import jsprit.core.problem.solution.route.activity.TimeWindow; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl; import jsprit.core.problem.vehicle.VehicleTypeImpl; +import jsprit.core.util.Coordinate; import org.junit.Before; import org.junit.Test; @@ -43,13 +50,8 @@ public class VrpWriterV2Test { public void whenWritingInfiniteVrp_itWritesCorrectly(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); builder.setFleetSize(FleetSize.INFINITE); -// Depot depot = new Depot("depotLoc",Coordinate.newInstance(0, 0)); -// Depot depot2 = new Depot("depotLoc2",Coordinate.newInstance(100, 100)); -// builder.addDepot(depot2); -// builder.assignVehicleType(depot, VehicleType.Builder.newInstance("vehType", 20).build()); -// builder.assignVehicleType(depot, VehicleType.Builder.newInstance("vehType2", 200).build()); VehicleTypeImpl type = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("myVehicle").setLocationId("loc").setType(type).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("myVehicle").setStartLocationId("loc").setType(type).build(); builder.addVehicle(vehicle); VehicleRoutingProblem vrp = builder.build(); new VrpXMLWriter(vrp, null).write(infileName); @@ -59,13 +61,10 @@ public class VrpWriterV2Test { public void whenWritingFiniteVrp_itWritesCorrectly(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); builder.setFleetSize(FleetSize.FINITE); -// Depot depot = new Depot("depotLoc",Coordinate.newInstance(0, 0)); -// Depot depot2 = new Depot("depotLoc2",Coordinate.newInstance(100, 100)); -// builder.addDepot(depot2); VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); - Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setLocationId("loc").setType(type1).build(); - Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc").setType(type2).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); builder.addVehicle(v1); builder.addVehicle(v2); VehicleRoutingProblem vrp = builder.build(); @@ -76,13 +75,10 @@ public class VrpWriterV2Test { public void t(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); builder.setFleetSize(FleetSize.FINITE); -// Depot depot = new Depot("depotLoc",Coordinate.newInstance(0, 0)); -// Depot depot2 = new Depot("depotLoc2",Coordinate.newInstance(100, 100)); -// builder.addDepot(depot2); VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); - Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setLocationId("loc").setType(type1).build(); - Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc").setType(type2).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); builder.addVehicle(v1); builder.addVehicle(v2); VehicleRoutingProblem vrp = builder.build(); @@ -98,8 +94,8 @@ public class VrpWriterV2Test { VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); - Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setLocationId("loc").setType(type1).build(); - Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc").setType(type2).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); builder.addVehicle(v1); builder.addVehicle(v2); @@ -122,6 +118,364 @@ public class VrpWriterV2Test { assertEquals(2.0,s1_read.getServiceDuration(),0.01); } + @Test + public void whenWritingShipments_readingThemAgainMustReturnTheWrittenLocationIdsOfS1(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Shipment s1 = Shipment.Builder.newInstance("1", 10).setPickupLocation("pickLoc").setDeliveryLocation("delLoc").setPickupTimeWindow(TimeWindow.newInstance(1, 2)) + .setDeliveryTimeWindow(TimeWindow.newInstance(3, 4)).build(); + Shipment s2 = Shipment.Builder.newInstance("2", 20).setPickupLocation("pickLocation").setDeliveryLocation("delLocation").setPickupTimeWindow(TimeWindow.newInstance(5, 6)) + .setDeliveryTimeWindow(TimeWindow.newInstance(7, 8)).build(); + + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + assertEquals(2,readVrp.getJobs().size()); + + assertEquals("pickLoc",((Shipment)readVrp.getJobs().get("1")).getPickupLocation()); + assertEquals("delLoc",((Shipment)readVrp.getJobs().get("1")).getDeliveryLocation()); + + } + + @Test + public void whenWritingShipments_readingThemAgainMustReturnTheWrittenPickupTimeWindowsOfS1(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Shipment s1 = Shipment.Builder.newInstance("1", 10).setPickupLocation("pickLoc").setDeliveryLocation("delLoc").setPickupTimeWindow(TimeWindow.newInstance(1, 2)) + .setDeliveryTimeWindow(TimeWindow.newInstance(3, 4)).build(); + Shipment s2 = Shipment.Builder.newInstance("2", 20).setPickupLocation("pickLocation").setDeliveryLocation("delLocation").setPickupTimeWindow(TimeWindow.newInstance(5, 6)) + .setDeliveryTimeWindow(TimeWindow.newInstance(7, 8)).build(); + + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + assertEquals(2,readVrp.getJobs().size()); + + assertEquals(1.0,((Shipment)readVrp.getJobs().get("1")).getPickupTimeWindow().getStart(),0.01); + assertEquals(2.0,((Shipment)readVrp.getJobs().get("1")).getPickupTimeWindow().getEnd(),0.01); + + + } + + @Test + public void whenWritingShipments_readingThemAgainMustReturnTheWrittenDeliveryTimeWindowsOfS1(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Shipment s1 = Shipment.Builder.newInstance("1", 10).setPickupLocation("pickLoc").setDeliveryLocation("delLoc").setPickupTimeWindow(TimeWindow.newInstance(1, 2)) + .setDeliveryTimeWindow(TimeWindow.newInstance(3, 4)).build(); + Shipment s2 = Shipment.Builder.newInstance("2", 20).setPickupLocation("pickLocation").setDeliveryLocation("delLocation").setPickupTimeWindow(TimeWindow.newInstance(5, 6)) + .setDeliveryTimeWindow(TimeWindow.newInstance(7, 8)).build(); + + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + assertEquals(2,readVrp.getJobs().size()); + + assertEquals(3.0,((Shipment)readVrp.getJobs().get("1")).getDeliveryTimeWindow().getStart(),0.01); + assertEquals(4.0,((Shipment)readVrp.getJobs().get("1")).getDeliveryTimeWindow().getEnd(),0.01); + + } + + @Test + public void whenWritingShipments_readingThemAgainMustReturnTheWrittenDeliveryServiceTimeOfS1(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Shipment s1 = Shipment.Builder.newInstance("1", 10).setPickupLocation("pickLoc").setDeliveryLocation("delLoc").setPickupTimeWindow(TimeWindow.newInstance(1, 2)) + .setDeliveryTimeWindow(TimeWindow.newInstance(3, 4)).setPickupServiceTime(100).setDeliveryServiceTime(50).build(); + Shipment s2 = Shipment.Builder.newInstance("2", 20).setPickupLocation("pickLocation").setDeliveryLocation("delLocation").setPickupTimeWindow(TimeWindow.newInstance(5, 6)) + .setDeliveryTimeWindow(TimeWindow.newInstance(7, 8)).build(); + + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + assertEquals(2,readVrp.getJobs().size()); + + assertEquals(100.0,((Shipment)readVrp.getJobs().get("1")).getPickupServiceTime(),0.01); + assertEquals(50.0,((Shipment)readVrp.getJobs().get("1")).getDeliveryServiceTime(),0.01); + + } + + @Test + public void whenWritingShipments_readingThemAgainMustReturnTheWrittenLocationIdOfS1(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Shipment s1 = Shipment.Builder.newInstance("1", 10).setPickupCoord(Coordinate.newInstance(1, 2)).setDeliveryLocation("delLoc").setPickupTimeWindow(TimeWindow.newInstance(1, 2)) + .setDeliveryTimeWindow(TimeWindow.newInstance(3, 4)).setPickupServiceTime(100).setDeliveryServiceTime(50).build(); + Shipment s2 = Shipment.Builder.newInstance("2", 20).setPickupLocation("pickLocation").setDeliveryLocation("delLocation").setPickupTimeWindow(TimeWindow.newInstance(5, 6)) + .setDeliveryTimeWindow(TimeWindow.newInstance(7, 8)).build(); + + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + assertEquals(2,readVrp.getJobs().size()); + + assertEquals("[x=1.0][y=2.0]",((Shipment)readVrp.getJobs().get("1")).getPickupLocation()); + } + + @Test + public void whenWritingShipments_readingThemAgainMustReturnTheWrittenLocationCoordOfS1(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Shipment s1 = Shipment.Builder.newInstance("1", 10).setPickupCoord(Coordinate.newInstance(1, 2)).setDeliveryCoord(Coordinate.newInstance(5, 6)).setDeliveryLocation("delLoc").setPickupTimeWindow(TimeWindow.newInstance(1, 2)) + .setDeliveryTimeWindow(TimeWindow.newInstance(3, 4)).setPickupServiceTime(100).setDeliveryServiceTime(50).build(); + Shipment s2 = Shipment.Builder.newInstance("2", 20).setPickupLocation("pickLocation").setDeliveryLocation("delLocation").setPickupTimeWindow(TimeWindow.newInstance(5, 6)) + .setDeliveryTimeWindow(TimeWindow.newInstance(7, 8)).build(); + + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + assertEquals(2,readVrp.getJobs().size()); + + assertEquals(1.0,((Shipment)readVrp.getJobs().get("1")).getPickupCoord().getX(),0.01); + assertEquals(2.0,((Shipment)readVrp.getJobs().get("1")).getPickupCoord().getY(),0.01); + + assertEquals(5.0,((Shipment)readVrp.getJobs().get("1")).getDeliveryCoord().getX(),0.01); + assertEquals(6.0,((Shipment)readVrp.getJobs().get("1")).getDeliveryCoord().getY(),0.01); + } + + @Test + public void whenWritingVehicleV1_itsStartLocationMustBeWrittenCorrectly(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build(); + Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build(); + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + + Vehicle v = getVehicle("v1",readVrp.getVehicles()); + assertEquals("loc",v.getStartLocationId()); + assertEquals("loc",v.getEndLocationId()); + + } + + @Test + public void whenWritingVehicleV1_itDoesNotReturnToDepotMustBeWrittenCorrectly(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setReturnToDepot(false).setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build(); + Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build(); + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + + Vehicle v = getVehicle("v1",readVrp.getVehicles()); + assertFalse(v.isReturnToDepot()); + } + + @Test + public void whenWritingVehicleV1_readingAgainAssignsCorrectType(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setReturnToDepot(false).setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build(); + Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build(); + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + + Vehicle v = getVehicle("v1",readVrp.getVehicles()); + assertEquals("vehType",v.getType().getTypeId()); + } + + @Test + public void whenWritingVehicleV2_readingAgainAssignsCorrectType(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setReturnToDepot(false).setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("loc").setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build(); + Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build(); + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + + Vehicle v = getVehicle("v2",readVrp.getVehicles()); + assertEquals("vehType2",v.getType().getTypeId()); + assertEquals(200,v.getType().getCapacity()); + + } + + @Test + public void whenWritingVehicleV2_readingItsLocationsAgainReturnsCorrectLocations(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setReturnToDepot(false).setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("startLoc").setStartLocationCoordinate(Coordinate.newInstance(1, 2)) + .setEndLocationId("endLoc").setEndLocationCoordinate(Coordinate.newInstance(4, 5)).setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build(); + Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build(); + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + + Vehicle v = getVehicle("v2",readVrp.getVehicles()); + assertEquals("startLoc",v.getStartLocationId()); + assertEquals("endLoc",v.getEndLocationId()); + } + + @Test + public void whenWritingVehicleV2_readingItsLocationsCoordsAgainReturnsCorrectLocationsCoords(){ + Builder builder = VehicleRoutingProblem.Builder.newInstance(); + + VehicleTypeImpl type1 = VehicleTypeImpl.Builder.newInstance("vehType", 20).build(); + VehicleTypeImpl type2 = VehicleTypeImpl.Builder.newInstance("vehType2", 200).build(); + Vehicle v1 = VehicleImpl.Builder.newInstance("v1").setReturnToDepot(false).setStartLocationId("loc").setType(type1).build(); + Vehicle v2 = VehicleImpl.Builder.newInstance("v2").setStartLocationId("startLoc").setStartLocationCoordinate(Coordinate.newInstance(1, 2)) + .setEndLocationId("endLoc").setEndLocationCoordinate(Coordinate.newInstance(4, 5)).setType(type2).build(); + + builder.addVehicle(v1); + builder.addVehicle(v2); + + Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build(); + Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build(); + + VehicleRoutingProblem vrp = builder.addJob(s1).addJob(s2).build(); + new VrpXMLWriter(vrp, null).write(infileName); + + VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(vrpToReadBuilder, null).read(infileName); + VehicleRoutingProblem readVrp = vrpToReadBuilder.build(); + + Vehicle v = getVehicle("v2",readVrp.getVehicles()); + assertEquals(1.0,v.getStartLocationCoordinate().getX(),0.01); + assertEquals(2.0,v.getStartLocationCoordinate().getY(),0.01); + + assertEquals(4.0,v.getEndLocationCoordinate().getX(),0.01); + assertEquals(5.0,v.getEndLocationCoordinate().getY(),0.01); + } + + private Vehicle getVehicle(String string, Collection vehicles) { + for(Vehicle v : vehicles) if(string.equals(v.getId())) return v; + return null; + } } diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/TestVehicleRoute.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/TestVehicleRoute.java index afa57d79..44307d44 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/TestVehicleRoute.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/TestVehicleRoute.java @@ -24,10 +24,7 @@ import java.util.Iterator; import jsprit.core.problem.driver.DriverImpl; import jsprit.core.problem.driver.DriverImpl.NoDriver; import jsprit.core.problem.job.Service; -import jsprit.core.problem.solution.route.VehicleRoute; import jsprit.core.problem.solution.route.activity.ServiceActivity; -import jsprit.core.problem.solution.route.activity.Start; -import jsprit.core.problem.solution.route.activity.TourActivities; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl; @@ -44,15 +41,13 @@ public class TestVehicleRoute { @Before public void doBefore(){ - vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(VehicleTypeImpl.Builder.newInstance("yo", 0).build()).build(); + vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("loc").setType(VehicleTypeImpl.Builder.newInstance("yo", 0).build()).build(); driver = DriverImpl.noDriver(); } - - - + @Test public void whenBuildingEmptyRouteCorrectly_go(){ - VehicleRoute route = VehicleRoute.newInstance(TourActivities.emptyTour(),DriverImpl.noDriver(),VehicleImpl.createNoVehicle()); + VehicleRoute route = VehicleRoute.Builder.newInstance(VehicleImpl.createNoVehicle(),DriverImpl.noDriver()).build(); assertTrue(route!=null); } @@ -74,56 +69,17 @@ public class TestVehicleRoute { assertEquals(0,count); } - @Test(expected=IllegalStateException.class) - public void whenBuildingEmptyRoute_(){ + @Test(expected=IllegalArgumentException.class) + public void whenBuildingRouteWithNulls_itThrowsException(){ @SuppressWarnings("unused") - VehicleRoute route = VehicleRoute.newInstance(null,null,null); + VehicleRoute route = VehicleRoute.Builder.newInstance(null, null).build(); } - @Test(expected=IllegalStateException.class) - public void whenBuildingRouteWithNonEmptyTour_throwException(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("jo", 10).build())); - @SuppressWarnings("unused") - VehicleRoute route = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),VehicleImpl.createNoVehicle()); - } - - @Test - public void whenBuildingEmptyTour_tourIterIteratesOverAnEmptyList(){ - TourActivities tour = new TourActivities(); - Vehicle v = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(VehicleTypeImpl.Builder.newInstance("yo", 0).build()).build(); - VehicleRoute route = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),v); - Iterator iter = route.getTourActivities().iterator(); - int count = 0; - while(iter.hasNext()){ - @SuppressWarnings("unused") - TourActivity act = iter.next(); - count++; - } - assertEquals(0,count); - } - - @Test - public void whenBuildingANonEmptyTour_tourIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(Start.newInstance("", 0, 0)); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); - Iterator iter = route.getTourActivities().iterator(); - int count = 0; - while(iter.hasNext()){ - @SuppressWarnings("unused") - TourActivity act = iter.next(); - count++; - } - assertEquals(1,count); - } - - @Test public void whenBuildingANonEmptyTour2Times_tourIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("2", 30).setLocationId("1").build())); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); + VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle, driver); + routeBuilder.addService(Service.Builder.newInstance("2", 30).setLocationId("1").build()); + VehicleRoute route = routeBuilder.build(); { Iterator iter = route.getTourActivities().iterator(); @@ -136,7 +92,7 @@ public class TestVehicleRoute { assertEquals(1,count); } { - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("3", 30).setLocationId("1").build())); + route.getTourActivities().addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("3", 30).setLocationId("1").build())); Iterator iter = route.getTourActivities().iterator(); int count = 0; while(iter.hasNext()){ @@ -150,8 +106,7 @@ public class TestVehicleRoute { @Test public void whenBuildingANonEmptyTour_tourReverseIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, driver).build(); Iterator iter = route.getTourActivities().reverseActivityIterator(); int count = 0; while(iter.hasNext()){ @@ -164,9 +119,9 @@ public class TestVehicleRoute { @Test public void whenBuildingANonEmptyTourV2_tourReverseIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("2", 30).setLocationId("1").build())); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); + VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle, driver); + routeBuilder.addService(Service.Builder.newInstance("2", 30).setLocationId("1").build()); + VehicleRoute route = routeBuilder.build(); Iterator iter = route.getTourActivities().reverseActivityIterator(); int count = 0; while(iter.hasNext()){ @@ -177,74 +132,162 @@ public class TestVehicleRoute { assertEquals(1,count); } - @Test - public void whenBuildingANonEmptyTourV3_tourReverseIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("2", 30).setLocationId("1").build())); - ServiceActivity del = ServiceActivity.newInstance(Service.Builder.newInstance("3", 30).setLocationId("1").build()); - tour.addActivity(del); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); - Iterator iter = route.getTourActivities().reverseActivityIterator(); - int count = 0; - TourActivity memAct = null; - while(iter.hasNext()){ - TourActivity act = iter.next(); - if(count==0) memAct = act; - count++; - } - assertEquals(memAct,del); - } - - @Test - public void whenBuildingANonEmptyTourV4_tourReverseIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("2", 30).setLocationId("1").build())); - ServiceActivity del = ServiceActivity.newInstance(Service.Builder.newInstance("3", 30).setLocationId("1").build()); - tour.addActivity(del); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); - Iterator iter = route.getTourActivities().reverseActivityIterator(); - int count = 0; - TourActivity memAct = null; - while(iter.hasNext()){ - TourActivity act = iter.next(); - if(count==0) memAct = act; - count++; - } - assertEquals(memAct,del); - assertEquals(2,count); - } - @Test public void whenBuildingANonEmptyTour2Times_tourReverseIterIteratesOverActivitiesCorrectly(){ - TourActivities tour = new TourActivities(); - tour.addActivity(ServiceActivity.newInstance(Service.Builder.newInstance("2", 30).setLocationId("1").build())); - ServiceActivity del = ServiceActivity.newInstance(Service.Builder.newInstance("3", 30).setLocationId("1").build()); - tour.addActivity(del); - VehicleRoute route = VehicleRoute.newInstance(tour, driver, vehicle); + VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle, driver); + routeBuilder.addService(Service.Builder.newInstance("2", 30).setLocationId("1").build()); + routeBuilder.addService(Service.Builder.newInstance("3", 30).setLocationId("2").build()); + VehicleRoute route = routeBuilder.build(); { Iterator iter = route.getTourActivities().reverseActivityIterator(); int count = 0; - TourActivity memAct = null; while(iter.hasNext()){ TourActivity act = iter.next(); - if(count==0) memAct = act; + if(count==0) { + assertEquals("2",act.getLocationId()); + } count++; } - assertEquals(memAct,del); assertEquals(2,count); } { Iterator secondIter = route.getTourActivities().reverseActivityIterator(); int count = 0; - TourActivity memAct = null; while(secondIter.hasNext()){ TourActivity act = secondIter.next(); - if(count==0) memAct = act; + if(count==0) { + assertEquals("2",act.getLocationId()); + } count++; } - assertEquals(memAct,del); assertEquals(2,count); } } + + @Test + public void whenBuildingRouteWithVehicleThatHasDifferentStartAndEndLocation_routeMustHaveCorrectStartLocation(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getStart().getLocationId().equals("start")); + } + + @Test + public void whenBuildingRouteWithVehicleThatHasDifferentStartAndEndLocation_routeMustHaveCorrectEndLocation(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getEnd().getLocationId().equals("end")); + } + + @Test + public void whenBuildingRouteWithVehicleThatHasSameStartAndEndLocation_routeMustHaveCorrectStartLocation(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("start").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getStart().getLocationId().equals("start")); + } + + @Test + public void whenBuildingRouteWithVehicleThatHasSameStartAndEndLocation_routeMustHaveCorrectEndLocation(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("start").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getEnd().getLocationId().equals("start")); + } + + @Test + public void whenBuildingRouteWithVehicleThatHasSameStartAndEndLocation_routeMustHaveCorrectStartLocationV2(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("start").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getStart().getLocationId().equals("start")); + } + + @Test + public void whenBuildingRouteWithVehicleThatHasSameStartAndEndLocation_routeMustHaveCorrectEndLocationV2(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("start").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertTrue(vRoute.getEnd().getLocationId().equals("start")); + } + + @Test + public void whenBuildingRouteWithVehicleThatHasDifferentStartAndEndLocation_routeMustHaveCorrectDepartureTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertEquals(vRoute.getDepartureTime(),100.0,0.01); + assertEquals(vRoute.getStart().getEndTime(),100.0,0.01); + } + + @Test + public void whenBuildingRouteWithVehicleThatHasDifferentStartAndEndLocation_routeMustHaveCorrectEndTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + assertEquals(200.0,vRoute.getEnd().getTheoreticalLatestOperationStartTime(),0.01); + } + + @Test + public void whenSettingDepartureTimeInBetweenEarliestStartAndLatestArr_routeMustHaveCorrectDepartureTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(vehicle, 150.0); + assertEquals(vRoute.getStart().getEndTime(),150.0,0.01); + assertEquals(vRoute.getDepartureTime(),150.0,0.01); + } + + @Test + public void whenSettingDepartureEarlierThanEarliestStart_routeMustHaveEarliestDepTimeAsDepTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(vehicle, 50.0); + assertEquals(vRoute.getStart().getEndTime(),100.0,0.01); + assertEquals(vRoute.getDepartureTime(),100.0,0.01); + } + + @Test + public void whenSettingDepartureTimeLaterThanLatestArrival_routeMustHaveThisDepTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(vehicle, 50.0); + assertEquals(vRoute.getStart().getEndTime(),100.0,0.01); + assertEquals(vRoute.getDepartureTime(),100.0,0.01); + } + + @Test + public void whenCreatingEmptyRoute_itMustReturnEmptyRoute(){ + @SuppressWarnings("unused") + VehicleRoute route = VehicleRoute.emptyRoute(); + assertTrue(true); + } + + @Test + public void whenIniRouteWithNewVehicle_startLocationMustBeCorrect(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + Vehicle new_vehicle = VehicleImpl.Builder.newInstance("new_v").setEarliestStart(1000).setLatestArrival(2000).setStartLocationId("new_start").setEndLocationId("new_end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(new_vehicle, 50.0); + assertEquals("new_start",vRoute.getStart().getLocationId()); + } + + @Test + public void whenIniRouteWithNewVehicle_endLocationMustBeCorrect(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + Vehicle new_vehicle = VehicleImpl.Builder.newInstance("new_v").setEarliestStart(1000).setLatestArrival(2000).setStartLocationId("new_start").setEndLocationId("new_end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(new_vehicle, 50.0); + assertEquals("new_end",vRoute.getEnd().getLocationId()); + } + @Test + public void whenIniRouteWithNewVehicle_depTimeMustBeEarliestDepTimeOfNewVehicle(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + Vehicle new_vehicle = VehicleImpl.Builder.newInstance("new_v").setEarliestStart(1000).setLatestArrival(2000).setStartLocationId("new_start").setEndLocationId("new_end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(new_vehicle, 50.0); + assertEquals(1000.0,vRoute.getDepartureTime(),0.01); + } + + @Test + public void whenIniRouteWithNewVehicle_depTimeMustBeSetDepTime(){ + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setEarliestStart(100).setLatestArrival(200).setStartLocationId("start").setEndLocationId("end").build(); + Vehicle new_vehicle = VehicleImpl.Builder.newInstance("new_v").setEarliestStart(1000).setLatestArrival(2000).setStartLocationId("new_start").setEndLocationId("new_end").build(); + VehicleRoute vRoute = VehicleRoute.Builder.newInstance(vehicle, DriverImpl.noDriver()).build(); + vRoute.setVehicleAndDepartureTime(new_vehicle, 1500.0); + assertEquals(1500.0,vRoute.getDepartureTime(),0.01); + } } diff --git a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java index 3a584e17..389527a7 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/solution/route/VehicleRouteBuilderTest.java @@ -65,14 +65,15 @@ public class VehicleRouteBuilderTest { Shipment s2 = mock(Shipment.class); Vehicle vehicle = mock(Vehicle.class); when(vehicle.isReturnToDepot()).thenReturn(true); - when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.getStartLocationId()).thenReturn("vehLoc"); + when(vehicle.getEndLocationId()).thenReturn("vehLoc"); VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)); builder.addPickup(s); builder.addPickup(s2); builder.addDelivery(s); builder.addDelivery(s2); VehicleRoute route = builder.build(); - assertEquals(route.getEnd().getLocationId(), vehicle.getLocationId()); + assertEquals("vehLoc",route.getEnd().getLocationId()); } @Test @@ -82,7 +83,7 @@ public class VehicleRouteBuilderTest { when(s2.getDeliveryLocation()).thenReturn("delLoc"); Vehicle vehicle = mock(Vehicle.class); when(vehicle.isReturnToDepot()).thenReturn(false); - when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.getStartLocationId()).thenReturn("vehLoc"); VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)); builder.addPickup(s); builder.addPickup(s2); @@ -99,7 +100,7 @@ public class VehicleRouteBuilderTest { when(s2.getDeliveryLocation()).thenReturn("delLoc"); Vehicle vehicle = mock(Vehicle.class); when(vehicle.isReturnToDepot()).thenReturn(false); - when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.getStartLocationId()).thenReturn("vehLoc"); VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)); builder.addPickup(s); builder.addPickup(s2); @@ -119,7 +120,8 @@ public class VehicleRouteBuilderTest { when(s2.getDeliveryLocation()).thenReturn("delLoc"); Vehicle vehicle = mock(Vehicle.class); when(vehicle.isReturnToDepot()).thenReturn(false); - when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.getStartLocationId()).thenReturn("vehLoc"); + when(vehicle.getLatestArrival()).thenReturn(200.0); VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)); builder.addPickup(s); builder.addPickup(s2); diff --git a/jsprit-core/src/test/java/jsprit/core/problem/vehicle/TestVehicleFleetManagerImpl.java b/jsprit-core/src/test/java/jsprit/core/problem/vehicle/TestVehicleFleetManagerImpl.java index 6833be64..7a2800c6 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/vehicle/TestVehicleFleetManagerImpl.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/vehicle/TestVehicleFleetManagerImpl.java @@ -39,8 +39,8 @@ public class TestVehicleFleetManagerImpl extends TestCase{ public void setUp(){ List vehicles = new ArrayList(); - v1 = VehicleImpl.Builder.newInstance("standard").setLocationId("loc").setType(VehicleTypeImpl.Builder.newInstance("standard", 0).build()).build(); - v2 = VehicleImpl.Builder.newInstance("foo").setLocationId("fooLoc").setType(VehicleTypeImpl.Builder.newInstance("foo", 0).build()).build(); + v1 = VehicleImpl.Builder.newInstance("standard").setStartLocationId("loc").setType(VehicleTypeImpl.Builder.newInstance("standard", 0).build()).build(); + v2 = VehicleImpl.Builder.newInstance("foo").setStartLocationId("fooLoc").setType(VehicleTypeImpl.Builder.newInstance("foo", 0).build()).build(); // v1. vehicles.add(v1); @@ -75,7 +75,7 @@ public class TestVehicleFleetManagerImpl extends TestCase{ } public void testGetVehiclesWithout(){ - Collection vehicles = fleetManager.getAvailableVehicles(v1.getType().getTypeId(),v1.getLocationId()); + Collection vehicles = fleetManager.getAvailableVehicles(v1); assertEquals(v2, vehicles.iterator().next()); assertEquals(1, vehicles.size()); @@ -91,7 +91,7 @@ public class TestVehicleFleetManagerImpl extends TestCase{ } public void testWithPenalty_whenHavingOneRegularVehicleAvailable_noPenaltyVehicleIsReturn(){ - Vehicle penalty4standard = VehicleImpl.Builder.newInstance("standard_penalty").setLocationId("loc"). + Vehicle penalty4standard = VehicleImpl.Builder.newInstance("standard_penalty").setStartLocationId("loc"). setType(VehicleTypeImpl.Builder.newInstance("standard", 0).build()).build(); List vehicles = new ArrayList(); @@ -108,10 +108,10 @@ public class TestVehicleFleetManagerImpl extends TestCase{ VehicleTypeImpl penaltyType = VehicleTypeImpl.Builder.newInstance("standard", 0).build(); PenaltyVehicleType penaltyVehicleType = new PenaltyVehicleType(penaltyType); - Vehicle penalty4standard = VehicleImpl.Builder.newInstance("standard_penalty").setLocationId("loc"). + Vehicle penalty4standard = VehicleImpl.Builder.newInstance("standard_penalty").setStartLocationId("loc"). setType(penaltyVehicleType).build(); - Vehicle v3 = VehicleImpl.Builder.newInstance("standard_v3").setLocationId("loc"). + Vehicle v3 = VehicleImpl.Builder.newInstance("standard_v3").setStartLocationId("loc"). setType(penaltyType).build(); List vehicles = new ArrayList(); @@ -130,7 +130,7 @@ public class TestVehicleFleetManagerImpl extends TestCase{ public void testWithPenalty_whenHavingNoRegularVehicleAvailable_penaltyVehicleIsReturned(){ VehicleTypeImpl penaltyType = VehicleTypeImpl.Builder.newInstance("standard", 0).build(); - Vehicle penalty4standard = VehicleImpl.Builder.newInstance("standard_penalty").setLocationId("loc"). + Vehicle penalty4standard = VehicleImpl.Builder.newInstance("standard_penalty").setStartLocationId("loc"). setType(penaltyType).build(); List vehicles = new ArrayList(); diff --git a/jsprit-core/src/test/java/jsprit/core/problem/vehicle/VehicleImplTest.java b/jsprit-core/src/test/java/jsprit/core/problem/vehicle/VehicleImplTest.java index 2876946a..ef48238f 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/vehicle/VehicleImplTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/vehicle/VehicleImplTest.java @@ -8,7 +8,7 @@ import jsprit.core.util.Coordinate; import org.junit.Test; - +@SuppressWarnings("deprecation") // still tests whether deprecated methods work correctly - if deprecated methods are removed entirely, shift to setStartLocationId(..) and setStartLocationCoordinate() public class VehicleImplTest { @Test @@ -98,5 +98,105 @@ public class VehicleImplTest { assertTrue(v instanceof NoVehicle); assertEquals("noVehicle",v.getId()); } + + @Test + public void whenStartLocationIsSet_itIsDoneCorrectly(){ + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationId("startLoc").build(); + assertEquals("startLoc", v.getLocationId()); + assertEquals("startLoc", v.getStartLocationId()); + } + + @Test(expected=IllegalArgumentException.class) + public void whenStartLocationIsNull_itThrowsException(){ + @SuppressWarnings("unused") + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationId(null).build(); + } + + @Test + public void whenStartLocationCoordIsSet_itIsDoneCorrectly(){ + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationCoordinate(Coordinate.newInstance(1, 2)).build(); + assertEquals(1.0, v.getStartLocationCoordinate().getX(),0.01); + assertEquals(2.0, v.getStartLocationCoordinate().getY(),0.01); + + assertEquals(1.0, v.getCoord().getX(),0.01); + assertEquals(2.0, v.getCoord().getY(),0.01); + } + + @Test + public void whenEndLocationIsSet_itIsDoneCorrectly(){ + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationId("startLoc").setEndLocationId("endLoc").build(); + assertEquals("startLoc", v.getStartLocationId()); + assertEquals("endLoc", v.getEndLocationId()); + } + + @Test + public void whenEndLocationCoordIsSet_itIsDoneCorrectly(){ + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationId("startLoc").setEndLocationCoordinate(Coordinate.newInstance(1, 2)).build(); + assertEquals(1.0, v.getEndLocationCoordinate().getX(),0.01); + assertEquals(2.0, v.getEndLocationCoordinate().getY(),0.01); + } + + + @Test + public void whenNeitherEndLocationIdNorEndLocationCoordAreSet_endLocationIdMustBeEqualToStartLocationId(){ + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationId("startLoc").build(); + assertEquals("startLoc", v.getEndLocationId()); + } + + @Test + public void whenNeitherEndLocationIdNorEndLocationCoordAreSet_endLocationCoordMustBeEqualToStartLocationCoord(){ + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationId("startLoc").build(); + assertEquals(v.getEndLocationCoordinate(), v.getStartLocationCoordinate()); + } + + @Test + public void whenNeitherEndLocationIdNorEndLocationCoordAreSet_endLocationCoordMustBeEqualToStartLocationCoordV2(){ + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationCoordinate(Coordinate.newInstance(1.0, 2.0)).build(); + assertEquals(v.getEndLocationCoordinate(), v.getStartLocationCoordinate()); + } + + @Test + public void whenEndLocationCoordinateIsSetButNoId_idMustBeCoordToString(){ + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationCoordinate(Coordinate.newInstance(1.0, 2.0)).setEndLocationCoordinate(Coordinate.newInstance(3.0, 4.0)).build(); + assertEquals(v.getEndLocationCoordinate().toString(), v.getEndLocationId()); + } + + @Test(expected=IllegalStateException.class) + public void whenEndLocationIdIsSpecifiedANDReturnToDepotIsFalse_itShouldThrowException(){ + @SuppressWarnings("unused") + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationCoordinate(Coordinate.newInstance(1.0, 2.0)).setEndLocationId("endLoc").setReturnToDepot(false).build(); + } + + @Test(expected=IllegalStateException.class) + public void whenEndLocationCoordIsSpecifiedANDReturnToDepotIsFalse_itShouldThrowException(){ + @SuppressWarnings("unused") + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationCoordinate(Coordinate.newInstance(1.0, 2.0)).setEndLocationCoordinate(Coordinate.newInstance(3, 4)).setReturnToDepot(false).build(); + } + + @Test + public void whenEndLocationCoordIsNotSpecifiedANDReturnToDepotIsFalse_endLocationCoordMustBeStartLocationCoord(){ + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationCoordinate(Coordinate.newInstance(1.0, 2.0)).setReturnToDepot(false).build(); + assertEquals(v.getStartLocationCoordinate(),v.getEndLocationCoordinate()); + } + + @Test + public void whenEndLocationIdIsNotSpecifiedANDReturnToDepotIsFalse_endLocationIdMustBeStartLocationId(){ + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationCoordinate(Coordinate.newInstance(1.0, 2.0)).setReturnToDepot(false).build(); + assertEquals(v.getStartLocationCoordinate().toString(),v.getEndLocationId()); + } + + @Test(expected=IllegalStateException.class) + public void whenStartAndEndAreUnequalANDReturnToDepotIsFalse_itShouldThrowException(){ + @SuppressWarnings("unused") + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("end").setReturnToDepot(false).build(); + } + + @Test + public void whenStartAndEndAreEqualANDReturnToDepotIsFalse_itShouldThrowException(){ + @SuppressWarnings("unused") + Vehicle v = VehicleImpl.Builder.newInstance("v").setStartLocationId("start").setEndLocationId("start").setReturnToDepot(false).build(); + assertTrue(true); + } + } diff --git a/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml b/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml index d38fa774..6a1b7236 100644 --- a/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml +++ b/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml @@ -46,6 +46,39 @@ depotLoc + false + vehType2 + + 0.0 + 1000.0 + + + + v3 + + startLoc + + + + endLoc + + + vehType2 + + 0.0 + 1000.0 + + + + v4 + + startLoc + + + + endLoc + + vehType2 0.0 diff --git a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml index 4d5bf129..11e1b5cf 100644 --- a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml +++ b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml @@ -9,21 +9,29 @@ v1 vehType - + loc - + + + loc + 0.0 1.7976931348623157E308 - true + false v2 vehType2 - - loc - + + startLoc + + + + endLoc + + 0.0 1.7976931348623157E308 diff --git a/jsprit-examples/input/algorithmConfig.xml b/jsprit-examples/input/algorithmConfig.xml index 410727cd..917e27bd 100755 --- a/jsprit-examples/input/algorithmConfig.xml +++ b/jsprit-examples/input/algorithmConfig.xml @@ -26,7 +26,7 @@ - route + @@ -35,8 +35,10 @@ - - + + 0.05 + 20 + @@ -51,7 +53,7 @@ - + @@ -67,7 +69,7 @@ - + diff --git a/jsprit-examples/input/algorithmConfig_fix.xml b/jsprit-examples/input/algorithmConfig_fix.xml index b7ffdd9c..7d01a4f3 100755 --- a/jsprit-examples/input/algorithmConfig_fix.xml +++ b/jsprit-examples/input/algorithmConfig_fix.xml @@ -7,7 +7,7 @@ - 1.0 + true diff --git a/jsprit-examples/input/algorithmConfig_fix_schrimpf.xml b/jsprit-examples/input/algorithmConfig_fix_schrimpf.xml new file mode 100755 index 00000000..ab7f6d05 --- /dev/null +++ b/jsprit-examples/input/algorithmConfig_fix_schrimpf.xml @@ -0,0 +1,52 @@ + + + + + 2000 + + + + true + + + + + 1 + + + + + + 0.05 + 20 + + + + + 0.5 + + + + + 0.5 + + + + + + + + + 0.3 + + + + + 0.5 + + + + + + diff --git a/jsprit-examples/input/algorithmConfig_open.xml b/jsprit-examples/input/algorithmConfig_open.xml index 25c78f00..031f78f0 100755 --- a/jsprit-examples/input/algorithmConfig_open.xml +++ b/jsprit-examples/input/algorithmConfig_open.xml @@ -22,11 +22,11 @@ - 1000 + 20000 - false + true @@ -36,8 +36,8 @@ - 0.1 - 40 + 0.05 + 20 @@ -56,7 +56,7 @@ - + 0.3 diff --git a/jsprit-examples/input/deliveries_solomon_specifiedVehicleEndLocations_c101.xml b/jsprit-examples/input/deliveries_solomon_specifiedVehicleEndLocations_c101.xml new file mode 100644 index 00000000..da1e27ce --- /dev/null +++ b/jsprit-examples/input/deliveries_solomon_specifiedVehicleEndLocations_c101.xml @@ -0,0 +1,1240 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 101 + + + + 0.0 + 1236.0 + + true + + + + + solomonType + 200 + + 1000.0 + 1.0 + + + + + + + [x=5.0][y=35.0] + + 10 + 90.0 + + + 283.0 + 344.0 + + + + + [x=5.0][y=45.0] + + 10 + 90.0 + + + 665.0 + 716.0 + + + + + [x=8.0][y=40.0] + + 40 + 90.0 + + + 87.0 + 158.0 + + + + + [x=8.0][y=45.0] + + 20 + 90.0 + + + 751.0 + 816.0 + + + + + [x=0.0][y=45.0] + + 20 + 90.0 + + + 567.0 + 624.0 + + + + + [x=2.0][y=40.0] + + 20 + 90.0 + + + 383.0 + 434.0 + + + + + [x=0.0][y=40.0] + + 30 + 90.0 + + + 479.0 + 522.0 + + + + + [x=33.0][y=35.0] + + 10 + 90.0 + + + 16.0 + 80.0 + + + + + [x=33.0][y=32.0] + + 20 + 90.0 + + + 68.0 + 149.0 + + + + + [x=35.0][y=32.0] + + 10 + 90.0 + + + 166.0 + 235.0 + + + + + [x=35.0][y=30.0] + + 10 + 90.0 + + + 264.0 + 321.0 + + + + + [x=28.0][y=52.0] + + 20 + 90.0 + + + 812.0 + 883.0 + + + + + [x=28.0][y=55.0] + + 10 + 90.0 + + + 732.0 + 777.0 + + + + + [x=25.0][y=50.0] + + 10 + 90.0 + + + 65.0 + 144.0 + + + + + [x=25.0][y=52.0] + + 40 + 90.0 + + + 169.0 + 224.0 + + + + + [x=25.0][y=55.0] + + 10 + 90.0 + + + 622.0 + 701.0 + + + + + [x=23.0][y=52.0] + + 10 + 90.0 + + + 261.0 + 316.0 + + + + + [x=23.0][y=55.0] + + 20 + 90.0 + + + 546.0 + 593.0 + + + + + [x=20.0][y=50.0] + + 10 + 90.0 + + + 358.0 + 405.0 + + + + + [x=42.0][y=66.0] + + 10 + 90.0 + + + 65.0 + 146.0 + + + + + [x=45.0][y=70.0] + + 30 + 90.0 + + + 825.0 + 870.0 + + + + + [x=45.0][y=68.0] + + 10 + 90.0 + + + 912.0 + 967.0 + + + + + [x=20.0][y=55.0] + + 10 + 90.0 + + + 449.0 + 504.0 + + + + + [x=40.0][y=66.0] + + 20 + 90.0 + + + 170.0 + 225.0 + + + + + [x=40.0][y=69.0] + + 20 + 90.0 + + + 621.0 + 702.0 + + + + + [x=42.0][y=65.0] + + 10 + 90.0 + + + 15.0 + 67.0 + + + + + [x=10.0][y=40.0] + + 30 + 90.0 + + + 31.0 + 100.0 + + + + + [x=42.0][y=68.0] + + 10 + 90.0 + + + 727.0 + 782.0 + + + + + [x=10.0][y=35.0] + + 20 + 90.0 + + + 200.0 + 237.0 + + + + + [x=38.0][y=70.0] + + 10 + 90.0 + + + 534.0 + 605.0 + + + + + [x=38.0][y=68.0] + + 20 + 90.0 + + + 255.0 + 324.0 + + + + + [x=15.0][y=80.0] + + 10 + 90.0 + + + 278.0 + 345.0 + + + + + [x=18.0][y=75.0] + + 20 + 90.0 + + + 99.0 + 148.0 + + + + + [x=15.0][y=75.0] + + 20 + 90.0 + + + 179.0 + 254.0 + + + + + [x=20.0][y=80.0] + + 40 + 90.0 + + + 384.0 + 429.0 + + + + + [x=20.0][y=85.0] + + 40 + 90.0 + + + 475.0 + 528.0 + + + + + [x=22.0][y=75.0] + + 30 + 90.0 + + + 30.0 + 92.0 + + + + + [x=22.0][y=85.0] + + 10 + 90.0 + + + 567.0 + 620.0 + + + + + [x=35.0][y=69.0] + + 10 + 90.0 + + + 448.0 + 505.0 + + + + + [x=25.0][y=85.0] + + 20 + 90.0 + + + 652.0 + 721.0 + + + + + [x=30.0][y=52.0] + + 20 + 90.0 + + + 914.0 + 965.0 + + + + + [x=30.0][y=50.0] + + 10 + 90.0 + + + 10.0 + 73.0 + + + + + [x=55.0][y=80.0] + + 10 + 90.0 + + + 743.0 + 820.0 + + + + + [x=55.0][y=85.0] + + 20 + 90.0 + + + 647.0 + 726.0 + + + + + [x=58.0][y=75.0] + + 20 + 90.0 + + + 30.0 + 84.0 + + + + + [x=60.0][y=85.0] + + 30 + 90.0 + + + 561.0 + 622.0 + + + + + [x=60.0][y=80.0] + + 10 + 90.0 + + + 95.0 + 156.0 + + + + + [x=62.0][y=80.0] + + 30 + 90.0 + + + 196.0 + 239.0 + + + + + [x=65.0][y=82.0] + + 10 + 90.0 + + + 285.0 + 336.0 + + + + + [x=65.0][y=85.0] + + 40 + 90.0 + + + 475.0 + 518.0 + + + + + [x=67.0][y=85.0] + + 20 + 90.0 + + + 368.0 + 441.0 + + + + + [x=60.0][y=60.0] + + 10 + 90.0 + + + 836.0 + 889.0 + + + + + [x=60.0][y=55.0] + + 10 + 90.0 + + + 20.0 + 84.0 + + + + + [x=35.0][y=66.0] + + 10 + 90.0 + + + 357.0 + 410.0 + + + + + [x=65.0][y=60.0] + + 30 + 90.0 + + + 645.0 + 708.0 + + + + + [x=63.0][y=58.0] + + 10 + 90.0 + + + 737.0 + 802.0 + + + + + [x=87.0][y=30.0] + + 10 + 90.0 + + + 668.0 + 731.0 + + + + + [x=88.0][y=35.0] + + 20 + 90.0 + + + 109.0 + 170.0 + + + + + [x=88.0][y=30.0] + + 10 + 90.0 + + + 574.0 + 643.0 + + + + + [x=75.0][y=55.0] + + 20 + 90.0 + + + 369.0 + 420.0 + + + + + [x=72.0][y=55.0] + + 10 + 90.0 + + + 265.0 + 338.0 + + + + + [x=85.0][y=25.0] + + 10 + 90.0 + + + 769.0 + 820.0 + + + + + [x=85.0][y=35.0] + + 30 + 90.0 + + + 47.0 + 124.0 + + + + + [x=66.0][y=55.0] + + 10 + 90.0 + + + 173.0 + 238.0 + + + + + [x=65.0][y=55.0] + + 20 + 90.0 + + + 85.0 + 144.0 + + + + + [x=70.0][y=58.0] + + 20 + 90.0 + + + 458.0 + 523.0 + + + + + [x=68.0][y=60.0] + + 30 + 90.0 + + + 555.0 + 612.0 + + + + + [x=47.0][y=40.0] + + 10 + 90.0 + + + 12.0 + 77.0 + + + + + [x=47.0][y=35.0] + + 10 + 90.0 + + + 826.0 + 875.0 + + + + + [x=45.0][y=35.0] + + 10 + 90.0 + + + 916.0 + 969.0 + + + + + [x=45.0][y=30.0] + + 10 + 90.0 + + + 734.0 + 777.0 + + + + + [x=95.0][y=30.0] + + 30 + 90.0 + + + 387.0 + 456.0 + + + + + [x=95.0][y=35.0] + + 20 + 90.0 + + + 293.0 + 360.0 + + + + + [x=53.0][y=30.0] + + 10 + 90.0 + + + 450.0 + 505.0 + + + + + [x=92.0][y=30.0] + + 10 + 90.0 + + + 478.0 + 551.0 + + + + + [x=53.0][y=35.0] + + 50 + 90.0 + + + 353.0 + 412.0 + + + + + [x=45.0][y=65.0] + + 20 + 90.0 + + + 997.0 + 1068.0 + + + + + [x=90.0][y=35.0] + + 10 + 90.0 + + + 203.0 + 260.0 + + + + + [x=38.0][y=15.0] + + 10 + 90.0 + + + 651.0 + 740.0 + + + + + [x=38.0][y=5.0] + + 30 + 90.0 + + + 471.0 + 534.0 + + + + + [x=40.0][y=15.0] + + 40 + 90.0 + + + 35.0 + 87.0 + + + + + [x=40.0][y=5.0] + + 30 + 90.0 + + + 385.0 + 436.0 + + + + + [x=42.0][y=15.0] + + 10 + 90.0 + + + 95.0 + 158.0 + + + + + [x=48.0][y=30.0] + + 10 + 90.0 + + + 632.0 + 693.0 + + + + + [x=48.0][y=40.0] + + 10 + 90.0 + + + 76.0 + 129.0 + + + + + [x=50.0][y=35.0] + + 20 + 90.0 + + + 262.0 + 317.0 + + + + + [x=50.0][y=40.0] + + 50 + 90.0 + + + 171.0 + 218.0 + + + + + [x=35.0][y=5.0] + + 20 + 90.0 + + + 562.0 + 629.0 + + + + + [x=50.0][y=30.0] + + 10 + 90.0 + + + 531.0 + 610.0 + + + + + [x=28.0][y=35.0] + + 10 + 90.0 + + + 1001.0 + 1066.0 + + + + + [x=28.0][y=30.0] + + 10 + 90.0 + + + 632.0 + 693.0 + + + + + [x=30.0][y=30.0] + + 10 + 90.0 + + + 541.0 + 600.0 + + + + + [x=32.0][y=30.0] + + 10 + 90.0 + + + 359.0 + 412.0 + + + + + [x=30.0][y=35.0] + + 10 + 90.0 + + + 1054.0 + 1127.0 + + + + + [x=30.0][y=32.0] + + 30 + 90.0 + + + 448.0 + 509.0 + + + + + [x=25.0][y=30.0] + + 10 + 90.0 + + + 725.0 + 786.0 + + + + + [x=25.0][y=35.0] + + 10 + 90.0 + + + 912.0 + 969.0 + + + + + [x=44.0][y=5.0] + + 20 + 90.0 + + + 286.0 + 347.0 + + + + + [x=42.0][y=10.0] + + 40 + 90.0 + + + 186.0 + 257.0 + + + + + [x=26.0][y=32.0] + + 10 + 90.0 + + + 815.0 + 880.0 + + + + + diff --git a/jsprit-examples/input/pickups_and_deliveries_solomon_c101_withoutTWs_and_specifiedVehicleEndLocations.xml b/jsprit-examples/input/pickups_and_deliveries_solomon_c101_withoutTWs_and_specifiedVehicleEndLocations.xml new file mode 100644 index 00000000..e13eeccd --- /dev/null +++ b/jsprit-examples/input/pickups_and_deliveries_solomon_c101_withoutTWs_and_specifiedVehicleEndLocations.xml @@ -0,0 +1,1239 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 101 + + + + 0.0 + 1236.0 + + + + + + solomonType + 200 + + 500.0 + 1.0 + + + + + + + [x=5.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=45.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=40.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=45.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=0.0][y=45.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=2.0][y=40.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=0.0][y=40.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=33.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=33.0][y=32.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=32.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=52.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=50.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=52.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=23.0][y=52.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=23.0][y=55.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=50.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=66.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=70.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=68.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=66.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=69.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=65.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=40.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=68.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=35.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=70.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=68.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=80.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=18.0][y=75.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=75.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=80.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=85.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=22.0][y=75.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=22.0][y=85.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=69.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=85.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=52.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=50.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=80.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=85.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=58.0][y=75.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=85.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=80.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=62.0][y=80.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=82.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=85.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=67.0][y=85.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=60.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=66.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=60.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=63.0][y=58.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=87.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=88.0][y=35.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=88.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=75.0][y=55.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=72.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=85.0][y=25.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=85.0][y=35.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=66.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=55.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=70.0][y=58.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=68.0][y=60.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=47.0][y=40.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=47.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=95.0][y=30.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=95.0][y=35.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=92.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=35.0] + + 50 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=65.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=90.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=15.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=5.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=15.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=5.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=15.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=48.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=48.0][y=40.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=50.0][y=35.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=50.0][y=40.0] + + 50 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=5.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=50.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=32.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=44.0][y=5.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=10.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=32.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + diff --git a/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java b/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java index 8ee6c648..1268654a 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java +++ b/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java @@ -8,6 +8,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; +import jsprit.analysis.toolbox.AlgorithmSearchProgressChartListener; import jsprit.analysis.toolbox.GraphStreamViewer; import jsprit.analysis.toolbox.GraphStreamViewer.Label; import jsprit.analysis.toolbox.Plotter; @@ -226,7 +227,7 @@ public class BicycleMessenger { problemBuilder.addConstraint(new ThreeTimesLessThanBestDirectRouteConstraint(nearestMessengers, routingCosts, stateManager)); problemBuilder.addConstraint(new IgnoreMessengerThatCanNeverMeetTimeRequirements(nearestMessengers, routingCosts)); - problemBuilder.addPenaltyVehicles(10.0,50000); + problemBuilder.addPenaltyVehicles(20.0,50000); //finally build the problem VehicleRoutingProblem bicycleMessengerProblem = problemBuilder.build(); @@ -238,8 +239,8 @@ public class BicycleMessenger { VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(bicycleMessengerProblem,"input/algorithmConfig_open.xml", stateManager); //if you want, terminate it after 1000 iterations with no change // algorithm.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(1000)); -// algorithm.addListener(new AlgorithmSearchProgressChartListener("output/progress.png")); - algorithm.setNuOfIterations(200); + algorithm.addListener(new AlgorithmSearchProgressChartListener("output/progress.png")); +// algorithm.setNuOfIterations(2000); Collection solutions = algorithm.searchSolutions(); //this is just to ensure that solution meet the above constraints @@ -303,7 +304,7 @@ public class BicycleMessenger { static double getTimeOfDirectRoute(Job job, Vehicle v, VehicleRoutingTransportCosts routingCosts) { Shipment envelope = (Shipment) job; - double direct = routingCosts.getTransportTime(v.getLocationId(), envelope.getPickupLocation(), 0.0, DriverImpl.noDriver(), v) + + double direct = routingCosts.getTransportTime(v.getStartLocationId(), envelope.getPickupLocation(), 0.0, DriverImpl.noDriver(), v) + routingCosts.getTransportTime(envelope.getPickupLocation(), envelope.getDeliveryLocation(), 0.0, DriverImpl.noDriver(), v); return direct; } @@ -341,7 +342,7 @@ public class BicycleMessenger { if(firstLine) { firstLine = false; continue; } String[] tokens = line.split("\\s+"); //build your vehicle - Vehicle vehicle = VehicleImpl.Builder.newInstance(tokens[1]).setLocationCoord(Coordinate.newInstance(Double.parseDouble(tokens[2]), Double.parseDouble(tokens[3]))) + Vehicle vehicle = VehicleImpl.Builder.newInstance(tokens[1]).setStartLocationCoordinate(Coordinate.newInstance(Double.parseDouble(tokens[2]), Double.parseDouble(tokens[3]))) .setReturnToDepot(false).setType(messengerType).build(); problemBuilder.addVehicle(vehicle); //build the penalty vehicle diff --git a/jsprit-examples/src/main/java/jsprit/examples/BuildAlgorithmFromScratchWithHardAndSoftConstraints.java b/jsprit-examples/src/main/java/jsprit/examples/BuildAlgorithmFromScratchWithHardAndSoftConstraints.java new file mode 100644 index 00000000..fa62669f --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/BuildAlgorithmFromScratchWithHardAndSoftConstraints.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (c) 2013 Stefan Schroeder. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Contributors: + * Stefan Schroeder - initial API and implementation + ******************************************************************************/ +package jsprit.examples; + +import java.util.Collection; + +import jsprit.analysis.toolbox.SolutionPrinter; +import jsprit.core.algorithm.InsertionInitialSolutionFactory; +import jsprit.core.algorithm.RemoveEmptyVehicles; +import jsprit.core.algorithm.SearchStrategy; +import jsprit.core.algorithm.SearchStrategyManager; +import jsprit.core.algorithm.VariablePlusFixedSolutionCostCalculatorFactory; +import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.acceptor.GreedyAcceptance; +import jsprit.core.algorithm.module.RuinAndRecreateModule; +import jsprit.core.algorithm.recreate.BestInsertionBuilder; +import jsprit.core.algorithm.recreate.InsertionStrategy; +import jsprit.core.algorithm.ruin.RadialRuinStrategyFactory; +import jsprit.core.algorithm.ruin.RandomRuinStrategyFactory; +import jsprit.core.algorithm.ruin.RuinStrategy; +import jsprit.core.algorithm.ruin.distance.AvgServiceAndShipmentDistance; +import jsprit.core.algorithm.selector.SelectBest; +import jsprit.core.algorithm.state.StateManager; +import jsprit.core.algorithm.state.UpdateVariableCosts; +import jsprit.core.algorithm.termination.IterationWithoutImprovementTermination; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.constraint.ConstraintManager; +import jsprit.core.problem.solution.SolutionCostCalculator; +import jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import jsprit.core.problem.vehicle.InfiniteFleetManagerFactory; +import jsprit.core.problem.vehicle.VehicleFleetManager; +import jsprit.core.util.Solutions; +import jsprit.instance.reader.SolomonReader; +import jsprit.util.Examples; + +public class BuildAlgorithmFromScratchWithHardAndSoftConstraints { + + /** + * @param args + */ + public static void main(String[] args) { + /* + * some preparation - create output folder + */ + Examples.createOutputFolder(); + + /* + * Build the problem. + * + * But define a problem-builder first. + */ + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + + /* + * A solomonReader reads solomon-instance files, and stores the required information in the builder. + */ + new SolomonReader(vrpBuilder).read("input/C101_solomon.txt"); + + /* + * Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances). + */ + VehicleRoutingProblem vrp = vrpBuilder.build(); + + /* + * Build algorithm + */ + VehicleRoutingAlgorithm vra = buildAlgorithmFromScratch(vrp); + + /* + * search solution + */ + Collection solutions = vra.searchSolutions(); + + /* + * print result + */ + SolutionPrinter.print(Solutions.bestOf(solutions)); + + } + + private static VehicleRoutingAlgorithm buildAlgorithmFromScratch(VehicleRoutingProblem vrp) { + + /* + * manages route and activity states. + */ + StateManager stateManager = new StateManager(vrp); + /* + * tells stateManager to update load states + */ + stateManager.updateLoadStates(); + /* + * tells stateManager to update time-window states + */ + stateManager.updateTimeWindowStates(); + /* + * stateManager.addStateUpdater(updater); + * lets you register your own stateUpdater + */ + + /* + * updates variable costs once a vehicleRoute has changed (by removing or adding a customer) + */ + stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager)); + + /* + * constructs a constraintManager that manages the various hardConstraints (and soon also softConstraints) + */ + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + /* + * tells constraintManager to add timeWindowConstraints + */ + constraintManager.addTimeWindowConstraint(); + /* + * tells constraintManager to add loadConstraints + */ + constraintManager.addLoadConstraint(); + /* + * add an arbitrary number of hardConstraints by + * constraintManager.addConstraint(...) + */ + + + /* + * define a fleetManager, here infinite vehicles can be used + */ + VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager(); + + /* + * define ruin-and-recreate strategies + * + */ + /* + * first, define an insertion-strategy, i.e. bestInsertion + */ + BestInsertionBuilder iBuilder = new BestInsertionBuilder(vrp, fleetManager, stateManager, constraintManager); + /* + * no need to set further options + */ + InsertionStrategy iStrategy = iBuilder.build(); + + /* + * second, define random-ruin that ruins 50-percent of the selected solution + */ + RuinStrategy randomRuin = new RandomRuinStrategyFactory(0.5).createStrategy(vrp); + + /* + * third, define radial-ruin that ruins 30-percent of the selected solution + * the second para defines the distance between two jobs. + */ + RuinStrategy radialRuin = new RadialRuinStrategyFactory(0.3, new AvgServiceAndShipmentDistance(vrp.getTransportCosts())).createStrategy(vrp); + + /* + * now define a strategy + */ + /* + * but before define how a generated solution is evaluated + * here: the VariablePlusFixed.... comes out of the box and it does what its name suggests + */ + SolutionCostCalculator solutionCostCalculator = new VariablePlusFixedSolutionCostCalculatorFactory(stateManager).createCalculator(); + + SearchStrategy firstStrategy = new SearchStrategy(new SelectBest(), new GreedyAcceptance(1), solutionCostCalculator); + firstStrategy.addModule(new RuinAndRecreateModule("randomRuinAndBestInsertion", iStrategy, randomRuin)); + + SearchStrategy secondStrategy = new SearchStrategy(new SelectBest(), new GreedyAcceptance(1), solutionCostCalculator); + secondStrategy.addModule(new RuinAndRecreateModule("radialRuinAndBestInsertion", iStrategy, radialRuin)); + + /* + * put both strategies together, each with the prob of 0.5 to be selected + */ + SearchStrategyManager searchStrategyManager = new SearchStrategyManager(); + searchStrategyManager.addStrategy(firstStrategy, 0.5); + searchStrategyManager.addStrategy(secondStrategy, 0.5); + + /* + * construct the algorithm + */ + VehicleRoutingAlgorithm vra = new VehicleRoutingAlgorithm(vrp, searchStrategyManager); + //do not forgett to add the stateManager listening to the algorithm-stages + vra.addListener(stateManager); + //remove empty vehicles after insertion has finished + vra.addListener(new RemoveEmptyVehicles(fleetManager)); + + /* + * Do not forget to add an initial solution by vra.addInitialSolution(solution); + * or + */ + vra.addInitialSolution(new InsertionInitialSolutionFactory(iStrategy, solutionCostCalculator).createSolution(vrp)); + + /* + * define the nIterations (by default nIteration=100) + */ + vra.setNuOfIterations(1000); + + /* + * optionally define a premature termination criterion (by default: not criterion is set) + */ + vra.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(100)); + + return vra; + } + +} diff --git a/jsprit-examples/src/main/java/jsprit/examples/ConfigureAlgorithmInCodeInsteadOfPerXml.java b/jsprit-examples/src/main/java/jsprit/examples/ConfigureAlgorithmInCodeInsteadOfPerXml.java index 49aadfdb..f2e54891 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/ConfigureAlgorithmInCodeInsteadOfPerXml.java +++ b/jsprit-examples/src/main/java/jsprit/examples/ConfigureAlgorithmInCodeInsteadOfPerXml.java @@ -18,7 +18,7 @@ package jsprit.examples; import java.util.Collection; -import jsprit.analysis.toolbox.SolutionPlotter; +import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.io.AlgorithmConfig; @@ -57,7 +57,7 @@ public class ConfigureAlgorithmInCodeInsteadOfPerXml { * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" */ Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); + vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); vehicleBuilder.setType(vehicleType); Vehicle vehicle = vehicleBuilder.build(); @@ -100,7 +100,7 @@ public class ConfigureAlgorithmInCodeInsteadOfPerXml { /* * plot */ - SolutionPlotter.plotSolutionAsPNG(problem, bestSolution, "output/solution.png", "solution"); + new Plotter(problem,bestSolution).plot("output/solution.png", "solution"); } private static AlgorithmConfig getAlgorithmConfig() { diff --git a/jsprit-examples/src/main/java/jsprit/examples/CostMatrixExample.java b/jsprit-examples/src/main/java/jsprit/examples/CostMatrixExample.java index 752d7616..16f979d5 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/CostMatrixExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/CostMatrixExample.java @@ -18,7 +18,7 @@ package jsprit.examples; import java.util.Collection; -import jsprit.analysis.toolbox.SolutionPlotter; +import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; @@ -54,7 +54,7 @@ public class CostMatrixExample { Examples.createOutputFolder(); VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 2).setCostPerDistance(1).setCostPerTime(2).build(); - Vehicle vehicle = VehicleImpl.Builder.newInstance("vehicle").setLocationId("0").setType(type).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("vehicle").setStartLocationId("0").setType(type).build(); Service s1 = Service.Builder.newInstance("1", 1).setLocationId("1").build(); Service s2 = Service.Builder.newInstance("2", 1).setLocationId("2").build(); @@ -105,9 +105,9 @@ public class CostMatrixExample { Collection solutions = vra.searchSolutions(); SolutionPrinter.print(Solutions.bestOf(solutions)); - - SolutionPlotter.plotSolutionAsPNG(vrp, Solutions.bestOf(solutions), "output/yo.png", "po"); - + + new Plotter(vrp, Solutions.bestOf(solutions)).plot("output/yo.png", "po"); + } } diff --git a/jsprit-examples/src/main/java/jsprit/examples/EnRoutePickupAndDeliveryWithMultipleDepotsAndOpenRoutesExample.java b/jsprit-examples/src/main/java/jsprit/examples/EnRoutePickupAndDeliveryWithMultipleDepotsAndOpenRoutesExample.java new file mode 100644 index 00000000..0f91b210 --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/EnRoutePickupAndDeliveryWithMultipleDepotsAndOpenRoutesExample.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (C) 2013 Stefan Schroeder + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + ******************************************************************************/ +package jsprit.examples; + +import java.util.Arrays; +import java.util.Collection; + +import jsprit.analysis.toolbox.GraphStreamViewer; +import jsprit.analysis.toolbox.GraphStreamViewer.Label; +import jsprit.analysis.toolbox.Plotter; +import jsprit.analysis.toolbox.SolutionPrinter; +import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.VehicleRoutingProblem.FleetSize; +import jsprit.core.problem.io.VrpXMLWriter; +import jsprit.core.problem.job.Shipment; +import jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import jsprit.core.problem.vehicle.Vehicle; +import jsprit.core.problem.vehicle.VehicleImpl; +import jsprit.core.problem.vehicle.VehicleImpl.Builder; +import jsprit.core.problem.vehicle.VehicleType; +import jsprit.core.problem.vehicle.VehicleTypeImpl; +import jsprit.core.util.Coordinate; +import jsprit.core.util.Solutions; +import jsprit.util.Examples; + + +public class EnRoutePickupAndDeliveryWithMultipleDepotsAndOpenRoutesExample { + + public static void main(String[] args) { + /* + * some preparation - create output folder + */ + Examples.createOutputFolder(); + + /* + * get a vehicle type-builder and build a type with the typeId "vehicleType" and a capacity of 2 + */ + VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType", 2); + vehicleTypeBuilder.setCostPerDistance(1.0); + VehicleType vehicleType = vehicleTypeBuilder.build(); + + /* + * define two vehicles and their start-locations + * + * the first two do need to return to depot + */ + Builder vehicleBuilder1 = VehicleImpl.Builder.newInstance("vehicles@[10,10]"); + vehicleBuilder1.setStartLocationCoordinate(Coordinate.newInstance(10, 10)).setReturnToDepot(false); + vehicleBuilder1.setType(vehicleType); + Vehicle vehicle1 = vehicleBuilder1.build(); + + Builder vehicleBuilder2 = VehicleImpl.Builder.newInstance("vehicles@[30,30]"); + vehicleBuilder2.setStartLocationCoordinate(Coordinate.newInstance(30, 30)).setReturnToDepot(false); + vehicleBuilder2.setType(vehicleType); + Vehicle vehicle2 = vehicleBuilder2.build(); + + Builder vehicleBuilder3 = VehicleImpl.Builder.newInstance("vehicles@[10,30]"); + vehicleBuilder3.setStartLocationCoordinate(Coordinate.newInstance(10, 30)); + vehicleBuilder3.setType(vehicleType); + Vehicle vehicle3 = vehicleBuilder3.build(); + + Builder vehicleBuilder4 = VehicleImpl.Builder.newInstance("vehicles@[30,10]"); + vehicleBuilder4.setStartLocationCoordinate(Coordinate.newInstance(30, 10)); + vehicleBuilder4.setType(vehicleType); + Vehicle vehicle4 = vehicleBuilder4.build(); + + /* + * build shipments at the required locations, each with a capacity-demand of 1. + + */ + + Shipment shipment1 = Shipment.Builder.newInstance("1", 1).setPickupCoord(Coordinate.newInstance(5, 7)).setDeliveryCoord(Coordinate.newInstance(6, 9)).build(); + Shipment shipment2 = Shipment.Builder.newInstance("2", 1).setPickupCoord(Coordinate.newInstance(5, 13)).setDeliveryCoord(Coordinate.newInstance(6, 11)).build(); + + Shipment shipment3 = Shipment.Builder.newInstance("3", 1).setPickupCoord(Coordinate.newInstance(15, 7)).setDeliveryCoord(Coordinate.newInstance(14, 9)).build(); + Shipment shipment4 = Shipment.Builder.newInstance("4", 1).setPickupCoord(Coordinate.newInstance(15, 13)).setDeliveryCoord(Coordinate.newInstance(14, 11)).build(); + + Shipment shipment5 = Shipment.Builder.newInstance("5", 1).setPickupCoord(Coordinate.newInstance(25, 27)).setDeliveryCoord(Coordinate.newInstance(26, 29)).build(); + Shipment shipment6 = Shipment.Builder.newInstance("6", 1).setPickupCoord(Coordinate.newInstance(25, 33)).setDeliveryCoord(Coordinate.newInstance(26, 31)).build(); + + Shipment shipment7 = Shipment.Builder.newInstance("7", 1).setPickupCoord(Coordinate.newInstance(35, 27)).setDeliveryCoord(Coordinate.newInstance(34, 29)).build(); + Shipment shipment8 = Shipment.Builder.newInstance("8", 1).setPickupCoord(Coordinate.newInstance(35, 33)).setDeliveryCoord(Coordinate.newInstance(34, 31)).build(); + + Shipment shipment9 = Shipment.Builder.newInstance("9", 1).setPickupCoord(Coordinate.newInstance(5, 27)).setDeliveryCoord(Coordinate.newInstance(6, 29)).build(); + Shipment shipment10 = Shipment.Builder.newInstance("10", 1).setPickupCoord(Coordinate.newInstance(5, 33)).setDeliveryCoord(Coordinate.newInstance(6, 31)).build(); + + Shipment shipment11 = Shipment.Builder.newInstance("11", 1).setPickupCoord(Coordinate.newInstance(15, 27)).setDeliveryCoord(Coordinate.newInstance(14, 29)).build(); + Shipment shipment12 = Shipment.Builder.newInstance("12", 1).setPickupCoord(Coordinate.newInstance(15, 33)).setDeliveryCoord(Coordinate.newInstance(14, 31)).build(); + + Shipment shipment13 = Shipment.Builder.newInstance("13", 1).setPickupCoord(Coordinate.newInstance(25, 7)).setDeliveryCoord(Coordinate.newInstance(26, 9)).build(); + Shipment shipment14 = Shipment.Builder.newInstance("14", 1).setPickupCoord(Coordinate.newInstance(25, 13)).setDeliveryCoord(Coordinate.newInstance(26, 11)).build(); + + Shipment shipment15 = Shipment.Builder.newInstance("15", 1).setPickupCoord(Coordinate.newInstance(35, 7)).setDeliveryCoord(Coordinate.newInstance(34, 9)).build(); + Shipment shipment16 = Shipment.Builder.newInstance("16", 1).setPickupCoord(Coordinate.newInstance(35, 13)).setDeliveryCoord(Coordinate.newInstance(34, 11)).build(); + + + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addVehicle(vehicle1).addVehicle(vehicle2).addVehicle(vehicle3).addVehicle(vehicle4); + vrpBuilder.addJob(shipment1).addJob(shipment2).addJob(shipment3).addJob(shipment4); + vrpBuilder.addJob(shipment5).addJob(shipment6).addJob(shipment7).addJob(shipment8); + vrpBuilder.addJob(shipment9).addJob(shipment10).addJob(shipment11).addJob(shipment12); + vrpBuilder.addJob(shipment13).addJob(shipment14).addJob(shipment15).addJob(shipment16); + + vrpBuilder.setFleetSize(FleetSize.FINITE); + VehicleRoutingProblem problem = vrpBuilder.build(); + + /* + * get the algorithm out-of-the-box. + */ + VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(problem, "input/algorithmConfig.xml"); +// algorithm.setNuOfIterations(30000); + /* + * and search a solution + */ + Collection solutions = algorithm.searchSolutions(); + + /* + * get the best + */ + VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions); + + /* + * write out problem and solution to xml-file + */ + new VrpXMLWriter(problem, solutions).write("output/shipment-problem-with-solution.xml"); + + /* + * print nRoutes and totalCosts of bestSolution + */ + SolutionPrinter.print(bestSolution); + + /* + * plot problem without solution + */ + Plotter problemPlotter = new Plotter(problem); + problemPlotter.plotShipments(true); + problemPlotter.plot("output/enRoutePickupAndDeliveryWithMultipleLocationsExample_problem.png", "en-route pickup and delivery"); + + /* + * plot problem with solution + */ + Plotter solutionPlotter = new Plotter(problem,Arrays.asList(Solutions.bestOf(solutions).getRoutes().iterator().next())); + solutionPlotter.plotShipments(true); + solutionPlotter.plot("output/enRoutePickupAndDeliveryWithMultipleLocationsExample_solution.png", "en-route pickup and delivery"); + + new GraphStreamViewer(problem,Solutions.bestOf(solutions)).labelWith(Label.ACTIVITY).setRenderDelay(100).setRenderShipments(true).display(); + + } + +} + diff --git a/jsprit-examples/src/main/java/jsprit/examples/EnRoutePickupAndDeliveryWithMultipleDepotsAndVehicleAccessConstraintAndSpecifiedVehicleEndLocationsExample.java b/jsprit-examples/src/main/java/jsprit/examples/EnRoutePickupAndDeliveryWithMultipleDepotsAndVehicleAccessConstraintAndSpecifiedVehicleEndLocationsExample.java new file mode 100644 index 00000000..3733f1c3 --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/EnRoutePickupAndDeliveryWithMultipleDepotsAndVehicleAccessConstraintAndSpecifiedVehicleEndLocationsExample.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (C) 2013 Stefan Schroeder + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + ******************************************************************************/ +package jsprit.examples; + +import java.util.Collection; + +import jsprit.analysis.toolbox.GraphStreamViewer; +import jsprit.analysis.toolbox.GraphStreamViewer.Label; +import jsprit.analysis.toolbox.SolutionPrinter; +import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; +import jsprit.core.algorithm.termination.IterationWithoutImprovementTermination; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.VehicleRoutingProblem.FleetSize; +import jsprit.core.problem.constraint.HardRouteStateLevelConstraint; +import jsprit.core.problem.job.Shipment; +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import jsprit.core.problem.vehicle.Vehicle; +import jsprit.core.problem.vehicle.VehicleImpl; +import jsprit.core.problem.vehicle.VehicleImpl.Builder; +import jsprit.core.problem.vehicle.VehicleType; +import jsprit.core.problem.vehicle.VehicleTypeImpl; +import jsprit.core.util.Coordinate; +import jsprit.core.util.Solutions; +import jsprit.util.Examples; + + +public class EnRoutePickupAndDeliveryWithMultipleDepotsAndVehicleAccessConstraintAndSpecifiedVehicleEndLocationsExample { + + public static void main(String[] args) { + /* + * some preparation - create output folder + */ + Examples.createOutputFolder(); + + /* + * get a vehicle type-builder and build a type with the typeId "vehicleType" and a capacity of 2 + */ + VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType", 2); + vehicleTypeBuilder.setCostPerDistance(1.0); + VehicleType vehicleType = vehicleTypeBuilder.build(); + + /* + * define two vehicles and their locations. + * + * this example employs two vehicles. one that has to return to its start-location (vehicle1) and one that has a different + * end-location. + * + * play with these location to see which impact they have on customer-sequences. + */ + Builder vehicleBuilder1 = VehicleImpl.Builder.newInstance("v1"); + vehicleBuilder1.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); + vehicleBuilder1.setType(vehicleType); + Vehicle vehicle1 = vehicleBuilder1.build(); + + Builder vehicleBuilder2 = VehicleImpl.Builder.newInstance("v2"); + vehicleBuilder2.setStartLocationCoordinate(Coordinate.newInstance(30, 30)).setEndLocationCoordinate(Coordinate.newInstance(30, 19)); + vehicleBuilder2.setType(vehicleType); + Vehicle vehicle2 = vehicleBuilder2.build(); + + + /* + * build shipments at the required locations, each with a capacity-demand of 1. + * + */ + Shipment shipment1 = Shipment.Builder.newInstance("1", 1).setPickupCoord(Coordinate.newInstance(5, 7)).setDeliveryCoord(Coordinate.newInstance(6, 9)).build(); + Shipment shipment2 = Shipment.Builder.newInstance("2", 1).setPickupCoord(Coordinate.newInstance(5, 13)).setDeliveryCoord(Coordinate.newInstance(6, 11)).build(); + + Shipment shipment3 = Shipment.Builder.newInstance("3", 1).setPickupCoord(Coordinate.newInstance(15, 7)).setDeliveryCoord(Coordinate.newInstance(14, 9)).build(); + Shipment shipment4 = Shipment.Builder.newInstance("4", 1).setPickupCoord(Coordinate.newInstance(15, 13)).setDeliveryCoord(Coordinate.newInstance(14, 11)).build(); + + Shipment shipment5 = Shipment.Builder.newInstance("5", 1).setPickupCoord(Coordinate.newInstance(25, 27)).setDeliveryCoord(Coordinate.newInstance(26, 29)).build(); + Shipment shipment6 = Shipment.Builder.newInstance("6", 1).setPickupCoord(Coordinate.newInstance(25, 33)).setDeliveryCoord(Coordinate.newInstance(26, 31)).build(); + + Shipment shipment7 = Shipment.Builder.newInstance("7", 1).setPickupCoord(Coordinate.newInstance(35, 27)).setDeliveryCoord(Coordinate.newInstance(34, 29)).build(); + Shipment shipment8 = Shipment.Builder.newInstance("8", 1).setPickupCoord(Coordinate.newInstance(35, 33)).setDeliveryCoord(Coordinate.newInstance(34, 31)).build(); + + Shipment shipment9 = Shipment.Builder.newInstance("9", 1).setPickupCoord(Coordinate.newInstance(5, 27)).setDeliveryCoord(Coordinate.newInstance(6, 29)).build(); + Shipment shipment10 = Shipment.Builder.newInstance("10", 1).setPickupCoord(Coordinate.newInstance(5, 33)).setDeliveryCoord(Coordinate.newInstance(6, 31)).build(); + + Shipment shipment11 = Shipment.Builder.newInstance("11", 1).setPickupCoord(Coordinate.newInstance(15, 27)).setDeliveryCoord(Coordinate.newInstance(14, 29)).build(); + Shipment shipment12 = Shipment.Builder.newInstance("12", 1).setPickupCoord(Coordinate.newInstance(15, 33)).setDeliveryCoord(Coordinate.newInstance(14, 31)).build(); + + Shipment shipment13 = Shipment.Builder.newInstance("13", 1).setPickupCoord(Coordinate.newInstance(25, 7)).setDeliveryCoord(Coordinate.newInstance(26, 9)).build(); + Shipment shipment14 = Shipment.Builder.newInstance("14", 1).setPickupCoord(Coordinate.newInstance(25, 13)).setDeliveryCoord(Coordinate.newInstance(26, 11)).build(); + + Shipment shipment15 = Shipment.Builder.newInstance("15", 1).setPickupCoord(Coordinate.newInstance(35, 7)).setDeliveryCoord(Coordinate.newInstance(34, 9)).build(); + Shipment shipment16 = Shipment.Builder.newInstance("16", 1).setPickupCoord(Coordinate.newInstance(35, 13)).setDeliveryCoord(Coordinate.newInstance(34, 11)).build(); + + Shipment shipment17 = Shipment.Builder.newInstance("17", 1).setPickupCoord(Coordinate.newInstance(5, 14)).setDeliveryCoord(Coordinate.newInstance(6, 16)).build(); + Shipment shipment18 = Shipment.Builder.newInstance("18", 1).setPickupCoord(Coordinate.newInstance(5, 20)).setDeliveryCoord(Coordinate.newInstance(6, 18)).build(); + + Shipment shipment19 = Shipment.Builder.newInstance("19", 1).setPickupCoord(Coordinate.newInstance(15, 14)).setDeliveryCoord(Coordinate.newInstance(14, 16)).build(); + Shipment shipment20 = Shipment.Builder.newInstance("20", 1).setPickupCoord(Coordinate.newInstance(15, 20)).setDeliveryCoord(Coordinate.newInstance(14, 18)).build(); + + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addVehicle(vehicle1).addVehicle(vehicle2); + vrpBuilder.addJob(shipment1).addJob(shipment2).addJob(shipment3).addJob(shipment4); + vrpBuilder.addJob(shipment5).addJob(shipment6).addJob(shipment7).addJob(shipment8); + vrpBuilder.addJob(shipment9).addJob(shipment10).addJob(shipment11).addJob(shipment12); + vrpBuilder.addJob(shipment13).addJob(shipment14).addJob(shipment15).addJob(shipment16); + vrpBuilder.addJob(shipment17).addJob(shipment18).addJob(shipment19).addJob(shipment20); + + //you only have two vehicles + vrpBuilder.setFleetSize(FleetSize.FINITE); + + /* + * add a geographic constraint determining that vehicle1 cannot go to x>15 and vehicle2 cannot go to x<15 + * + * switch off the geoConstraints to see the impact of this constraint on routes, or just exchange v1 and v2 to reverse the geo-constraint. + */ + HardRouteStateLevelConstraint geoClusterConstraint = new HardRouteStateLevelConstraint() { + + @Override + public boolean fulfilled(JobInsertionContext insertionContext) { + Shipment shipment2insert = ((Shipment)insertionContext.getJob()); + if(insertionContext.getNewVehicle().getId().equals("v1")){ + if(shipment2insert.getPickupCoord().getX() > 15. || shipment2insert.getDeliveryCoord().getX() > 15.){ + return false; + } + } + if(insertionContext.getNewVehicle().getId().equals("v2")){ + if(shipment2insert.getPickupCoord().getX() < 15. || shipment2insert.getDeliveryCoord().getX() < 15.){ + return false; + } + } + return true; + } + }; + //add the constraint to the problem + vrpBuilder.addConstraint(geoClusterConstraint); + //build the problem + VehicleRoutingProblem problem = vrpBuilder.build(); + + + /* + * get a sample algorithm. + * + * Note that you need to make sure to prohibit vehicle-switching by adding the insertion-tag false. + * This way you make sure that no vehicle can take over a route that is employed by another. Allowing this might make sense when dealing with + * a heterogeneous fleet and you want to employ a bigger vehicle on a still existing route. However, allowing it makes constraint-checking + * bit more complicated and you cannot just add the above hard-constraint. Latter will be covered in another example. + * + */ + VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(problem, "input/algorithmConfig_noVehicleSwitch.xml"); + algorithm.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(100)); +// algorithm.setNuOfIterations(30000); + /* + * and search a solution + */ + Collection solutions = algorithm.searchSolutions(); + + /* + * get the best + */ + VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions); + + /* + * write out problem and solution to xml-file + */ +// new VrpXMLWriter(problem, solutions).write("output/shipment-problem-with-solution.xml"); + + /* + * print nRoutes and totalCosts of bestSolution + */ + SolutionPrinter.print(bestSolution); + + /* + * plot problem without solution + */ +// Plotter problemPlotter = new Plotter(problem); +// problemPlotter.plotShipments(true); +// problemPlotter.plot("output/enRoutePickupAndDeliveryWithMultipleLocationsExample_problem.png", "en-route pickup and delivery"); +// +// /* +// * plot problem with solution +// */ +// Plotter solutionPlotter = new Plotter(problem,Arrays.asList(Solutions.bestOf(solutions).getRoutes().iterator().next())); +// solutionPlotter.plotShipments(true); +// solutionPlotter.plot("output/enRoutePickupAndDeliveryWithMultipleLocationsExample_solution.png", "en-route pickup and delivery"); + + new GraphStreamViewer(problem).labelWith(Label.ID).setRenderDelay(100).setRenderShipments(true).display(); + + new GraphStreamViewer(problem,Solutions.bestOf(solutions)).labelWith(Label.ACTIVITY).setRenderDelay(100).setRenderShipments(true).display(); + + } + +} + diff --git a/jsprit-examples/src/main/java/jsprit/examples/HVRPExample.java b/jsprit-examples/src/main/java/jsprit/examples/HVRPExample.java index 3702d2be..dcc853f1 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/HVRPExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/HVRPExample.java @@ -81,17 +81,17 @@ public class HVRPExample { //add vehicle - finite fleet //2xtype1 VehicleType type1 = VehicleTypeImpl.Builder.newInstance("type_1", 120).setCostPerDistance(1.0).build(); - VehicleImpl vehicle1_1 = VehicleImpl.Builder.newInstance("1_1").setLocationCoord(Coordinate.newInstance(40, 40)).setType(type1).build(); + VehicleImpl vehicle1_1 = VehicleImpl.Builder.newInstance("1_1").setStartLocationCoordinate(Coordinate.newInstance(40, 40)).setType(type1).build(); vrpBuilder.addVehicle(vehicle1_1); - VehicleImpl vehicle1_2 = VehicleImpl.Builder.newInstance("1_2").setLocationCoord(Coordinate.newInstance(40, 40)).setType(type1).build(); + VehicleImpl vehicle1_2 = VehicleImpl.Builder.newInstance("1_2").setStartLocationCoordinate(Coordinate.newInstance(40, 40)).setType(type1).build(); vrpBuilder.addVehicle(vehicle1_2); //1xtype2 VehicleType type2 = VehicleTypeImpl.Builder.newInstance("type_2", 160).setCostPerDistance(1.1).build(); - VehicleImpl vehicle2_1 = VehicleImpl.Builder.newInstance("2_1").setLocationCoord(Coordinate.newInstance(40, 40)).setType(type2).build(); + VehicleImpl vehicle2_1 = VehicleImpl.Builder.newInstance("2_1").setStartLocationCoordinate(Coordinate.newInstance(40, 40)).setType(type2).build(); vrpBuilder.addVehicle(vehicle2_1); //1xtype3 VehicleType type3 = VehicleTypeImpl.Builder.newInstance("type_3", 300).setCostPerDistance(1.3).build(); - VehicleImpl vehicle3_1 = VehicleImpl.Builder.newInstance("3_1").setLocationCoord(Coordinate.newInstance(40, 40)).setType(type3).build(); + VehicleImpl vehicle3_1 = VehicleImpl.Builder.newInstance("3_1").setStartLocationCoordinate(Coordinate.newInstance(40, 40)).setType(type3).build(); vrpBuilder.addVehicle(vehicle3_1); //add penaltyVehicles to allow invalid solutions temporarily diff --git a/jsprit-examples/src/main/java/jsprit/examples/MultipleDepotExample.java b/jsprit-examples/src/main/java/jsprit/examples/MultipleDepotExample.java index af082fcd..93546366 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/MultipleDepotExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/MultipleDepotExample.java @@ -21,7 +21,7 @@ import java.util.Collection; import jsprit.analysis.toolbox.AlgorithmSearchProgressChartListener; import jsprit.analysis.toolbox.GraphStreamViewer; -import jsprit.analysis.toolbox.SolutionPlotter; +import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.analysis.toolbox.StopWatch; import jsprit.core.algorithm.VehicleRoutingAlgorithm; @@ -77,7 +77,7 @@ public class MultipleDepotExample { for(Coordinate depotCoord : Arrays.asList(firstDepotCoord,second,third,fourth)){ for(int i=0;i solutions = vra.searchSolutions(); SolutionPrinter.print(Solutions.bestOf(solutions)); - SolutionPlotter.plotSolutionAsPNG(vrp, Solutions.bestOf(solutions), "output/p01_solution.png", "p01"); - + + new Plotter(vrp, Solutions.bestOf(solutions)).plot("output/p01_solution.png", "p01"); + new GraphStreamViewer(vrp, Solutions.bestOf(solutions)).setRenderDelay(100).display(); } diff --git a/jsprit-examples/src/main/java/jsprit/examples/MultipleDepotExampleWithPenaltyVehicles.java b/jsprit-examples/src/main/java/jsprit/examples/MultipleDepotExampleWithPenaltyVehicles.java index 9d2b5efd..a8701ced 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/MultipleDepotExampleWithPenaltyVehicles.java +++ b/jsprit-examples/src/main/java/jsprit/examples/MultipleDepotExampleWithPenaltyVehicles.java @@ -21,7 +21,7 @@ import java.util.Collection; import jsprit.analysis.toolbox.AlgorithmSearchProgressChartListener; import jsprit.analysis.toolbox.GraphStreamViewer; -import jsprit.analysis.toolbox.SolutionPlotter; +import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.analysis.toolbox.SolutionPrinter.Print; import jsprit.analysis.toolbox.StopWatch; @@ -32,7 +32,6 @@ import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem.FleetSize; import jsprit.core.problem.io.VrpXMLReader; import jsprit.core.problem.solution.VehicleRoutingProblemSolution; -import jsprit.core.problem.vehicle.PenaltyVehicleType; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl; import jsprit.core.problem.vehicle.VehicleType; @@ -79,36 +78,19 @@ public class MultipleDepotExampleWithPenaltyVehicles { VehicleType vehicleType = VehicleTypeImpl.Builder.newInstance(depotCounter + "_type", capacity).setCostPerDistance(1.0).build(); String vehicleId = depotCounter + "_" + (i+1) + "_vehicle"; VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance(vehicleId); - vehicleBuilder.setLocationCoord(depotCoord); + vehicleBuilder.setStartLocationCoordinate(depotCoord); vehicleBuilder.setType(vehicleType); vehicleBuilder.setLatestArrival(maxDuration); Vehicle vehicle = vehicleBuilder.build(); vrpBuilder.addVehicle(vehicle); } - /* - * define penalty-type with the same id, but other higher fixed and variable costs - */ - VehicleType penaltyType = VehicleTypeImpl.Builder.newInstance(depotCounter + "_type", capacity).setFixedCost(50).setCostPerDistance(3.0).build(); - /* - * to mark the penalty-type as penalty-type, wrap it with PenaltyVehicleType(Wrapper) - * this is to tell the fleetManager that this is not a regular but a penalty vehicle - */ - PenaltyVehicleType penaltyVehicleType = new PenaltyVehicleType(penaltyType,3); - String vehicleId = depotCounter + "_vehicle#penalty"; - VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance(vehicleId); - vehicleBuilder.setLocationCoord(depotCoord); - /* - * set PenaltyVehicleType - */ - vehicleBuilder.setType(penaltyVehicleType); - vehicleBuilder.setLatestArrival(maxDuration); - Vehicle penaltyVehicle = vehicleBuilder.build(); - vrpBuilder.addVehicle(penaltyVehicle); - depotCounter++; } - + /* + * define penalty-type with the same id, but other higher fixed and variable costs + */ + vrpBuilder.addPenaltyVehicles(3, 50); /* * define problem with finite fleet @@ -134,8 +116,9 @@ public class MultipleDepotExampleWithPenaltyVehicles { Collection solutions = vra.searchSolutions(); SolutionPrinter.print(vrp,Solutions.bestOf(solutions),Print.VERBOSE); - SolutionPlotter.plotSolutionAsPNG(vrp, Solutions.bestOf(solutions), "output/p08_solution.png", "p08"); + new Plotter(vrp, Solutions.bestOf(solutions)).plot("output/p08_solution.png", "p08"); + new GraphStreamViewer(vrp,Solutions.bestOf(solutions)).setRenderDelay(50).display(); } diff --git a/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample.java b/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample.java index fe5d5d64..86ed20a0 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample.java @@ -21,7 +21,6 @@ import java.util.Collection; import jsprit.analysis.toolbox.AlgorithmSearchProgressChartListener; import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.Plotter.Label; -import jsprit.analysis.toolbox.SolutionPlotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; @@ -59,7 +58,8 @@ public class PickupAndDeliveryExample { VehicleRoutingProblem vrp = vrpBuilder.build(); - SolutionPlotter.plotVrpAsPNG(vrp, "output/pd_solomon_r101.png", "pd_r101"); + new Plotter(vrp).plot("output/pd_solomon_r101.png", "pd_r101"); + /* * Define the required vehicle-routing algorithms to solve the above problem. diff --git a/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample2.java b/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample2.java index 3b7d98ae..ee9419f6 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample2.java +++ b/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample2.java @@ -22,7 +22,6 @@ import jsprit.analysis.toolbox.AlgorithmSearchProgressChartListener; import jsprit.analysis.toolbox.GraphStreamViewer; import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.Plotter.Label; -import jsprit.analysis.toolbox.SolutionPlotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; @@ -65,7 +64,8 @@ public class PickupAndDeliveryExample2 { VehicleRoutingProblem vrp = vrpBuilder.build(); - SolutionPlotter.plotVrpAsPNG(vrp, "output/pd_christophides_vrpnc1.png", "pd_vrpnc1"); + new Plotter(vrp).plot("output/pd_christophides_vrpnc1.png", "pd_vrpnc1"); + /* * Define the required vehicle-routing algorithms to solve the above problem. diff --git a/jsprit-examples/src/main/java/jsprit/examples/RefuseCollectionExample.java b/jsprit-examples/src/main/java/jsprit/examples/RefuseCollectionExample.java index 1218c24a..80199588 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/RefuseCollectionExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/RefuseCollectionExample.java @@ -165,7 +165,7 @@ public class RefuseCollectionExample { VehicleTypeImpl bigType = typeBuilder.build(); VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationId("1"); + vehicleBuilder.setStartLocationId("1"); vehicleBuilder.setType(bigType); Vehicle bigVehicle = vehicleBuilder.build(); diff --git a/jsprit-examples/src/main/java/jsprit/examples/ServicePickupsWithMultipleDepotsExample.java b/jsprit-examples/src/main/java/jsprit/examples/ServicePickupsWithMultipleDepotsExample.java new file mode 100644 index 00000000..aa74ad42 --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/ServicePickupsWithMultipleDepotsExample.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (C) 2013 Stefan Schroeder + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + ******************************************************************************/ +package jsprit.examples; + +import java.util.Arrays; +import java.util.Collection; + +import jsprit.analysis.toolbox.GraphStreamViewer; +import jsprit.analysis.toolbox.GraphStreamViewer.Label; +import jsprit.analysis.toolbox.Plotter; +import jsprit.analysis.toolbox.SolutionPrinter; +import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.io.VrpXMLWriter; +import jsprit.core.problem.job.Service; +import jsprit.core.problem.solution.VehicleRoutingProblemSolution; +import jsprit.core.problem.vehicle.Vehicle; +import jsprit.core.problem.vehicle.VehicleImpl; +import jsprit.core.problem.vehicle.VehicleImpl.Builder; +import jsprit.core.problem.vehicle.VehicleType; +import jsprit.core.problem.vehicle.VehicleTypeImpl; +import jsprit.core.util.Coordinate; +import jsprit.core.util.Solutions; +import jsprit.util.Examples; + + +public class ServicePickupsWithMultipleDepotsExample { + + public static void main(String[] args) { + /* + * some preparation - create output folder + */ + Examples.createOutputFolder(); + + /* + * get a vehicle type-builder and build a type with the typeId "vehicleType" and a capacity of 2 + */ + VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType", 8); + vehicleTypeBuilder.setCostPerDistance(1.0); + VehicleType vehicleType = vehicleTypeBuilder.build(); + + /* + * define two depots, i.e. two vehicle locations ([10,10],[50,50]) and equip them with an infinite number of vehicles of type 'vehicleType' + */ + Builder vehicleBuilder1 = VehicleImpl.Builder.newInstance("vehicles@[10,10]"); + vehicleBuilder1.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); + vehicleBuilder1.setType(vehicleType); + Vehicle vehicle1 = vehicleBuilder1.build(); + + Builder vehicleBuilder2 = VehicleImpl.Builder.newInstance("vehicles@[50,50]"); + vehicleBuilder2.setStartLocationCoordinate(Coordinate.newInstance(50, 50)); + vehicleBuilder2.setType(vehicleType); + Vehicle vehicle2 = vehicleBuilder2.build(); + + + /* + * build shipments at the required locations, each with a capacity-demand of 1. + * 4 shipments + * 1: (5,7)->(6,9) + * 2: (5,13)->(6,11) + * 3: (15,7)->(14,9) + * 4: (15,13)->(14,11) + */ + + Service shipment1 = Service.Builder.newInstance("1", 1).setCoord(Coordinate.newInstance(5, 7)).build(); + Service shipment2 = Service.Builder.newInstance("2", 1).setCoord(Coordinate.newInstance(5, 13)).build(); + + Service shipment3 = Service.Builder.newInstance("3", 1).setCoord(Coordinate.newInstance(15, 7)).build(); + Service shipment4 = Service.Builder.newInstance("4", 1).setCoord(Coordinate.newInstance(15, 13)).build(); + + Service shipment5 = Service.Builder.newInstance("5", 1).setCoord(Coordinate.newInstance(55, 57)).build(); + Service shipment6 = Service.Builder.newInstance("6", 1).setCoord(Coordinate.newInstance(55, 63)).build(); + + Service shipment7 = Service.Builder.newInstance("7", 1).setCoord(Coordinate.newInstance(65, 57)).build(); + Service shipment8 = Service.Builder.newInstance("8", 1).setCoord(Coordinate.newInstance(65, 63)).build(); + + + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addVehicle(vehicle1).addVehicle(vehicle2); + vrpBuilder.addJob(shipment1).addJob(shipment2).addJob(shipment3).addJob(shipment4); + vrpBuilder.addJob(shipment5).addJob(shipment6).addJob(shipment7).addJob(shipment8); + +// vrpBuilder.setFleetSize(FleetSize.FINITE); + VehicleRoutingProblem problem = vrpBuilder.build(); + + /* + * get the algorithm out-of-the-box. + */ + VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(problem, "input/algorithmConfig.xml"); + algorithm.setNuOfIterations(10); + + /* + * and search a solution + */ + Collection solutions = algorithm.searchSolutions(); + + /* + * get the best + */ + VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions); + + /* + * write out problem and solution to xml-file + */ + new VrpXMLWriter(problem, solutions).write("output/shipment-problem-with-solution.xml"); + + /* + * print nRoutes and totalCosts of bestSolution + */ + SolutionPrinter.print(bestSolution); + + /* + * plot problem without solution + */ + Plotter problemPlotter = new Plotter(problem); + problemPlotter.plotShipments(true); + problemPlotter.plot("output/enRoutePickupAndDeliveryWithMultipleLocationsExample_problem.png", "en-route pickup and delivery"); + + /* + * plot problem with solution + */ + Plotter solutionPlotter = new Plotter(problem,Arrays.asList(Solutions.bestOf(solutions).getRoutes().iterator().next())); + solutionPlotter.plotShipments(true); + solutionPlotter.plot("output/enRoutePickupAndDeliveryWithMultipleLocationsExample_solution.png", "en-route pickup and delivery"); + + new GraphStreamViewer(problem,Solutions.bestOf(solutions)).labelWith(Label.ACTIVITY).setRenderDelay(100).setRenderShipments(true).display(); + + } + +} diff --git a/jsprit-examples/src/main/java/jsprit/examples/SimpleDepotBoundedPickupAndDeliveryExample.java b/jsprit-examples/src/main/java/jsprit/examples/SimpleDepotBoundedPickupAndDeliveryExample.java index aa713d06..c4f33762 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SimpleDepotBoundedPickupAndDeliveryExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SimpleDepotBoundedPickupAndDeliveryExample.java @@ -56,7 +56,7 @@ public class SimpleDepotBoundedPickupAndDeliveryExample { * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" */ Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); + vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); vehicleBuilder.setType(vehicleType); Vehicle vehicle = vehicleBuilder.build(); diff --git a/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryExample.java b/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryExample.java index f5000532..3235baff 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryExample.java @@ -56,7 +56,7 @@ public class SimpleEnRoutePickupAndDeliveryExample { * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" */ Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); + vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); vehicleBuilder.setType(vehicleType); Vehicle vehicle = vehicleBuilder.build(); diff --git a/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryOpenRoutesExample.java b/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryOpenRoutesExample.java index 318035df..78a70a49 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryOpenRoutesExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryOpenRoutesExample.java @@ -56,7 +56,7 @@ public class SimpleEnRoutePickupAndDeliveryOpenRoutesExample { * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" */ Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); + vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); vehicleBuilder.setType(vehicleType); vehicleBuilder.setReturnToDepot(false); Vehicle vehicle = vehicleBuilder.build(); diff --git a/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryWithDepotBoundedDeliveriesExample.java b/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryWithDepotBoundedDeliveriesExample.java index a578acfc..4db4057e 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryWithDepotBoundedDeliveriesExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryWithDepotBoundedDeliveriesExample.java @@ -56,7 +56,7 @@ public class SimpleEnRoutePickupAndDeliveryWithDepotBoundedDeliveriesExample { * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" */ Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); + vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); vehicleBuilder.setType(vehicleType); Vehicle vehicle = vehicleBuilder.build(); diff --git a/jsprit-examples/src/main/java/jsprit/examples/SimpleExample.java b/jsprit-examples/src/main/java/jsprit/examples/SimpleExample.java index e8c0b2d9..dd6532f8 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SimpleExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SimpleExample.java @@ -56,7 +56,7 @@ public class SimpleExample { * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" */ Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); + vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); vehicleBuilder.setType(vehicleType); Vehicle vehicle = vehicleBuilder.build(); diff --git a/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.java b/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.java index 46546c2f..7203fa6a 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.java @@ -18,7 +18,7 @@ package jsprit.examples; import java.util.Collection; -import jsprit.analysis.toolbox.SolutionPlotter; +import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; @@ -55,7 +55,7 @@ public class SimpleExampleOpenRoutes { * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" */ Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); + vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); vehicleBuilder.setType(vehicleType); vehicleBuilder.setReturnToDepot(false); @@ -99,7 +99,9 @@ public class SimpleExampleOpenRoutes { /* * plot */ - SolutionPlotter.plotSolutionAsPNG(problem, bestSolution, "output/solution.png", "solution"); + + new Plotter(problem, bestSolution).plot("output/solution.png", "solution"); + } } diff --git a/jsprit-examples/src/main/java/jsprit/examples/SimpleVRPWithBackhaulsExample.java b/jsprit-examples/src/main/java/jsprit/examples/SimpleVRPWithBackhaulsExample.java index 17148987..c2ffc5ca 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SimpleVRPWithBackhaulsExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SimpleVRPWithBackhaulsExample.java @@ -57,7 +57,7 @@ public class SimpleVRPWithBackhaulsExample { * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType" */ Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle"); - vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); + vehicleBuilder.setStartLocationCoordinate(Coordinate.newInstance(10, 10)); vehicleBuilder.setType(vehicleType); Vehicle vehicle = vehicleBuilder.build(); diff --git a/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java b/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java index 9de7c4cf..854f3e36 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java @@ -21,7 +21,7 @@ import java.util.Collection; import jsprit.analysis.toolbox.GraphStreamViewer; import jsprit.analysis.toolbox.GraphStreamViewer.Label; import jsprit.analysis.toolbox.Plotter; -import jsprit.analysis.toolbox.SolutionPlotter; + import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.analysis.toolbox.SolutionPrinter.Print; import jsprit.core.algorithm.VehicleRoutingAlgorithm; @@ -58,7 +58,7 @@ public class SolomonExample { */ VehicleRoutingProblem vrp = vrpBuilder.build(); - SolutionPlotter.plotVrpAsPNG(vrp, "output/solomon_C101.png", "C101"); + new Plotter(vrp).plot("output/solomon_C101.png", "C101"); /* * Define the required vehicle-routing algorithms to solve the above problem. diff --git a/jsprit-examples/src/main/java/jsprit/examples/SolomonExampleWithSpecifiedVehicleEndLocations.java b/jsprit-examples/src/main/java/jsprit/examples/SolomonExampleWithSpecifiedVehicleEndLocations.java new file mode 100644 index 00000000..9cb6b2c5 --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/SolomonExampleWithSpecifiedVehicleEndLocations.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (C) 2013 Stefan Schroeder + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + ******************************************************************************/ +package jsprit.examples; + +import java.io.File; +import java.util.Collection; + +import jsprit.analysis.toolbox.AlgorithmSearchProgressChartListener; +import jsprit.analysis.toolbox.GraphStreamViewer; +import jsprit.analysis.toolbox.GraphStreamViewer.Label; +import jsprit.analysis.toolbox.Plotter; +import jsprit.analysis.toolbox.SolutionPrinter; +import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; +import jsprit.core.algorithm.selector.SelectBest; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.io.VrpXMLReader; +import jsprit.core.problem.solution.VehicleRoutingProblemSolution; + + +public class SolomonExampleWithSpecifiedVehicleEndLocations { + + public static void main(String[] args) { + /* + * some preparation - create output folder + */ + File dir = new File("output"); + // if the directory does not exist, create it + if (!dir.exists()){ + System.out.println("creating directory ./output"); + boolean result = dir.mkdir(); + if(result) System.out.println("./output created"); + } + + /* + * Build the problem. + * + * But define a problem-builder first. + */ + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + + /* + * A solomonReader reads solomon-instance files, and stores the required information in the builder. + */ + new VrpXMLReader(vrpBuilder).read("input/deliveries_solomon_specifiedVehicleEndLocations_c101.xml"); + + /* + * Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances). + */ + VehicleRoutingProblem vrp = vrpBuilder.build(); + + Plotter pblmPlotter = new Plotter(vrp); + pblmPlotter.plot("output/solomon_C101_specifiedVehicleEndLocations.png","C101"); + + /* + * Define the required vehicle-routing algorithms to solve the above problem. + * + * The algorithm can be defined and configured in an xml-file. + */ +// VehicleRoutingAlgorithm vra = new SchrimpfFactory().createAlgorithm(vrp); + VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig_fix.xml"); + vra.setNuOfIterations(20000); +// vra.setPrematureBreak(100); + vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/sol_progress.png")); + /* + * Solve the problem. + * + * + */ + Collection solutions = vra.searchSolutions(); + + /* + * Retrieve best solution. + */ + VehicleRoutingProblemSolution solution = new SelectBest().selectSolution(solutions); + + /* + * print solution + */ + SolutionPrinter.print(solution); + + /* + * Plot solution. + */ +// SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/solomon_C101_specifiedVehicleEndLocations_solution.png","C101"); + Plotter solPlotter = new Plotter(vrp, solution); + solPlotter.plot("output/solomon_C101_specifiedVehicleEndLocations_solution.png","C101"); + + + new GraphStreamViewer(vrp, solution).setRenderDelay(50).labelWith(Label.ID).setEnableAutoLayout(true).display(); + + + } + +} diff --git a/jsprit-examples/src/main/java/jsprit/examples/SolomonExampleWithSpecifiedVehicleEndLocationsWithoutTWs.java b/jsprit-examples/src/main/java/jsprit/examples/SolomonExampleWithSpecifiedVehicleEndLocationsWithoutTWs.java new file mode 100644 index 00000000..71dadb1f --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/SolomonExampleWithSpecifiedVehicleEndLocationsWithoutTWs.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (C) 2013 Stefan Schroeder + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + ******************************************************************************/ +package jsprit.examples; + +import java.io.File; +import java.util.Collection; + +import jsprit.analysis.toolbox.GraphStreamViewer; +import jsprit.analysis.toolbox.GraphStreamViewer.Label; +import jsprit.analysis.toolbox.Plotter; +import jsprit.analysis.toolbox.SolutionPrinter; +import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; +import jsprit.core.algorithm.selector.SelectBest; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.io.VrpXMLReader; +import jsprit.core.problem.solution.VehicleRoutingProblemSolution; + + +public class SolomonExampleWithSpecifiedVehicleEndLocationsWithoutTWs { + + public static void main(String[] args) { + /* + * some preparation - create output folder + */ + File dir = new File("output"); + // if the directory does not exist, create it + if (!dir.exists()){ + System.out.println("creating directory ./output"); + boolean result = dir.mkdir(); + if(result) System.out.println("./output created"); + } + + /* + * Build the problem. + * + * But define a problem-builder first. + */ + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + + /* + * A solomonReader reads solomon-instance files, and stores the required information in the builder. + */ + new VrpXMLReader(vrpBuilder).read("input/pickups_and_deliveries_solomon_c101_withoutTWs_and_specifiedVehicleEndLocations.xml"); + + /* + * Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances). + */ +// vrpBuilder.addProblemConstraint(Constraint.DELIVERIES_FIRST); + VehicleRoutingProblem vrp = vrpBuilder.build(); + + Plotter pblmPlotter = new Plotter(vrp); + pblmPlotter.plot("output/solomon_C101_specifiedVehicleEndLocations_withoutTWs.png","C101"); + + /* + * Define the required vehicle-routing algorithms to solve the above problem. + * + * The algorithm can be defined and configured in an xml-file. + */ +// VehicleRoutingAlgorithm vra = new SchrimpfFactory().createAlgorithm(vrp); + VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfigWithSchrimpfAcceptance.xml"); + vra.setNuOfIterations(20000); +// vra.setPrematureBreak(100); +// vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/sol_progress.png")); + /* + * Solve the problem. + * + * + */ + Collection solutions = vra.searchSolutions(); + + /* + * Retrieve best solution. + */ + VehicleRoutingProblemSolution solution = new SelectBest().selectSolution(solutions); + + /* + * print solution + */ + SolutionPrinter.print(solution); + + /* + * Plot solution. + */ +// SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/solomon_C101_specifiedVehicleEndLocations_solution.png","C101"); + Plotter solPlotter = new Plotter(vrp, solution); + solPlotter.plot("output/solomon_C101_specifiedVehicleEndLocations_withoutTWs_solution.png","C101"); + + + new GraphStreamViewer(vrp, solution).setRenderDelay(50).labelWith(Label.ID).setEnableAutoLayout(true).display(); + + + } + +} diff --git a/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java b/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java index 2278bffc..48228e7b 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java @@ -20,7 +20,9 @@ import java.util.Collection; import jsprit.analysis.toolbox.GraphStreamViewer; import jsprit.analysis.toolbox.GraphStreamViewer.Label; -import jsprit.analysis.toolbox.SolutionPlotter; + +import jsprit.analysis.toolbox.Plotter; + import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; @@ -56,7 +58,7 @@ public class SolomonOpenExample { */ VehicleRoutingProblem vrp = vrpBuilder.build(); - SolutionPlotter.plotVrpAsPNG(vrp, "output/solomon_C101_open.png", "C101"); + new Plotter(vrp).plot("output/solomon_C101_open.png", "C101"); /* * Define the required vehicle-routing algorithms to solve the above problem. diff --git a/jsprit-examples/src/main/java/jsprit/examples/SolomonR101Example.java b/jsprit-examples/src/main/java/jsprit/examples/SolomonR101Example.java index 309ba5a1..0be001d4 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SolomonR101Example.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SolomonR101Example.java @@ -18,7 +18,7 @@ package jsprit.examples; import java.util.Collection; -import jsprit.analysis.toolbox.SolutionPlotter; +import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; @@ -54,7 +54,7 @@ public class SolomonR101Example { */ VehicleRoutingProblem vrp = vrpBuilder.build(); - SolutionPlotter.plotVrpAsPNG(vrp, "output/solomon_R101.png", "R101"); + new Plotter(vrp).plot("output/solomon_R101.png", "R101"); /* * Define the required vehicle-routing algorithms to solve the above problem. @@ -85,9 +85,7 @@ public class SolomonR101Example { /* * Plot solution. */ - SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/solomon_R101_solution.png","R101"); - - + new Plotter(vrp,solution).plot( "output/solomon_R101_solution.png","R101"); } diff --git a/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample2.java b/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample2.java index cf6b586e..1bdffbcb 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample2.java +++ b/jsprit-examples/src/main/java/jsprit/examples/VRPWithBackhaulsExample2.java @@ -20,7 +20,6 @@ import java.util.Collection; import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.Plotter.Label; -import jsprit.analysis.toolbox.SolutionPlotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; @@ -63,7 +62,8 @@ public class VRPWithBackhaulsExample2 { */ VehicleRoutingProblem vrp = vrpBuilder.build(); - SolutionPlotter.plotVrpAsPNG(vrp, "output/vrpwbh_christophides_vrpnc1.png", "pd_vrpnc1"); + new Plotter(vrp).plot("output/vrpwbh_christophides_vrpnc1.png", "pd_vrpnc1"); + /* * Define the required vehicle-routing algorithms to solve the above problem.