From 11eb5dc9837abe06527e012746847ddaf682deb7 Mon Sep 17 00:00:00 2001 From: oblonski Date: Thu, 6 Aug 2015 11:44:46 +0200 Subject: [PATCH] throw UnsupportedOperationEx when having breaks and infinite fleet - #170 --- .../core/problem/VehicleRoutingProblem.java | 10 ++- .../VariableStartAndWaitingTimeExample.java | 64 +++++++++++++------ 2 files changed, 53 insertions(+), 21 deletions(-) diff --git a/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java b/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java index 9f6db14c..038d3eca 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java @@ -94,6 +94,8 @@ public class VehicleRoutingProblem { private Set uniqueVehicles = new HashSet(); + private boolean hasBreaks = false; + private JobActivityFactory jobActivityFactory = new JobActivityFactory() { @Override @@ -254,15 +256,18 @@ public class VehicleRoutingProblem { activityMap.put(job, jobActs); } - private void addBreaksToActivityMap(){ + private boolean addBreaksToActivityMap(){ + boolean hasBreaks = false; for(Vehicle v : uniqueVehicles){ if(v.getBreak() != null){ + hasBreaks = true; AbstractActivity breakActivity = BreakActivity.newInstance(v.getBreak()); breakActivity.setIndex(activityIndexCounter); incActivityIndexCounter(); activityMap.put(v.getBreak(),Arrays.asList(breakActivity)); } } + return hasBreaks; } /** @@ -406,7 +411,8 @@ public class VehicleRoutingProblem { addJobToFinalJobMapAndCreateActivities(job); } } - addBreaksToActivityMap(); + boolean hasBreaks = addBreaksToActivityMap(); + if(hasBreaks && fleetSize.equals(FleetSize.INFINITE)) throw new UnsupportedOperationException("breaks are not yet supported when dealing with infinite fleet. either set it to finite or omit breaks."); return new VehicleRoutingProblem(this); } diff --git a/jsprit-examples/src/main/java/jsprit/examples/VariableStartAndWaitingTimeExample.java b/jsprit-examples/src/main/java/jsprit/examples/VariableStartAndWaitingTimeExample.java index 4320b816..041db797 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/VariableStartAndWaitingTimeExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/VariableStartAndWaitingTimeExample.java @@ -14,9 +14,11 @@ import jsprit.core.problem.constraint.ConstraintManager; import jsprit.core.problem.cost.TransportDistance; import jsprit.core.problem.job.Break; import jsprit.core.problem.job.Service; +import jsprit.core.problem.job.Shipment; import jsprit.core.problem.solution.SolutionCostCalculator; import jsprit.core.problem.solution.VehicleRoutingProblemSolution; import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.activity.BreakActivity; import jsprit.core.problem.solution.route.activity.TimeWindow; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.VehicleImpl; @@ -52,24 +54,24 @@ public class VariableStartAndWaitingTimeExample { VehicleImpl v2 = VehicleImpl.Builder.newInstance("v2").setType(type).setReturnToDepot(true) .setStartLocation(Location.newInstance(0, 0)) - .setEarliestStart(0).setLatestArrival(420) - .setBreak((Break) Break.Builder.newInstance("v2-break").setTimeWindow(TimeWindow.newInstance(50,70)).setServiceTime(100).build()) + .setEarliestStart(0).setLatestArrival(500) + .setBreak((Break) Break.Builder.newInstance("v2-break").setTimeWindow(TimeWindow.newInstance(100,150)).setServiceTime(50).build()) .build(); VehicleImpl v3 = VehicleImpl.Builder.newInstance("v3").setType(type2).setReturnToDepot(true) .setStartLocation(Location.newInstance(0.5, 10.5)) - .setBreak((Break) Break.Builder.newInstance("v3-break").setTimeWindow(TimeWindow.newInstance(50,70)).setServiceTime(100).build()) - .setEarliestStart(0).setLatestArrival(420) - .build(); - VehicleImpl v4 = VehicleImpl.Builder.newInstance("v4").setType(type3).setReturnToDepot(true) - .setStartLocation(Location.newInstance(7, 10.5)) - .setBreak((Break) Break.Builder.newInstance("v4-break").setTimeWindow(TimeWindow.newInstance(50,70)).setServiceTime(50).build()) - .setEarliestStart(0).setLatestArrival(420) - .build(); - VehicleImpl v5 = VehicleImpl.Builder.newInstance("v5").setType(type3).setReturnToDepot(true) - .setStartLocation(Location.newInstance(7, 10.5)) - .setBreak((Break) Break.Builder.newInstance("v5-break").setTimeWindow(TimeWindow.newInstance(300,350)).setServiceTime(20).build()) - .setEarliestStart(250).setLatestArrival(420) + .setBreak((Break) Break.Builder.newInstance("v3-break").setTimeWindow(TimeWindow.newInstance(100,150)).setServiceTime(50).build()) + .setEarliestStart(0).setLatestArrival(500) .build(); +// VehicleImpl v4 = VehicleImpl.Builder.newInstance("v4").setType(type3).setReturnToDepot(true) +// .setStartLocation(Location.newInstance(7, 10.5)) +// .setBreak((Break) Break.Builder.newInstance("v4-break").setTimeWindow(TimeWindow.newInstance(50,70)).setServiceTime(50).build()) +// .setEarliestStart(0).setLatestArrival(420) +// .build(); +// VehicleImpl v5 = VehicleImpl.Builder.newInstance("v5").setType(type3).setReturnToDepot(true) +// .setStartLocation(Location.newInstance(7, 10.5)) +// .setBreak((Break) Break.Builder.newInstance("v5-break").setTimeWindow(TimeWindow.newInstance(490,550)).setServiceTime(50).build()) +// .setEarliestStart(400).setLatestArrival(600) +// .build(); // VehicleImpl v4 = VehicleImpl.Builder.newInstance("v4").setType(type2).setReturnToDepot(true) // .setStartLocation(Location.newInstance(0, 0)).build(); VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); @@ -82,13 +84,32 @@ public class VariableStartAndWaitingTimeExample { .build(); vrpBuilder.addJob(s); } - Service s1 = Service.Builder.newInstance("s12").addSizeDimension(0,1).setLocation(Location.newInstance(-3, 15)).setTimeWindow(TimeWindow.newInstance(290, 600)).build(); - Service s4 = Service.Builder.newInstance("s13").addSizeDimension(0,1).setLocation(Location.newInstance(0, 20)).setTimeWindow(TimeWindow.newInstance(290, 340)).build(); - Service s2 = Service.Builder.newInstance("s10").addSizeDimension(0,1).setLocation(Location.newInstance(-1, 15)).setTimeWindow(TimeWindow.newInstance(300, 350)).build(); - Service s3 = Service.Builder.newInstance("s11").addSizeDimension(0,1).setLocation(Location.newInstance(10, 10)).setTimeWindow(TimeWindow.newInstance(300, 600)).build(); + Service s1 = Service.Builder.newInstance("s12").addSizeDimension(0,1).setLocation(Location.newInstance(-3, 15)).setTimeWindow(TimeWindow.newInstance(100, 600)).build(); + Service s4 = Service.Builder.newInstance("s13").addSizeDimension(0,1).setLocation(Location.newInstance(0, 20)).setTimeWindow(TimeWindow.newInstance(100, 340)).build(); + Service s2 = Service.Builder.newInstance("s10").addSizeDimension(0,1).setLocation(Location.newInstance(-1, 15)).setTimeWindow(TimeWindow.newInstance(100, 350)).build(); + Service s3 = Service.Builder.newInstance("s11").addSizeDimension(0,1).setLocation(Location.newInstance(10, 10)).setTimeWindow(TimeWindow.newInstance(100, 600)).build(); + + Shipment shipment1 = Shipment.Builder.newInstance("ship1").addSizeDimension(0, 1) + .setPickupLocation(Location.newInstance(5, 7)) + .setPickupTimeWindow(TimeWindow.newInstance(0, 600)) + .setDeliveryLocation(Location.newInstance(6, 9)).build(); + Shipment shipment2 = Shipment.Builder.newInstance("ship2").addSizeDimension(0, 1) + .setPickupTimeWindow(TimeWindow.newInstance(0, 600)) + .setPickupLocation(Location.newInstance(5, 13)).setDeliveryLocation(Location.newInstance(6, 11)).build(); + + Shipment shipment3 = Shipment.Builder.newInstance("ship3").addSizeDimension(0, 1) + .setPickupTimeWindow(TimeWindow.newInstance(0, 600)) + .setPickupLocation(Location.newInstance(15, 7)).setDeliveryLocation(Location.newInstance(14, 9)).build(); + Shipment shipment4 = Shipment.Builder.newInstance("ship4").addSizeDimension(0, 1) + .setPickupTimeWindow(TimeWindow.newInstance(0, 600)) + .setPickupLocation(Location.newInstance(15, 13)).setDeliveryLocation(Location.newInstance(14, 11)).build(); + + vrpBuilder .addJob(s1).addJob(s2).addJob(s3).addJob(s4) - .addVehicle(v2).addVehicle(v3).addVehicle(v4).addVehicle(v5); + .addJob(shipment1).addJob(shipment2).addJob(shipment3).addJob(shipment4) + .addVehicle(v2).addVehicle(v3); +// .addVehicle(v4).addVehicle(v5); vrpBuilder.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE); final VehicleRoutingProblem vrp = vrpBuilder.build(); @@ -118,14 +139,19 @@ public class VariableStartAndWaitingTimeExample { for (VehicleRoute route : solution.getRoutes()) { costs += route.getVehicle().getType().getVehicleCostParams().fix; TourActivity prevAct = route.getStart(); + boolean vehicleHasBreak = route.getVehicle().getBreak() != null; + boolean routeHasBreak = false; for (TourActivity act : route.getActivities()) { + if(act instanceof BreakActivity) routeHasBreak = true; costs += vrp.getTransportCosts().getTransportCost(prevAct.getLocation(), act.getLocation(), prevAct.getEndTime(), route.getDriver(), route.getVehicle()); costs += vrp.getActivityCosts().getActivityCost(act, act.getArrTime(), route.getDriver(), route.getVehicle()); prevAct = act; } + if(vehicleHasBreak && !routeHasBreak) costs += 200; costs += vrp.getTransportCosts().getTransportCost(prevAct.getLocation(), route.getEnd().getLocation(), prevAct.getEndTime(), route.getDriver(), route.getVehicle()); } costs += solution.getUnassignedJobs().size() * 200; + return costs; } })