When I set time-window to break constraint of vehicle (ex: from 20 to 25) and service time as 1, the output should be something between [20:25] and +1. But, it gives break first as [0:21] and then locations to visit. This is output:
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| 4 | vehicles@[30,10] | start | - | undef | 0 | 0 |
| 4 | vehicles@[30,10] | break | myFirstBreak2 | 0 | 21 | 0 |
| 4 | vehicles@[30,10] | pickupShipment | 16 | 27 | 27 | 6 |
| 4 | vehicles@[30,10] | deliverShipment | 16 | 29 | 29 | 8 |
| 4 | vehicles@[30,10] | pickupShipment | 15 | 33 | 33 | 12 |
| 4 | vehicles@[30,10] | deliverShipment | 15 | 35 | 35 | 14 |
| 4 | vehicles@[30,10] | pickupShipment | 13 | 45 | 45 | 24 |
| 4 | vehicles@[30,10] | deliverShipment | 13 | 47 | 47 | 26 |
| 4 | vehicles@[30,10] | pickupShipment | 14 | 51 | 51 | 30 |
| 4 | vehicles@[30,10] | deliverShipment | 14 | 53 | 53 | 32 |
| 4 | vehicles@[30,10] | end | - | 57 | undef | 36 |
+--------------------------------------------------------------------------------------------------------------------------------+
And this is without break:
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| 4 | vehicles@[30,10] | start | - | undef | 0 | 0 |
| 4 | vehicles@[30,10] | pickupShipment | 14 | 6 | 6 | 6 |
| 4 | vehicles@[30,10] | deliverShipment | 14 | 8 | 8 | 8 |
| 4 | vehicles@[30,10] | pickupShipment | 13 | 12 | 12 | 12 |
| 4 | vehicles@[30,10] | deliverShipment | 13 | 14 | 14 | 14 |
| 4 | vehicles@[30,10] | pickupShipment | 15 | 24 | 24 | 24 |
| 4 | vehicles@[30,10] | deliverShipment | 15 | 26 | 26 | 26 |
| 4 | vehicles@[30,10] | pickupShipment | 16 | 30 | 30 | 30 |
| 4 | vehicles@[30,10] | deliverShipment | 16 | 32 | 32 | 32 |
| 4 | vehicles@[30,10] | end | - | 36 | undef | 36 |
+--------------------------------------------------------------------------------------------------------------------------------+
So, the break should be somewhere between visit locations. Could you please, suggest whats wrong with the code?
My Code
public class RouteOptimizer {
public static void main(String[] args) {
/*
* 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")
.addCapacityDimension(0, 2);
vehicleTypeBuilder.setCostPerDistance(1.0);
VehicleType vehicleType = vehicleTypeBuilder.build();
/*
* define break
*
* todo which starts at [10, 15] and lasts long = 11
*/
Break myFirstBreak = Break.Builder.newInstance("myFirstBreak")
.setTimeWindow(TimeWindow.newInstance(10, 15)).build();
Break myFirstBreak2 = Break.Builder.newInstance("myFirstBreak2")
.setTimeWindow(TimeWindow.newInstance(20, 25)).setServiceTime(1).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.setStartLocation(loc(Coordinate.newInstance(10, 10))).setReturnToDepot(false);
// vehicleBuilder1.setBreak(myFirstBreak);
vehicleBuilder1.setType(vehicleType);
VehicleImpl vehicle1 = vehicleBuilder1.build();
Builder vehicleBuilder2 = VehicleImpl.Builder.newInstance("vehicles@[30,30]");
vehicleBuilder2.setStartLocation(loc(Coordinate.newInstance(30, 30))).setReturnToDepot(false);
// vehicleBuilder2.setEarliestStart(8);
// vehicleBuilder2.setLatestArrival(32);
vehicleBuilder2.setType(vehicleType);
VehicleImpl vehicle2 = vehicleBuilder2.build();
Builder vehicleBuilder3 = VehicleImpl.Builder.newInstance("vehicles@[10,30]");
vehicleBuilder3.setStartLocation(loc(Coordinate.newInstance(10, 30)));
vehicleBuilder3.setType(vehicleType);
VehicleImpl vehicle3 = vehicleBuilder3.build();
Builder vehicleBuilder4 = VehicleImpl.Builder.newInstance("vehicles@[30,10]");
vehicleBuilder4.setStartLocation(loc(Coordinate.newInstance(30, 10)));
vehicleBuilder4.setType(vehicleType);
vehicleBuilder4.setBreak(myFirstBreak2);
VehicleImpl vehicle4 = vehicleBuilder4.build();
/*
* build shipments at the required locations, each with a capacity-demand of 1.
*/
Shipment shipment1 = Shipment.Builder.newInstance("1").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(5, 7)))
.setDeliveryLocation(loc(Coordinate.newInstance(6, 9))).build();
// shipment1.getPickupTimeWindow()
// shipment1.pickupServiceTime
// shipment1.userData
// shipment1
Shipment shipment2 = Shipment.Builder.newInstance("2").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(5, 13)))
.setDeliveryLocation(loc(Coordinate.newInstance(6, 11))).build();
Shipment shipment3 = Shipment.Builder.newInstance("3").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(15, 7)))
.setDeliveryLocation(loc(Coordinate.newInstance(14, 9))).build();
Shipment shipment4 = Shipment.Builder.newInstance("4").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(15, 13)))
.setDeliveryLocation(loc(Coordinate.newInstance(14, 11))).build();
Shipment shipment5 = Shipment.Builder.newInstance("5").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(25, 27)))
.setDeliveryLocation(loc(Coordinate.newInstance(26, 29))).build();
Shipment shipment6 = Shipment.Builder.newInstance("6").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(25, 33)))
.setDeliveryLocation(loc(Coordinate.newInstance(26, 31))).build();
Shipment shipment7 = Shipment.Builder.newInstance("7").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(35, 27)))
.setDeliveryLocation(loc(Coordinate.newInstance(34, 29))).build();
Shipment shipment8 = Shipment.Builder.newInstance("8").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(35, 33)))
.setDeliveryLocation(loc(Coordinate.newInstance(34, 31))).build();
Shipment shipment9 = Shipment.Builder.newInstance("9").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(5, 27)))
.setDeliveryLocation(loc(Coordinate.newInstance(6, 29))).build();
Shipment shipment10 = Shipment.Builder.newInstance("10").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(5, 33)))
.setDeliveryLocation(loc(Coordinate.newInstance(6, 31))).build();
Shipment shipment11 = Shipment.Builder.newInstance("11").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(15, 27)))
.setDeliveryLocation(loc(Coordinate.newInstance(14, 29))).build();
Shipment shipment12 = Shipment.Builder.newInstance("12").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(15, 33)))
.setDeliveryLocation(loc(Coordinate.newInstance(14, 31))).build();
Shipment shipment13 = Shipment.Builder.newInstance("13").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(25, 7)))
.setDeliveryLocation(loc(Coordinate.newInstance(26, 9))).build();
Shipment shipment14 = Shipment.Builder.newInstance("14").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(25, 13)))
.setDeliveryLocation(loc(Coordinate.newInstance(26, 11))).build();
Shipment shipment15 = Shipment.Builder.newInstance("15").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(35, 7)))
.setDeliveryLocation(loc(Coordinate.newInstance(34, 9))).build();
Shipment shipment16 = Shipment.Builder.newInstance("16").addSizeDimension(0, 1)
.setPickupLocation(loc(Coordinate.newInstance(35, 13)))
.setDeliveryLocation(loc(Coordinate.newInstance(34, 11))).build();
/*
* pre-asign shipment to vehicle
*/
VehicleRoute initialRoute_withServices = VehicleRoute.Builder.newInstance(vehicle1).addPickup(shipment2)
.addDelivery(shipment2).build();
/*
* Asign job to builder
*/
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.addInitialVehicleRoute(initialRoute_withServices);
vrpBuilder.setFleetSize(FleetSize.FINITE);
VehicleRoutingProblem problem = vrpBuilder.build();
/*
* get the algorithm out-of-the-box.
*/
VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(problem);
// algorithm.setMaxIterations(30000);
/*
* and search a solution
*/
Collection<VehicleRoutingProblemSolution> solutions = algorithm.searchSolutions();
/*
* get the best
*/
VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions);
/*
* print nRoutes and totalCosts of bestSolution
*/
SolutionPrinter.print(problem, bestSolution, SolutionPrinter.Print.VERBOSE);
/*
* 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(bestSolution.getRoutes().iterator().next()));
solutionPlotter.plotShipments(true);
solutionPlotter.plot("output/enRoutePickupAndDeliveryWithMultipleLocationsExample_solution.png",
"en-route pickup and delivery");
new GraphStreamViewer(problem, bestSolution).labelWith(Label.ACTIVITY).setRenderDelay(0)
.setRenderShipments(true).display();
}
private static Location loc(Coordinate coordinate) {
return Location.Builder.newInstance().setCoordinate(coordinate).build();
}
}