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 02828d77..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,7 +252,7 @@ class CalculatorBuilder { actInsertionCalc = activityInsertionCostCalculator; } - ShipmentInsertionCalculator shipmentInsertion = new ShipmentInsertionCalculator(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(); 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..4c21eeb3 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); @@ -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 jobs = new ArrayList(); jobs.add(first); jobs.add(second); @@ -279,12 +249,11 @@ public class TestCalculatesServiceInsertion { @Test public void whenInsertingJobAndCurrRouteAndVehicleHaveTheSameLocation_accessEggressCalcShouldReturnZero(){ VehicleRoute route = VehicleRoute.Builder.newInstance(newVehicle, DriverImpl.noDriver()) - .addService(Service.Builder.newInstance("1", 0).setLocationId("1").setTimeWindow(TimeWindow.newInstance(0.0, 100.0)).build()) + .addService(first) .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); + JobInsertionContext iContex = new JobInsertionContext(route, first, newVehicle, mock(Driver.class), 0.0); assertEquals(0.0, accessEgressCalc.getCosts(iContex),0.01); } diff --git a/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java b/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java index 8ee6c648..fbcc7ca9 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java +++ b/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java @@ -239,7 +239,7 @@ public class BicycleMessenger { //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.setNuOfIterations(2000); Collection solutions = algorithm.searchSolutions(); //this is just to ensure that solution meet the above constraints diff --git a/jsprit-examples/src/main/java/jsprit/examples/EnRoutePickupAndDeliveryWithMultipleDepotsExample.java b/jsprit-examples/src/main/java/jsprit/examples/EnRoutePickupAndDeliveryWithMultipleDepotsExample.java index dfd69fd2..476346b6 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/EnRoutePickupAndDeliveryWithMultipleDepotsExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/EnRoutePickupAndDeliveryWithMultipleDepotsExample.java @@ -63,11 +63,20 @@ public class EnRoutePickupAndDeliveryWithMultipleDepotsExample { vehicleBuilder1.setType(vehicleType); Vehicle vehicle1 = vehicleBuilder1.build(); - Builder vehicleBuilder2 = VehicleImpl.Builder.newInstance("vehicles@[50,50]"); - vehicleBuilder2.setLocationCoord(Coordinate.newInstance(50, 50)); + Builder vehicleBuilder2 = VehicleImpl.Builder.newInstance("vehicles@[30,30]"); + vehicleBuilder2.setLocationCoord(Coordinate.newInstance(30, 30)); vehicleBuilder2.setType(vehicleType); Vehicle vehicle2 = vehicleBuilder2.build(); + Builder vehicleBuilder3 = VehicleImpl.Builder.newInstance("vehicles@[10,30]"); + vehicleBuilder3.setLocationCoord(Coordinate.newInstance(10, 30)); + vehicleBuilder3.setType(vehicleType); + Vehicle vehicle3 = vehicleBuilder3.build(); + + Builder vehicleBuilder4 = VehicleImpl.Builder.newInstance("vehicles@[30,10]"); + vehicleBuilder4.setLocationCoord(Coordinate.newInstance(30, 10)); + vehicleBuilder4.setType(vehicleType); + Vehicle vehicle4 = vehicleBuilder4.build(); /* * build shipments at the required locations, each with a capacity-demand of 1. @@ -84,17 +93,31 @@ public class EnRoutePickupAndDeliveryWithMultipleDepotsExample { 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(55, 57)).setDeliveryCoord(Coordinate.newInstance(56, 59)).build(); - Shipment shipment6 = Shipment.Builder.newInstance("6", 1).setPickupCoord(Coordinate.newInstance(55, 63)).setDeliveryCoord(Coordinate.newInstance(56, 61)).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(65, 57)).setDeliveryCoord(Coordinate.newInstance(64, 59)).build(); - Shipment shipment8 = Shipment.Builder.newInstance("8", 1).setPickupCoord(Coordinate.newInstance(65, 63)).setDeliveryCoord(Coordinate.newInstance(64, 61)).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); + 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(); @@ -102,8 +125,8 @@ public class EnRoutePickupAndDeliveryWithMultipleDepotsExample { /* * get the algorithm out-of-the-box. */ - VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(problem, "input/algorithmConfig_noVehicleSwitch.xml"); - algorithm.setNuOfIterations(30000); + VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(problem, "input/algorithmConfig.xml"); +// algorithm.setNuOfIterations(30000); /* * and search a solution */ 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..4e5dadd1 --- /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.setLocationCoord(Coordinate.newInstance(10, 10)); + vehicleBuilder1.setType(vehicleType); + Vehicle vehicle1 = vehicleBuilder1.build(); + + Builder vehicleBuilder2 = VehicleImpl.Builder.newInstance("vehicles@[50,50]"); + vehicleBuilder2.setLocationCoord(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(); + + } + +}