From 4e25d894b63846018370485e3623c4deb43b1ce8 Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Wed, 27 Nov 2013 17:22:42 +0100 Subject: [PATCH 01/10] modify insertion to incorporate open-routes --- .../core/algorithm/recreate/Inserter.java | 20 +++ ...LocalActivityInsertionCostsCalculator.java | 8 ++ .../jsprit/core/problem/vehicle/Vehicle.java | 2 + .../core/problem/vehicle/VehicleImpl.java | 21 +++ .../core/algorithm/recreate/TestInserter.java | 7 + ...utePickupAndDeliveryOpenRoutesExample.java | 132 ++++++++++++++++++ .../examples/SimpleExampleOpenRoutes.java | 109 +++++++++++++++ 7 files changed, 299 insertions(+) create mode 100644 jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java create mode 100644 jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryOpenRoutesExample.java create mode 100644 jsprit-examples/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.java 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 6e73e670..aed0becb 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 @@ -62,10 +62,20 @@ class Inserter { if(job instanceof Service){ route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), this.activityFactory.createActivity((Service)job)); route.setDepartureTime(iData.getVehicleDepartureTime()); + if(!iData.getSelectedVehicle().isReturnToDepot()){ + if(iData.getDeliveryInsertionIndex()>=route.getTourActivities().getActivities().size()){ + setEndLocation(route,(Service)job); + } + } } else delegator.handleJobInsertion(job, iData, route); } + private void setEndLocation(VehicleRoute route, Service service) { + route.getEnd().setCoordinate(service.getCoord()); + route.getEnd().setLocationId(service.getLocationId()); + } + public void setNextHandler(JobInsertionHandler jobInsertionHandler){ this.delegator = jobInsertionHandler; } @@ -86,10 +96,20 @@ class Inserter { route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), deliverShipment); route.getTourActivities().addActivity(iData.getPickupInsertionIndex(), pickupShipment); route.setDepartureTime(iData.getVehicleDepartureTime()); + if(!iData.getSelectedVehicle().isReturnToDepot()){ + if(iData.getDeliveryInsertionIndex()>=route.getTourActivities().getActivities().size()){ + setEndLocation(route,(Shipment)job); + } + } } else delegator.handleJobInsertion(job, iData, route); } + private void setEndLocation(VehicleRoute route, Shipment shipment) { + route.getEnd().setCoordinate(shipment.getDeliveryCoord()); + route.getEnd().setLocationId(shipment.getDeliveryLocation()); + } + public void setNextHandler(JobInsertionHandler jobInsertionHandler){ this.delegator = jobInsertionHandler; } diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/LocalActivityInsertionCostsCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/LocalActivityInsertionCostsCalculator.java index 92dacfb9..56b755f0 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/LocalActivityInsertionCostsCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/LocalActivityInsertionCostsCalculator.java @@ -23,6 +23,7 @@ package jsprit.core.algorithm.recreate; import jsprit.core.problem.cost.VehicleRoutingActivityCosts; 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; @@ -61,6 +62,13 @@ class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCal double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); + //open routes + if(nextAct instanceof End){ + if(!iFacts.getNewVehicle().isReturnToDepot()){ + return new ActivityInsertionCosts(tp_costs_prevAct_newAct, tp_time_prevAct_newAct); + } + } + double tp_costs_newAct_nextAct = routingCosts.getTransportCost(newAct.getLocationId(), nextAct.getLocationId(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double tp_time_newAct_nextAct = routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); 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 0d178938..f846e201 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 @@ -35,5 +35,7 @@ public interface Vehicle { public abstract String getId(); public abstract int getCapacity(); + + public abstract boolean isReturnToDepot(); } 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 b7d53c1a..3be48623 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 @@ -54,6 +54,8 @@ public class VehicleImpl implements Vehicle { private double earliestStart = 0.0; private double latestArrival = Double.MAX_VALUE; + private boolean returnToDepot = true; + private VehicleType type = VehicleTypeImpl.Builder.newInstance("default", 0).build(); private Builder(String id) { @@ -66,6 +68,11 @@ public class VehicleImpl implements Vehicle { return this; } + public Builder setReturnToDepot(boolean returnToDepot){ + this.returnToDepot = returnToDepot; + return this; + } + public Builder setLocationId(String id){ this.locationId = id; return this; @@ -113,6 +120,8 @@ public class VehicleImpl implements Vehicle { private final double earliestDeparture; private final double latestArrival; + + private boolean returnToDepot; private VehicleImpl(Builder builder){ id = builder.id; @@ -121,6 +130,7 @@ public class VehicleImpl implements Vehicle { locationId = builder.locationId; earliestDeparture = builder.earliestStart; latestArrival = builder.latestArrival; + returnToDepot = builder.returnToDepot; } @@ -193,5 +203,16 @@ public class VehicleImpl implements Vehicle { public int getCapacity() { return type.getCapacity(); } + + + + /** + * @return the returnToDepot + */ + public boolean isReturnToDepot() { + return returnToDepot; + } + + } 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 new file mode 100644 index 00000000..20e28113 --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestInserter.java @@ -0,0 +1,7 @@ +package jsprit.core.algorithm.recreate; + +public class TestInserter { + + + +} diff --git a/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryOpenRoutesExample.java b/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryOpenRoutesExample.java new file mode 100644 index 00000000..4203e4aa --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryOpenRoutesExample.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * 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.Arrays; +import java.util.Collection; + +import jsprit.analysis.toolbox.Plotter; +import jsprit.analysis.toolbox.SolutionPrinter; +import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.box.SchrimpfFactory; +import jsprit.core.problem.VehicleRoutingProblem; +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; + + +public class SimpleEnRoutePickupAndDeliveryOpenRoutesExample { + + 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"); + } + + /* + * 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); + VehicleType vehicleType = vehicleTypeBuilder.build(); + + /* + * 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.setType(vehicleType); + vehicleBuilder.setReturnToDepot(false); + Vehicle vehicle = vehicleBuilder.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) + */ + + 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(); + + + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addVehicle(vehicle); + vrpBuilder.addJob(shipment1).addJob(shipment2).addJob(shipment3).addJob(shipment4); + + VehicleRoutingProblem problem = vrpBuilder.build(); + + /* + * get the algorithm out-of-the-box. + */ + VehicleRoutingAlgorithm algorithm = new SchrimpfFactory().createAlgorithm(problem); + + /* + * 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/simpleEnRoutePickupAndDeliveryExample_problem.png", "en-route pickup and delivery"); + + /* + * plot problem with solution + */ + Plotter solutionPlotter = new Plotter(problem,Solutions.bestOf(solutions).getRoutes()); + solutionPlotter.plotShipments(true); + solutionPlotter.plot("output/simpleEnRoutePickupAndDeliveryExample_solution.png", "en-route pickup and delivery"); + + } + +} diff --git a/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.java b/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.java new file mode 100644 index 00000000..1bc409b7 --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.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.SolutionPlotter; +import jsprit.analysis.toolbox.SolutionPrinter; +import jsprit.core.algorithm.VehicleRoutingAlgorithm; +import jsprit.core.algorithm.box.SchrimpfFactory; +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; + + +public class SimpleExampleOpenRoutes { + + 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"); + } + + /* + * 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); + VehicleType vehicleType = vehicleTypeBuilder.build(); + + /* + * 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.setType(vehicleType); + vehicleBuilder.setReturnToDepot(false); + Vehicle vehicle = vehicleBuilder.build(); + + /* + * build services at the required locations, each with a capacity-demand of 1. + */ + Service service1 = Service.Builder.newInstance("1", 1).setCoord(Coordinate.newInstance(5, 7)).build(); + Service service2 = Service.Builder.newInstance("2", 1).setCoord(Coordinate.newInstance(5, 13)).build(); + + Service service3 = Service.Builder.newInstance("3", 1).setCoord(Coordinate.newInstance(15, 7)).build(); + Service service4 = Service.Builder.newInstance("4", 1).setCoord(Coordinate.newInstance(15, 13)).build(); + + + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + vrpBuilder.addVehicle(vehicle); + vrpBuilder.addJob(service1).addJob(service2).addJob(service3).addJob(service4); + + VehicleRoutingProblem problem = vrpBuilder.build(); + + /* + * get the algorithm out-of-the-box. + */ + VehicleRoutingAlgorithm algorithm = new SchrimpfFactory().createAlgorithm(problem); + + /* + * and search a solution + */ + Collection solutions = algorithm.searchSolutions(); + + /* + * get the best + */ + VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions); + + new VrpXMLWriter(problem, solutions).write("output/problem-with-solution.xml"); + + SolutionPrinter.print(bestSolution); + + /* + * plot + */ + SolutionPlotter.plotSolutionAsPNG(problem, bestSolution, "output/solution.png", "solution"); + } + +} From f662e5a4699b3eef06db78b382a5dd621275e79d Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Fri, 29 Nov 2013 08:27:30 +0100 Subject: [PATCH 02/10] modify reader/writer to deal with open routes and add examples --- .../core/algorithm/recreate/Inserter.java | 10 +- .../jsprit/core/problem/io/VrpXMLReader.java | 13 +- .../jsprit/core/problem/io/VrpXMLWriter.java | 1 + .../problem/solution/route/VehicleRoute.java | 35 +- .../src/main/resources/vrp_xml_schema.xsd | 2 +- jsprit-examples/input/algorithmConfig_fix.xml | 49 + .../input/deliveries_solomon_open_c101.xml | 1236 +++++++++++++++++ .../examples/SimpleExampleOpenRoutes.java | 5 +- .../jsprit/examples/SolomonOpenExample.java | 101 ++ 9 files changed, 1434 insertions(+), 18 deletions(-) create mode 100755 jsprit-examples/input/algorithmConfig_fix.xml create mode 100644 jsprit-examples/input/deliveries_solomon_open_c101.xml create mode 100644 jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java 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 aed0becb..9ea0f15f 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.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), this.activityFactory.createActivity((Service)job)); - route.setDepartureTime(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); } @@ -93,14 +93,14 @@ class Inserter { if(job instanceof Shipment){ TourActivity pickupShipment = this.activityFactory.createPickup((Shipment)job); TourActivity deliverShipment = this.activityFactory.createDelivery((Shipment)job); - route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), deliverShipment); - route.getTourActivities().addActivity(iData.getPickupInsertionIndex(), pickupShipment); - route.setDepartureTime(iData.getVehicleDepartureTime()); if(!iData.getSelectedVehicle().isReturnToDepot()){ if(iData.getDeliveryInsertionIndex()>=route.getTourActivities().getActivities().size()){ setEndLocation(route,(Shipment)job); } } + route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), deliverShipment); + route.getTourActivities().addActivity(iData.getPickupInsertionIndex(), pickupShipment); + route.setDepartureTime(iData.getVehicleDepartureTime()); } else delegator.handleJobInsertion(job, iData, route); } 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 b6e15ab6..ab45c336 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 @@ -230,14 +230,19 @@ public class VrpXMLReader{ if(vehicle == null) throw new IllegalStateException("vehicle is missing."); String start = routeConfig.getString("start"); if(start == null) throw new IllegalStateException("route start-time is missing."); + double departureTime = Double.parseDouble(start); + String end = routeConfig.getString("end"); if(end == null) throw new IllegalStateException("route end-time is missing."); - Start startAct = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); - startAct.setEndTime(Double.parseDouble(start)); + +// Start startAct = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); +// startAct.setEndTime(Double.parseDouble(start)); End endAct = End.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); endAct.setArrTime(Double.parseDouble(end)); VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle, driver); + routeBuilder.setDepartureTime(departureTime); + routeBuilder.setRouteEndArrivalTime(Double.parseDouble(end)); List actConfigs = routeConfig.configurationsAt("act"); for(HierarchicalConfiguration actConfig : actConfigs){ String type = actConfig.getString("[@type]"); @@ -466,6 +471,10 @@ public class VrpXMLReader{ String end = vehicleConfig.getString("timeSchedule.end"); if(start != null) builder.setEarliestStart(Double.parseDouble(start)); if(end != null) builder.setLatestArrival(Double.parseDouble(end)); + String returnToDepot = vehicleConfig.getString("returnToDepot"); + if(returnToDepot != null){ + builder.setReturnToDepot(vehicleConfig.getBoolean("returnToDepot")); + } VehicleImpl vehicle = builder.build(); vrpBuilder.addVehicle(vehicle); vehicleMap.put(vehicleId, vehicle); 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 6167b29f..64643d6c 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 @@ -234,6 +234,7 @@ public class VrpXMLWriter { xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.start", vehicle.getEarliestDeparture()); xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.end", vehicle.getLatestArrival()); + xmlConfig.setProperty(vehiclePathString + "("+counter+").returnToDepot", vehicle.isReturnToDepot()); counter++; } 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 22695b9d..424aaa40 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 @@ -61,6 +61,8 @@ public class VehicleRoute { private Start start; + private End end; + private TourActivities tourActivities = new TourActivities(); private TourActivityFactory serviceActivityFactory = new DefaultTourActivityFactory(); @@ -79,6 +81,10 @@ 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 * @param vehicle * @param driver */ @@ -88,7 +94,7 @@ public class VehicleRoute { this.driver = driver; start = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); start.setEndTime(vehicle.getEarliestDeparture()); - End.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); + end = End.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); } /** @@ -102,6 +108,11 @@ public class VehicleRoute { return this; } + public Builder setRouteEndArrivalTime(double endTime){ + end.setArrTime(endTime); + return this; + } + public Builder addService(Service service){ addService(service,0.0,0.0); return this; @@ -185,7 +196,12 @@ public class VehicleRoute { if(!openShipments.isEmpty()){ throw new IllegalStateException("there are still shipments that have not been delivered yet."); } - VehicleRoute route = VehicleRoute.newInstance(tourActivities, driver, vehicle); + if(!vehicle.isReturnToDepot()){ + if(!tourActivities.isEmpty()){ + end.setLocationId(tourActivities.getActivities().get(tourActivities.getActivities().size()-1).getLocationId()); + } + } + VehicleRoute route = new VehicleRoute(this); return route; } @@ -218,13 +234,14 @@ public class VehicleRoute { setStartAndEnd(vehicle, vehicle.getEarliestDeparture()); } -// private VehicleRoute(Builder builder){ -// this.tourActivities = builder.tour; -// this.vehicle = builder.vehicle; -// this.driver = builder.driver; -// this.start = builder.start; -// this.end = builder.end; -// } + + private VehicleRoute(Builder builder){ + this.tourActivities = builder.tourActivities; + this.vehicle = builder.vehicle; + this.driver = builder.driver; + this.start = builder.start; + this.end = builder.end; + } 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." + diff --git a/jsprit-core/src/main/resources/vrp_xml_schema.xsd b/jsprit-core/src/main/resources/vrp_xml_schema.xsd index 04edd787..f1722126 100644 --- a/jsprit-core/src/main/resources/vrp_xml_schema.xsd +++ b/jsprit-core/src/main/resources/vrp_xml_schema.xsd @@ -53,7 +53,7 @@ - + diff --git a/jsprit-examples/input/algorithmConfig_fix.xml b/jsprit-examples/input/algorithmConfig_fix.xml new file mode 100755 index 00000000..b7ffdd9c --- /dev/null +++ b/jsprit-examples/input/algorithmConfig_fix.xml @@ -0,0 +1,49 @@ + + + + + 2000 + + + + 1.0 + + + + + 1 + + + + + + + + + 0.5 + + + + + 0.5 + + + + + + + + + 0.3 + + + + + 0.5 + + + + + + diff --git a/jsprit-examples/input/deliveries_solomon_open_c101.xml b/jsprit-examples/input/deliveries_solomon_open_c101.xml new file mode 100644 index 00000000..6dd2ab3f --- /dev/null +++ b/jsprit-examples/input/deliveries_solomon_open_c101.xml @@ -0,0 +1,1236 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 0.0 + 1236.0 + + false + + + + + solomonType + 200 + + 0.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/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.java b/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.java index 1bc409b7..21599f2b 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SimpleExampleOpenRoutes.java @@ -23,6 +23,7 @@ import jsprit.analysis.toolbox.SolutionPlotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.box.SchrimpfFactory; +import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.io.VrpXMLWriter; import jsprit.core.problem.job.Service; @@ -54,6 +55,7 @@ public class SimpleExampleOpenRoutes { * 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.setFixedCost(100); VehicleType vehicleType = vehicleTypeBuilder.build(); /* @@ -63,6 +65,7 @@ public class SimpleExampleOpenRoutes { vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); vehicleBuilder.setType(vehicleType); vehicleBuilder.setReturnToDepot(false); + Vehicle vehicle = vehicleBuilder.build(); /* @@ -84,7 +87,7 @@ public class SimpleExampleOpenRoutes { /* * get the algorithm out-of-the-box. */ - VehicleRoutingAlgorithm algorithm = new SchrimpfFactory().createAlgorithm(problem); + VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(problem, "input/algorithmConfig_fix.xml"); /* * and search a solution diff --git a/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java b/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java new file mode 100644 index 00000000..6cba5e5c --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * 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.SolutionPlotter; +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; +import jsprit.instance.reader.SolomonReader; + + +public class SolomonOpenExample { + + 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_open_c101.xml"); + + /* + * Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances). + */ + VehicleRoutingProblem vrp = vrpBuilder.build(); + + SolutionPlotter.plotVrpAsPNG(vrp, "output/solomon_C101_open.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.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_open_solution.png","C101"); + + + + } + +} From 2291bd23c213ad5a9a2a9b7b8b25b73da5fd0ab5 Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Fri, 29 Nov 2013 11:59:02 +0100 Subject: [PATCH 03/10] add Examples and testTemplate for open-routes --- .../TestCalculatesServiceInsertion.java | 8 +- ...alculatesServiceInsertionOnRouteLevel.java | 7 + .../route/VehicleRouteBuilderTest.java | 16 + .../test/resources/infiniteWriterV2Test.xml | 2 + .../input/algorithmConfig_open.xml | 71 + ...eliveries_solomon_r101_withoutTWs_open.xml | 1236 +++++++++++++++++ .../examples/PickupAndDeliveryExample.java | 2 +- .../PickupAndDeliveryOpenExample.java | 108 ++ 8 files changed, 1448 insertions(+), 2 deletions(-) create mode 100755 jsprit-examples/input/algorithmConfig_open.xml create mode 100644 jsprit-examples/input/pickups_and_deliveries_solomon_r101_withoutTWs_open.xml create mode 100644 jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryOpenExample.java 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 5ee1abf7..c634b076 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 @@ -16,6 +16,7 @@ ******************************************************************************/ package jsprit.core.algorithm.recreate; +import static org.junit.Assert.*; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -80,12 +81,14 @@ public class TestCalculatesServiceInsertion { when(vehicle.getLocationId()).thenReturn("depot"); 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("depot"); when(newVehicle.getEarliestDeparture()).thenReturn(0.0); when(newVehicle.getLatestArrival()).thenReturn(100.0); + when(newVehicle.isReturnToDepot()).thenReturn(true); driver = DriverImpl.noDriver(); @@ -264,6 +267,9 @@ public class TestCalculatesServiceInsertion { assertEquals(2, iData.getDeliveryInsertionIndex()); } - + @Test + public void whenInsertingAndRouteIsOpen(){ + assertTrue(false); + } } 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 46e7f430..0c621a74 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 @@ -17,6 +17,7 @@ package jsprit.core.algorithm.recreate; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -239,4 +240,10 @@ public class TestCalculatesServiceInsertionOnRouteLevel { assertEquals(2, iData.getDeliveryInsertionIndex()); } + @Test + public void whenInsertingAndRouteIsOpen(){ + assertTrue(false); + } + + } 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 b9219432..5d998aaa 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 @@ -1,5 +1,6 @@ package jsprit.core.problem.solution.route; +import static org.junit.Assert.*; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import jsprit.core.problem.driver.Driver; @@ -58,4 +59,19 @@ public class VehicleRouteBuilderTest { assertEquals(4,route.getTourActivities().getActivities().size()); } + @Test + public void whenBuildingOpenRoute(){ + assertTrue(false); + } + + @Test + public void whenSettingDepartureTime(){ + assertTrue(false); + } + + + @Test + public void whenSettingEndTime(){ + assertTrue(false); + } } diff --git a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml index ec10a45f..4d5bf129 100644 --- a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml +++ b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml @@ -16,6 +16,7 @@ 0.0 1.7976931348623157E308 + true v2 @@ -27,6 +28,7 @@ 0.0 1.7976931348623157E308 + true diff --git a/jsprit-examples/input/algorithmConfig_open.xml b/jsprit-examples/input/algorithmConfig_open.xml new file mode 100755 index 00000000..e66a2ac3 --- /dev/null +++ b/jsprit-examples/input/algorithmConfig_open.xml @@ -0,0 +1,71 @@ + + + + + 2000 + + + + + + + + + 1 + + + + + + + + + 0.5 + + + + + + 0.5 + + + + + + + + + + 0.3 + + + + + + 0.5 + + + + + + diff --git a/jsprit-examples/input/pickups_and_deliveries_solomon_r101_withoutTWs_open.xml b/jsprit-examples/input/pickups_and_deliveries_solomon_r101_withoutTWs_open.xml new file mode 100644 index 00000000..46fba629 --- /dev/null +++ b/jsprit-examples/input/pickups_and_deliveries_solomon_r101_withoutTWs_open.xml @@ -0,0 +1,1236 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 0.0 + 230.0 + + false + + + + + solomonType + 200 + + 0.0 + 1.0 + + + + + + + [x=63.0][y=65.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=2.0][y=60.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=52.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=55.0] + + 14 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=12.0] + + 31 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=20.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=5.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=23.0][y=3.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=24.0][y=12.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=7.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=25.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=10.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=5.0] + + 29 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=35.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=20.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=30.0] + + 17 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=40.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=41.0][y=37.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=64.0][y=42.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=45.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=17.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=41.0][y=49.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=60.0] + + 21 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=50.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=30.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=30.0] + + 26 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=69.0] + + 23 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=20.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=52.0] + + 27 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=60.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=43.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=60.0] + + 17 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=30.0] + + 2 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=40.0] + + 12 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=5.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=20.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=25.0] + + 23 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=10.0] + + 20 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=65.0] + + 12 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=50.0][y=35.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=20.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=65.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=26.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=18.0][y=18.0] + + 17 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=19.0][y=21.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=21.0] + + 12 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=22.0][y=27.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=24.0] + + 20 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=27.0] + + 27 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=18.0][y=24.0] + + 22 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=22.0][y=22.0] + + 2 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=19.0] + + 1 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=67.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=60.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=52.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=35.0] + + 15 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=48.0] + + 23 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=61.0][y=52.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=43.0] + + 14 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=47.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=14.0][y=37.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=56.0][y=37.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=54.0] + + 26 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=4.0][y=18.0] + + 35 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=18.0] + + 26 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=11.0][y=31.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=16.0][y=22.0] + + 41 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=67.0][y=5.0] + + 25 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=73.0] + + 25 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=47.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=56.0][y=39.0] + + 36 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=56.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=68.0] + + 15 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=47.0][y=16.0] + + 25 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=44.0][y=17.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=46.0][y=13.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=11.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=42.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=21.0][y=24.0] + + 28 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=36.0][y=26.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=12.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=12.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=63.0][y=23.0] + + 2 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=77.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=62.0][y=77.0] + + 20 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=24.0][y=58.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=69.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=34.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=12.0][y=24.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=6.0][y=68.0] + + 30 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=13.0][y=52.0] + + 36 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=6.0][y=38.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=11.0][y=14.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=56.0] + + 27 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=2.0][y=48.0] + + 1 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=58.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=43.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=31.0] + + 14 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=29.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=47.0][y=47.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + diff --git a/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample.java b/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample.java index 30399f20..04aafdaa 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryExample.java @@ -57,7 +57,7 @@ public class PickupAndDeliveryExample { /* * A solomonReader reads solomon-instance files, and stores the required information in the builder. */ - new VrpXMLReader(vrpBuilder).read("input/pickups_and_deliveries_solomon_r101.xml"); + new VrpXMLReader(vrpBuilder).read("input/pickups_and_deliveries_solomon_r101_withoutTWs.xml"); /* * Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances). diff --git a/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryOpenExample.java b/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryOpenExample.java new file mode 100644 index 00000000..340b595e --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/PickupAndDeliveryOpenExample.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * 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.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; +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 PickupAndDeliveryOpenExample { + + 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_r101_withoutTWs_open.xml"); + + /* + * Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances). + */ + + VehicleRoutingProblem vrp = vrpBuilder.build(); + +// SolutionPlotter.plotVrpAsPNG(vrp, "output/pd_solomon_r101_o.png", "pd_r101"); + + /* + * 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_open.xml"); + 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/pd_solomon_r101_solution.png","pd_r101"); + Plotter plotter = new Plotter(vrp, solution); + plotter.setLabel(Label.SIZE); + plotter.setShowFirstActivity(true); + plotter.plot("output/pd_solomon_r101_solution_open.png","pd_r101"); + + + + } + +} From 381e3489266519007df08a6dd56015198efbe556 Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Fri, 29 Nov 2013 15:03:01 +0100 Subject: [PATCH 04/10] add bicycle-messenger-example --- .../input/bicycle_messenger_demand.txt | 31 +++++++ .../input/bicycle_messenger_supply.txt | 6 ++ .../jsprit/examples/BicycleMessenger.java | 87 +++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 jsprit-examples/input/bicycle_messenger_demand.txt create mode 100644 jsprit-examples/input/bicycle_messenger_supply.txt create mode 100644 jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java diff --git a/jsprit-examples/input/bicycle_messenger_demand.txt b/jsprit-examples/input/bicycle_messenger_demand.txt new file mode 100644 index 00000000..42890e1b --- /dev/null +++ b/jsprit-examples/input/bicycle_messenger_demand.txt @@ -0,0 +1,31 @@ +item id pickup_x pickup_y deliver_x deliver_y +envelope 1 13745 55419 13883 55756 +envelope 2 8406 53246 13937 55854 +envelope 3 15738 57396 35996 79499 +envelope 4 12045 60418 19349 57118 +envelope 5 13750 56416 35733 78403 +envelope 6 13190 57068 11860 59749 +envelope 7 15021 55768 14098 57379 +envelope 8 11513 58543 11501 59683 +envelope 9 12013 64155 14120 59301 +envelope 10 15006 57578 35511 78426 +envelope 11 11450 58819 11916 58338 +envelope 12 13728 56304 35524 79013 +envelope 13 15104 60923 17937 57066 +envelope 14 11373 58388 13983 53804 +envelope 15 18575 55186 18718 54381 +envelope 16 11639 50071 17363 58375 +envelope 17 11273 53410 10860 60441 +envelope 18 13766 59041 13963 57769 +envelope 19 16138 55801 16183 56024 +envelope 20 13728 56146 14301 61694 +envelope 21 12848 57059 13586 59734 +envelope 22 13645 56488 13955 55859 +envelope 23 12896 56838 13937 55908 +envelope 24 13341 58150 35709 78924 +envelope 25 13483 57303 13614 57820 +envelope 26 12741 63478 15230 59838 +envelope 27 14676 51691 16501 48361 +envelope 28 13748 54933 14120 56110 +envelope 29 17875 59565 20453 61903 +envelope 30 9772 56424 6404 55601 \ No newline at end of file diff --git a/jsprit-examples/input/bicycle_messenger_supply.txt b/jsprit-examples/input/bicycle_messenger_supply.txt new file mode 100644 index 00000000..f25f8b66 --- /dev/null +++ b/jsprit-examples/input/bicycle_messenger_supply.txt @@ -0,0 +1,6 @@ +type id x y +messenger A 13750 57578 +messenger B 15104 53410 +messenger C 13728 55801 +messenger D 12741 63478 +messenger E 14676 18575 \ No newline at end of file diff --git a/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java b/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java new file mode 100644 index 00000000..123834d9 --- /dev/null +++ b/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java @@ -0,0 +1,87 @@ +package jsprit.examples; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Collection; + +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.termination.IterationWithoutImprovementTermination; +import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.VehicleRoutingProblem.Builder; +import jsprit.core.problem.VehicleRoutingProblem.FleetSize; +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.VehicleType; +import jsprit.core.problem.vehicle.VehicleTypeImpl; +import jsprit.core.util.Coordinate; +import jsprit.core.util.Solutions; + +public class BicycleMessenger { + + /** + * @param args + * @throws IOException + */ + public static void main(String[] args) throws IOException { + + VehicleRoutingProblem.Builder problemBuilder = VehicleRoutingProblem.Builder.newInstance(); + readEnvelopes(problemBuilder); + readMessengers(problemBuilder); + problemBuilder.setFleetSize(FleetSize.FINITE); + + VehicleRoutingProblem bicycleMessengerProblem = problemBuilder.build(); + + VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(bicycleMessengerProblem, 6, "input/algorithmConfig_open.xml"); + algorithm.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(50)); + Collection solutions = algorithm.searchSolutions(); + + SolutionPrinter.print(Solutions.bestOf(solutions)); + Plotter plotter = new Plotter(bicycleMessengerProblem); + plotter.plotShipments(true); + plotter.plot("output/bicycleMessengerProblem.png", "bicycleMenssenger"); + + + Plotter plotter1 = new Plotter(bicycleMessengerProblem, Solutions.bestOf(solutions)); + plotter1.plotShipments(false); + plotter1.plot("output/bicycleMessengerSolution.png", "bicycleMenssenger"); + + + } + + private static void readEnvelopes(Builder problemBuilder) throws IOException { + BufferedReader reader = new BufferedReader(new FileReader(new File("input/bicycle_messenger_demand.txt"))); + String line = null; + boolean firstLine = true; + while((line = reader.readLine()) != null){ + if(firstLine) { firstLine = false; continue; } + String[] tokens = line.split("\\s+"); + Shipment envelope = Shipment.Builder.newInstance(tokens[1], 1).setPickupCoord(Coordinate.newInstance(Double.parseDouble(tokens[2]), Double.parseDouble(tokens[3]))) + .setDeliveryCoord(Coordinate.newInstance(Double.parseDouble(tokens[4]), Double.parseDouble(tokens[5]))).build(); + problemBuilder.addJob(envelope); + } + reader.close(); + } + + private static void readMessengers(Builder problemBuilder) throws IOException { + BufferedReader reader = new BufferedReader(new FileReader(new File("input/bicycle_messenger_supply.txt"))); + String line = null; + boolean firstLine = true; + VehicleType messengerType = VehicleTypeImpl.Builder.newInstance("messengerType", 15).setCostPerDistance(1).build(); + while((line = reader.readLine()) != null){ + if(firstLine) { firstLine = false; continue; } + String[] tokens = line.split("\\s+"); + Vehicle vehicle = VehicleImpl.Builder.newInstance(tokens[1]).setLocationCoord(Coordinate.newInstance(Double.parseDouble(tokens[2]), Double.parseDouble(tokens[3]))) + .setReturnToDepot(false).setType(messengerType).build(); + problemBuilder.addVehicle(vehicle); + } + reader.close(); + } + +} From 9af21094bf95ae3e766f4f8e1883f8d873c743b2 Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Fri, 29 Nov 2013 16:59:44 +0100 Subject: [PATCH 05/10] add zoom to plotter, i.e. add plotter.setBoundaryBox(...) --- .../java/jsprit/analysis/toolbox/Plotter.java | 45 ++++++++++++++++--- .../java/jsprit/examples/SolomonExample.java | 6 ++- 2 files changed, 44 insertions(+), 7 deletions(-) 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 4e494bd1..8849f6ae 100644 --- a/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java +++ b/jsprit-analysis/src/main/java/jsprit/analysis/toolbox/Plotter.java @@ -50,6 +50,7 @@ import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.chart.title.LegendTitle; +import org.jfree.data.Range; import org.jfree.data.xy.XYDataItem; import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries; @@ -59,6 +60,21 @@ import org.jfree.ui.RectangleEdge; public class Plotter { + private static class BoundingBox { + double minX; + double minY; + double maxX; + double maxY; + public BoundingBox(double minX, double minY, double maxX, double maxY) { + super(); + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + + } + private static class NoLocationFoundException extends Exception{ /** @@ -87,6 +103,8 @@ public class Plotter { private Collection routes; + private BoundingBox boundingBox = null; + public void setShowFirstActivity(boolean show){ showFirstActivity = show; } @@ -94,6 +112,10 @@ public class Plotter { public void setLabel(Label label){ this.label = label; } + + public void setBoundingBox(double minX, double minY, double maxX, double maxY){ + boundingBox = new BoundingBox(minX,minY,maxX,maxY); + } public Plotter(VehicleRoutingProblem vrp) { super(); @@ -198,7 +220,7 @@ public class Plotter { } - private static XYPlot createProblemPlot(final XYSeriesCollection problem, XYSeriesCollection shipments, final Map labels) { + private XYPlot createProblemPlot(final XYSeriesCollection problem, XYSeriesCollection shipments, final Map labels) { XYPlot plot = new XYPlot(); plot.setBackgroundPaint(Color.LIGHT_GRAY); plot.setRangeGridlinePaint(Color.WHITE); @@ -216,11 +238,12 @@ public class Plotter { problemRenderer.setBaseItemLabelsVisible(true); problemRenderer.setBaseItemLabelPaint(Color.BLACK); - NumberAxis xAxis = new NumberAxis(); - xAxis.setRangeWithMargins(problem.getDomainBounds(true)); + NumberAxis xAxis = new NumberAxis(); + + xAxis.setRangeWithMargins(getDomainRange(problem)); NumberAxis yAxis = new NumberAxis(); - yAxis.setRangeWithMargins(problem.getRangeBounds(false)); + yAxis.setRangeWithMargins(getRange(problem)); plot.setDataset(0, problem); plot.setRenderer(0, problemRenderer); @@ -245,6 +268,16 @@ public class Plotter { return plot; } + private Range getRange(final XYSeriesCollection problem) { + if(this.boundingBox==null) return problem.getRangeBounds(false); + else return new Range(boundingBox.minY, boundingBox.maxY); + } + + private Range getDomainRange(final XYSeriesCollection problem) { + if(this.boundingBox == null) return problem.getDomainBounds(true); + else return new Range(boundingBox.minX, boundingBox.maxX); + } + private XYPlot createProblemSolutionPlot(final XYSeriesCollection problem, XYSeriesCollection shipments, XYSeriesCollection solutionColl, final Map labels) { XYPlot plot = new XYPlot(); plot.setBackgroundPaint(Color.LIGHT_GRAY); @@ -264,10 +297,10 @@ public class Plotter { problemRenderer.setBaseItemLabelPaint(Color.BLACK); NumberAxis xAxis = new NumberAxis(); - xAxis.setRangeWithMargins(problem.getDomainBounds(true)); + xAxis.setRangeWithMargins(getDomainRange(problem)); NumberAxis yAxis = new NumberAxis(); - yAxis.setRangeWithMargins(problem.getRangeBounds(true)); + yAxis.setRangeWithMargins(getRange(problem)); plot.setDataset(0, problem); plot.setRenderer(0, problemRenderer); diff --git a/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java b/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java index 9aaa823c..6cabfe27 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java @@ -19,6 +19,7 @@ package jsprit.examples; import java.io.File; import java.util.Collection; +import jsprit.analysis.toolbox.Plotter; import jsprit.analysis.toolbox.SolutionPlotter; import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.core.algorithm.VehicleRoutingAlgorithm; @@ -91,7 +92,10 @@ public class SolomonExample { /* * Plot solution. */ - SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/solomon_C101_solution.png","C101"); + Plotter plotter = new Plotter(vrp,solution); +// plotter.setBoundingBox(30, 0, 50, 20); + plotter.plot("output/solomon_C101_solution.png", "C101"); +// SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/solomon_C101_solution.png","C101"); From d526ce00800f18dbac328d67f01c30b1d85737c7 Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Mon, 2 Dec 2013 09:00:44 +0100 Subject: [PATCH 06/10] hide set/getCoordinates in Start/End activity --- .../java/jsprit/core/problem/solution/route/activity/End.java | 4 ++-- .../jsprit/core/problem/solution/route/activity/Start.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java index beacc9ad..69079d2f 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/End.java @@ -35,11 +35,11 @@ public final class End implements TourActivity { private Coordinate coordinate; - public Coordinate getCoordinate() { + Coordinate getCoordinate() { return coordinate; } - public void setCoordinate(Coordinate coordinate) { + void setCoordinate(Coordinate coordinate) { this.coordinate = coordinate; } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java index 13067feb..5ae08844 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/Start.java @@ -65,11 +65,11 @@ public final class Start implements TourActivity { - public Coordinate getCoordinate() { + Coordinate getCoordinate() { return coordinate; } - public void setCoordinate(Coordinate coordinate) { + void setCoordinate(Coordinate coordinate) { this.coordinate = coordinate; } From cf9d3c077921a8a761509c539a70522b8c0bb901 Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Mon, 2 Dec 2013 09:01:31 +0100 Subject: [PATCH 07/10] add tests verifying open-routes --- .../core/algorithm/recreate/Inserter.java | 2 - .../TestCalculatesServiceInsertion.java | 5 +- .../core/algorithm/recreate/TestInserter.java | 115 ++ ...LocalActivityInsertionCostsCalculator.java | 42 + ...LevelActivityInsertionCostsCalculator.java | 7 + .../route/VehicleRouteBuilderTest.java | 65 +- ...ckups_and_deliveries_solomon_r101_open.xml | 1236 +++++++++++++++++ 7 files changed, 1461 insertions(+), 11 deletions(-) create mode 100644 jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java create mode 100644 jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java create mode 100644 jsprit-examples/input/pickups_and_deliveries_solomon_r101_open.xml 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 9ea0f15f..61422bb3 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 @@ -72,7 +72,6 @@ class Inserter { } private void setEndLocation(VehicleRoute route, Service service) { - route.getEnd().setCoordinate(service.getCoord()); route.getEnd().setLocationId(service.getLocationId()); } @@ -106,7 +105,6 @@ class Inserter { } private void setEndLocation(VehicleRoute route, Shipment shipment) { - route.getEnd().setCoordinate(shipment.getDeliveryCoord()); route.getEnd().setLocationId(shipment.getDeliveryLocation()); } 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 c634b076..72e9f6c0 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 @@ -267,9 +267,6 @@ public class TestCalculatesServiceInsertion { assertEquals(2, iData.getDeliveryInsertionIndex()); } - @Test - public void whenInsertingAndRouteIsOpen(){ - assertTrue(false); - } + } 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 20e28113..a9887a1b 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 @@ -1,7 +1,122 @@ package jsprit.core.algorithm.recreate; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import jsprit.core.algorithm.recreate.listener.InsertionListeners; +import jsprit.core.problem.driver.Driver; +import jsprit.core.problem.job.Service; +import jsprit.core.problem.job.Shipment; +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.vehicle.Vehicle; + +import org.junit.Test; + public class TestInserter { + @Test + public void whenInsertingServiceAndRouteIsClosed_itInsertsCorrectly(){ + Service service = mock(Service.class); + Vehicle vehicle = mock(Vehicle.class); + when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.isReturnToDepot()).thenReturn(true); + when(vehicle.getId()).thenReturn("vehId"); + + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addService(service).build(); + //start - pick(shipment) - del(shipment) - end + Service serviceToInsert = mock(Service.class); + when(serviceToInsert.getLocationId()).thenReturn("delLoc"); + + InsertionData iData = mock(InsertionData.class); + when(iData.getDeliveryInsertionIndex()).thenReturn(1); + when(iData.getSelectedVehicle()).thenReturn(vehicle); + + Inserter inserter = new Inserter(mock(InsertionListeners.class)); + inserter.insertJob(serviceToInsert, iData, route); + + assertEquals(2,route.getTourActivities().getActivities().size()); + assertEquals(route.getTourActivities().getActivities().get(1).getLocationId(),serviceToInsert.getLocationId()); + assertEquals(route.getEnd().getLocationId(),vehicle.getLocationId()); + } + + @Test + public void whenInsertingServiceAndRouteIsOpen_itInsertsCorrectlyAndSwitchesEndLocation(){ + Service service = mock(Service.class); + Vehicle vehicle = mock(Vehicle.class); + when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.isReturnToDepot()).thenReturn(false); + when(vehicle.getId()).thenReturn("vehId"); + + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addService(service).build(); + Service serviceToInsert = mock(Service.class); + when(serviceToInsert.getLocationId()).thenReturn("delLoc"); + + InsertionData iData = mock(InsertionData.class); + when(iData.getDeliveryInsertionIndex()).thenReturn(1); + when(iData.getSelectedVehicle()).thenReturn(vehicle); + + Inserter inserter = new Inserter(mock(InsertionListeners.class)); + inserter.insertJob(serviceToInsert, iData, route); + + assertEquals(2,route.getTourActivities().getActivities().size()); + assertEquals(route.getTourActivities().getActivities().get(1).getLocationId(),serviceToInsert.getLocationId()); + assertEquals(route.getEnd().getLocationId(),serviceToInsert.getLocationId()); + } + + + @Test + public void whenInsertingShipmentAndRouteIsClosed_itInsertsCorrectly(){ + Shipment shipment = mock(Shipment.class); + Vehicle vehicle = mock(Vehicle.class); + when(vehicle.getLocationId()).thenReturn("vehLoc"); + when(vehicle.isReturnToDepot()).thenReturn(true); + when(vehicle.getId()).thenReturn("vehId"); + + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build(); + //start - pick(shipment) - del(shipment) - end + Shipment shipmentToInsert = mock(Shipment.class); + when(shipmentToInsert.getDeliveryLocation()).thenReturn("delLoc"); + when(shipmentToInsert.getPickupLocation()).thenReturn("pickLoc"); + InsertionData iData = mock(InsertionData.class); + when(iData.getPickupInsertionIndex()).thenReturn(2); + when(iData.getDeliveryInsertionIndex()).thenReturn(2); + when(iData.getSelectedVehicle()).thenReturn(vehicle); + + Inserter inserter = new Inserter(mock(InsertionListeners.class)); + inserter.insertJob(shipmentToInsert, iData, route); + + 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()); + } + + @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"); + + VehicleRoute route = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)).addPickup(shipment).addDelivery(shipment).build(); + //start - pick(shipment) - del(shipment) - end + Shipment shipmentToInsert = mock(Shipment.class); + when(shipmentToInsert.getDeliveryLocation()).thenReturn("delLoc"); + when(shipmentToInsert.getPickupLocation()).thenReturn("pickLoc"); + InsertionData iData = mock(InsertionData.class); + when(iData.getPickupInsertionIndex()).thenReturn(2); + when(iData.getDeliveryInsertionIndex()).thenReturn(2); + when(iData.getSelectedVehicle()).thenReturn(vehicle); + + Inserter inserter = new Inserter(mock(InsertionListeners.class)); + inserter.insertJob(shipmentToInsert, iData, route); + + 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(),shipmentToInsert.getDeliveryLocation()); + } } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java new file mode 100644 index 00000000..824a04ce --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java @@ -0,0 +1,42 @@ +package jsprit.core.algorithm.recreate; + +import static org.mockito.Mockito.mock; +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; +import jsprit.core.problem.cost.VehicleRoutingTransportCosts; + +import org.junit.Before; +import org.junit.Test; + +public class TestLocalActivityInsertionCostsCalculator { + + VehicleRoutingTransportCosts tpCosts; + + VehicleRoutingActivityCosts actCosts; + + LocalActivityInsertionCostsCalculator calc; + + @Before + public void doBefore(){ + tpCosts = mock(VehicleRoutingTransportCosts.class); + actCosts = mock(VehicleRoutingActivityCosts.class); + calc = new LocalActivityInsertionCostsCalculator(tpCosts, actCosts); + } + + @Test + public void whenInsertingActBetweenTwoRouteActs_itCalcsMarginalTpCosts(){ + VehicleRoutingTransportCosts tpCosts = mock(VehicleRoutingTransportCosts.class); + VehicleRoutingActivityCosts actCosts = mock(VehicleRoutingActivityCosts.class); + + LocalActivityInsertionCostsCalculator calc = new LocalActivityInsertionCostsCalculator(tpCosts, actCosts); + } + + @Test + public void whenInsertingActBeforeEndANDRouteIsOpen_itReturnsTransportCostsToLastAct(){ + + } + + @Test + public void whenInsertingActBeforeEndANDRouteIsClosed_itReturnsMarginalTpCosts(){ + + } +} diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java new file mode 100644 index 00000000..55d4d9a1 --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java @@ -0,0 +1,7 @@ +package jsprit.core.algorithm.recreate; + +public class TestRouteLevelActivityInsertionCostsCalculator { + + + +} 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 5d998aaa..3a584e17 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 @@ -1,8 +1,8 @@ package jsprit.core.problem.solution.route; -import static org.junit.Assert.*; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import jsprit.core.problem.driver.Driver; import jsprit.core.problem.job.Shipment; import jsprit.core.problem.vehicle.Vehicle; @@ -60,18 +60,73 @@ public class VehicleRouteBuilderTest { } @Test - public void whenBuildingOpenRoute(){ - assertTrue(false); + public void whenBuildingClosedRoute_routeEndShouldHaveLocationOfVehicle(){ + Shipment s = mock(Shipment.class); + Shipment s2 = mock(Shipment.class); + Vehicle vehicle = mock(Vehicle.class); + when(vehicle.isReturnToDepot()).thenReturn(true); + when(vehicle.getLocationId()).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()); + } + + @Test + public void whenBuildingOpenRoute_routeEndShouldHaveLocationOfLastActivity(){ + Shipment s = mock(Shipment.class); + Shipment s2 = mock(Shipment.class); + when(s2.getDeliveryLocation()).thenReturn("delLoc"); + Vehicle vehicle = mock(Vehicle.class); + when(vehicle.isReturnToDepot()).thenReturn(false); + when(vehicle.getLocationId()).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(), s2.getDeliveryLocation()); } @Test public void whenSettingDepartureTime(){ - assertTrue(false); + Shipment s = mock(Shipment.class); + Shipment s2 = mock(Shipment.class); + when(s2.getDeliveryLocation()).thenReturn("delLoc"); + Vehicle vehicle = mock(Vehicle.class); + when(vehicle.isReturnToDepot()).thenReturn(false); + when(vehicle.getLocationId()).thenReturn("vehLoc"); + VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)); + builder.addPickup(s); + builder.addPickup(s2); + builder.addDelivery(s); + builder.addDelivery(s2); + builder.setDepartureTime(100); + VehicleRoute route = builder.build(); + assertEquals(100.0,route.getDepartureTime(),0.01); + assertEquals(100.0,route.getStart().getEndTime(),0.01); } @Test public void whenSettingEndTime(){ - assertTrue(false); + Shipment s = mock(Shipment.class); + Shipment s2 = mock(Shipment.class); + when(s2.getDeliveryLocation()).thenReturn("delLoc"); + Vehicle vehicle = mock(Vehicle.class); + when(vehicle.isReturnToDepot()).thenReturn(false); + when(vehicle.getLocationId()).thenReturn("vehLoc"); + VehicleRoute.Builder builder = VehicleRoute.Builder.newInstance(vehicle, mock(Driver.class)); + builder.addPickup(s); + builder.addPickup(s2); + builder.addDelivery(s); + builder.addDelivery(s2); + builder.setRouteEndArrivalTime(100.0); + VehicleRoute route = builder.build(); + assertEquals(100.0,route.getEnd().getArrTime(),0.01); } } diff --git a/jsprit-examples/input/pickups_and_deliveries_solomon_r101_open.xml b/jsprit-examples/input/pickups_and_deliveries_solomon_r101_open.xml new file mode 100644 index 00000000..758cfab0 --- /dev/null +++ b/jsprit-examples/input/pickups_and_deliveries_solomon_r101_open.xml @@ -0,0 +1,1236 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 0.0 + 230.0 + + false + + + + + solomonType + 200 + + 100.0 + 1.0 + + + + + + + [x=63.0][y=65.0] + + 8 + 10.0 + + + 143.0 + 153.0 + + + + + [x=2.0][y=60.0] + + 5 + 10.0 + + + 41.0 + 51.0 + + + + + [x=53.0][y=52.0] + + 11 + 10.0 + + + 37.0 + 47.0 + + + + + [x=65.0][y=55.0] + + 14 + 10.0 + + + 117.0 + 127.0 + + + + + [x=60.0][y=12.0] + + 31 + 10.0 + + + 44.0 + 54.0 + + + + + [x=20.0][y=20.0] + + 8 + 10.0 + + + 134.0 + 144.0 + + + + + [x=5.0][y=5.0] + + 16 + 10.0 + + + 83.0 + 93.0 + + + + + [x=23.0][y=3.0] + + 7 + 10.0 + + + 132.0 + 142.0 + + + + + [x=24.0][y=12.0] + + 5 + 10.0 + + + 31.0 + 41.0 + + + + + [x=42.0][y=7.0] + + 5 + 10.0 + + + 97.0 + 107.0 + + + + + [x=40.0][y=25.0] + + 9 + 10.0 + + + 85.0 + 95.0 + + + + + [x=45.0][y=10.0] + + 18 + 10.0 + + + 97.0 + 107.0 + + + + + [x=55.0][y=5.0] + + 29 + 10.0 + + + 68.0 + 78.0 + + + + + [x=65.0][y=35.0] + + 3 + 10.0 + + + 153.0 + 163.0 + + + + + [x=65.0][y=20.0] + + 6 + 10.0 + + + 172.0 + 182.0 + + + + + [x=45.0][y=30.0] + + 17 + 10.0 + + + 132.0 + 142.0 + + + + + [x=35.0][y=40.0] + + 16 + 10.0 + + + 37.0 + 47.0 + + + + + [x=41.0][y=37.0] + + 16 + 10.0 + + + 39.0 + 49.0 + + + + + [x=64.0][y=42.0] + + 9 + 10.0 + + + 63.0 + 73.0 + + + + + [x=55.0][y=45.0] + + 13 + 10.0 + + + 116.0 + 126.0 + + + + + [x=35.0][y=17.0] + + 7 + 10.0 + + + 50.0 + 60.0 + + + + + [x=41.0][y=49.0] + + 10 + 10.0 + + + 161.0 + 171.0 + + + + + [x=40.0][y=60.0] + + 21 + 10.0 + + + 71.0 + 81.0 + + + + + [x=20.0][y=50.0] + + 5 + 10.0 + + + 81.0 + 91.0 + + + + + [x=25.0][y=30.0] + + 3 + 10.0 + + + 99.0 + 109.0 + + + + + [x=15.0][y=30.0] + + 26 + 10.0 + + + 34.0 + 44.0 + + + + + [x=35.0][y=69.0] + + 23 + 10.0 + + + 141.0 + 151.0 + + + + + [x=55.0][y=20.0] + + 19 + 10.0 + + + 149.0 + 159.0 + + + + + [x=31.0][y=52.0] + + 27 + 10.0 + + + 50.0 + 60.0 + + + + + [x=55.0][y=60.0] + + 16 + 10.0 + + + 97.0 + 107.0 + + + + + [x=10.0][y=43.0] + + 9 + 10.0 + + + 95.0 + 105.0 + + + + + [x=15.0][y=60.0] + + 17 + 10.0 + + + 76.0 + 86.0 + + + + + [x=5.0][y=30.0] + + 2 + 10.0 + + + 157.0 + 167.0 + + + + + [x=20.0][y=40.0] + + 12 + 10.0 + + + 87.0 + 97.0 + + + + + [x=30.0][y=5.0] + + 8 + 10.0 + + + 61.0 + 71.0 + + + + + [x=10.0][y=20.0] + + 19 + 10.0 + + + 75.0 + 85.0 + + + + + [x=30.0][y=25.0] + + 23 + 10.0 + + + 159.0 + 169.0 + + + + + [x=15.0][y=10.0] + + 20 + 10.0 + + + 32.0 + 42.0 + + + + + [x=20.0][y=65.0] + + 12 + 10.0 + + + 67.0 + 77.0 + + + + + [x=50.0][y=35.0] + + 19 + 10.0 + + + 63.0 + 73.0 + + + + + [x=45.0][y=20.0] + + 11 + 10.0 + + + 62.0 + 72.0 + + + + + [x=45.0][y=65.0] + + 9 + 10.0 + + + 126.0 + 136.0 + + + + + [x=20.0][y=26.0] + + 9 + 10.0 + + + 83.0 + 93.0 + + + + + [x=18.0][y=18.0] + + 17 + 10.0 + + + 185.0 + 195.0 + + + + + [x=19.0][y=21.0] + + 10 + 10.0 + + + 58.0 + 68.0 + + + + + [x=25.0][y=21.0] + + 12 + 10.0 + + + 133.0 + 143.0 + + + + + [x=22.0][y=27.0] + + 11 + 10.0 + + + 135.0 + 145.0 + + + + + [x=25.0][y=24.0] + + 20 + 10.0 + + + 39.0 + 49.0 + + + + + [x=26.0][y=27.0] + + 27 + 10.0 + + + 100.0 + 110.0 + + + + + [x=18.0][y=24.0] + + 22 + 10.0 + + + 188.0 + 198.0 + + + + + [x=22.0][y=22.0] + + 2 + 10.0 + + + 18.0 + 28.0 + + + + + [x=15.0][y=19.0] + + 1 + 10.0 + + + 160.0 + 170.0 + + + + + [x=31.0][y=67.0] + + 3 + 10.0 + + + 95.0 + 105.0 + + + + + [x=30.0][y=60.0] + + 16 + 10.0 + + + 124.0 + 134.0 + + + + + [x=26.0][y=52.0] + + 9 + 10.0 + + + 74.0 + 84.0 + + + + + [x=26.0][y=35.0] + + 15 + 10.0 + + + 176.0 + 186.0 + + + + + [x=57.0][y=48.0] + + 23 + 10.0 + + + 92.0 + 102.0 + + + + + [x=61.0][y=52.0] + + 3 + 10.0 + + + 96.0 + 106.0 + + + + + [x=53.0][y=43.0] + + 14 + 10.0 + + + 179.0 + 189.0 + + + + + [x=15.0][y=47.0] + + 16 + 10.0 + + + 55.0 + 65.0 + + + + + [x=14.0][y=37.0] + + 11 + 10.0 + + + 44.0 + 54.0 + + + + + [x=56.0][y=37.0] + + 6 + 10.0 + + + 182.0 + 192.0 + + + + + [x=55.0][y=54.0] + + 26 + 10.0 + + + 94.0 + 104.0 + + + + + [x=4.0][y=18.0] + + 35 + 10.0 + + + 94.0 + 104.0 + + + + + [x=28.0][y=18.0] + + 26 + 10.0 + + + 93.0 + 103.0 + + + + + [x=11.0][y=31.0] + + 7 + 10.0 + + + 101.0 + 111.0 + + + + + [x=16.0][y=22.0] + + 41 + 10.0 + + + 91.0 + 101.0 + + + + + [x=67.0][y=5.0] + + 25 + 10.0 + + + 83.0 + 93.0 + + + + + [x=49.0][y=73.0] + + 25 + 10.0 + + + 127.0 + 137.0 + + + + + [x=37.0][y=47.0] + + 6 + 10.0 + + + 50.0 + 60.0 + + + + + [x=56.0][y=39.0] + + 36 + 10.0 + + + 142.0 + 152.0 + + + + + [x=37.0][y=56.0] + + 5 + 10.0 + + + 182.0 + 192.0 + + + + + [x=57.0][y=68.0] + + 15 + 10.0 + + + 77.0 + 87.0 + + + + + [x=47.0][y=16.0] + + 25 + 10.0 + + + 35.0 + 45.0 + + + + + [x=44.0][y=17.0] + + 9 + 10.0 + + + 78.0 + 88.0 + + + + + [x=46.0][y=13.0] + + 8 + 10.0 + + + 149.0 + 159.0 + + + + + [x=49.0][y=11.0] + + 18 + 10.0 + + + 69.0 + 79.0 + + + + + [x=49.0][y=42.0] + + 13 + 10.0 + + + 73.0 + 83.0 + + + + + [x=21.0][y=24.0] + + 28 + 10.0 + + + 18.0 + 28.0 + + + + + [x=36.0][y=26.0] + + 18 + 10.0 + + + 200.0 + 210.0 + + + + + [x=32.0][y=12.0] + + 7 + 10.0 + + + 101.0 + 111.0 + + + + + [x=53.0][y=12.0] + + 6 + 10.0 + + + 130.0 + 140.0 + + + + + [x=63.0][y=23.0] + + 2 + 10.0 + + + 136.0 + 146.0 + + + + + [x=15.0][y=77.0] + + 9 + 10.0 + + + 73.0 + 83.0 + + + + + [x=62.0][y=77.0] + + 20 + 10.0 + + + 51.0 + 61.0 + + + + + [x=24.0][y=58.0] + + 19 + 10.0 + + + 58.0 + 68.0 + + + + + [x=27.0][y=69.0] + + 10 + 10.0 + + + 34.0 + 44.0 + + + + + [x=17.0][y=34.0] + + 3 + 10.0 + + + 162.0 + 172.0 + + + + + [x=12.0][y=24.0] + + 13 + 10.0 + + + 76.0 + 86.0 + + + + + [x=6.0][y=68.0] + + 30 + 10.0 + + + 108.0 + 118.0 + + + + + [x=13.0][y=52.0] + + 36 + 10.0 + + + 165.0 + 175.0 + + + + + [x=6.0][y=38.0] + + 16 + 10.0 + + + 32.0 + 42.0 + + + + + [x=11.0][y=14.0] + + 18 + 10.0 + + + 69.0 + 79.0 + + + + + [x=8.0][y=56.0] + + 27 + 10.0 + + + 51.0 + 61.0 + + + + + [x=2.0][y=48.0] + + 1 + 10.0 + + + 117.0 + 127.0 + + + + + [x=49.0][y=58.0] + + 10 + 10.0 + + + 88.0 + 98.0 + + + + + [x=27.0][y=43.0] + + 9 + 10.0 + + + 52.0 + 62.0 + + + + + [x=37.0][y=31.0] + + 14 + 10.0 + + + 95.0 + 105.0 + + + + + [x=57.0][y=29.0] + + 18 + 10.0 + + + 140.0 + 150.0 + + + + + [x=47.0][y=47.0] + + 13 + 10.0 + + + 124.0 + 134.0 + + + + + From b52a103ae5676e82eabf438cbb5671748e4b9260 Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Mon, 2 Dec 2013 17:42:51 +0100 Subject: [PATCH 08/10] finalize test with open-routes --- .../recreate/AuxilliaryCostCalculator.java | 42 ++----- .../TestAuxilliaryCostCalculator.java | 103 ++++++++++++++++++ ...alculatesServiceInsertionOnRouteLevel.java | 7 +- ...LocalActivityInsertionCostsCalculator.java | 87 +++++++++++++-- ...LevelActivityInsertionCostsCalculator.java | 7 -- .../input/bicycle_messenger_demand.txt | 31 ------ .../input/bicycle_messenger_supply.txt | 6 - .../jsprit/examples/BicycleMessenger.java | 87 --------------- 8 files changed, 192 insertions(+), 178 deletions(-) create mode 100644 jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestAuxilliaryCostCalculator.java delete mode 100644 jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java delete mode 100644 jsprit-examples/input/bicycle_messenger_demand.txt delete mode 100644 jsprit-examples/input/bicycle_messenger_supply.txt delete mode 100644 jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java index 2ff04582..0010f9f5 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/recreate/AuxilliaryCostCalculator.java @@ -22,6 +22,7 @@ import java.util.List; import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; import jsprit.core.problem.driver.Driver; +import jsprit.core.problem.solution.route.activity.End; import jsprit.core.problem.solution.route.activity.TourActivity; import jsprit.core.problem.vehicle.Vehicle; @@ -33,10 +34,10 @@ final class AuxilliaryCostCalculator { private final VehicleRoutingActivityCosts activityCosts; - public AuxilliaryCostCalculator(final VehicleRoutingTransportCosts routingCosts, final VehicleRoutingActivityCosts costFunction) { + public AuxilliaryCostCalculator(final VehicleRoutingTransportCosts routingCosts, final VehicleRoutingActivityCosts actCosts) { super(); this.routingCosts = routingCosts; - this.activityCosts = costFunction; + this.activityCosts = actCosts; } /** @@ -59,6 +60,11 @@ final class AuxilliaryCostCalculator { double departureTimePrevAct = depTime; while(actIter.hasNext()){ TourActivity act = actIter.next(); + if(act instanceof End){ + if(!vehicle.isReturnToDepot()){ + return cost; + } + } double transportCost = routingCosts.getTransportCost(prevAct.getLocationId(), act.getLocationId(), departureTimePrevAct, driver, vehicle); double transportTime = routingCosts.getTransportTime(prevAct.getLocationId(), act.getLocationId(), departureTimePrevAct, driver, vehicle); cost += transportCost; @@ -72,37 +78,5 @@ final class AuxilliaryCostCalculator { return cost; } - public double costOfPath(String startLocationId, final double startTime, final List path, String endLocationId, final Driver driver, final Vehicle vehicle){ - if(path.isEmpty()){ - return 0.0; - } - double cost = 0.0; -// Iterator actIter = path.iterator(); - String prevActLocation = startLocationId; -// TourActivity prevAct = actIter.next(); - double startCost = 0.0; - cost += startCost; - double departureTimePrevAct = startTime; - for(TourActivity act : path){ -// TourActivity act = actIter.next(); - double transportCost = routingCosts.getTransportCost(prevActLocation, act.getLocationId(), departureTimePrevAct, driver, vehicle); - double transportTime = routingCosts.getTransportTime(prevActLocation, act.getLocationId(), departureTimePrevAct, driver, vehicle); - cost += transportCost; - double actStartTime = departureTimePrevAct + transportTime; - double earliestOperationStartTime = Math.max(actStartTime, act.getTheoreticalEarliestOperationStartTime()); - double actEndTime = earliestOperationStartTime + act.getOperationTime(); - departureTimePrevAct = actEndTime; - cost += activityCosts.getActivityCost(act, actStartTime, driver, vehicle); - prevActLocation = act.getLocationId(); - } - - /* - *!!! ENDLOCATION - => Start u. End können primitiv sein. - - */ - - return cost; - } } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestAuxilliaryCostCalculator.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestAuxilliaryCostCalculator.java new file mode 100644 index 00000000..f0bb4d5c --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestAuxilliaryCostCalculator.java @@ -0,0 +1,103 @@ +package jsprit.core.algorithm.recreate; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Arrays; + +import jsprit.core.problem.cost.VehicleRoutingActivityCosts; +import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.solution.route.activity.End; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.vehicle.Vehicle; + +import org.junit.Before; +import org.junit.Test; + +public class TestAuxilliaryCostCalculator { + + private VehicleRoutingTransportCosts routingCosts; + + private VehicleRoutingActivityCosts actCosts; + + private Vehicle vehicle; + + @Before + public void doBefore(){ + vehicle = mock(Vehicle.class); + + routingCosts = mock(VehicleRoutingTransportCosts.class); + actCosts = mock(VehicleRoutingActivityCosts.class); + + when(routingCosts.getTransportCost("i", "j", 0.0, null, vehicle)).thenReturn(2.0); + when(routingCosts.getTransportTime("i", "j", 0.0, null, vehicle)).thenReturn(0.0); + when(routingCosts.getTransportCost("i", "k", 0.0, null, vehicle)).thenReturn(3.0); + when(routingCosts.getTransportTime("i", "k", 0.0, null, vehicle)).thenReturn(0.0); + when(routingCosts.getTransportCost("k", "j", 0.0, null, vehicle)).thenReturn(3.0); + when(routingCosts.getTransportTime("k", "j", 0.0, null, vehicle)).thenReturn(0.0); + } + + @Test + public void whenRouteIsClosed_itCalculatesCostUpToEnd_v1(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + TourActivity nextAct = mock(TourActivity.class); + when(nextAct.getLocationId()).thenReturn("j"); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(true); + + AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts); + double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle); + assertEquals(6.0,costs,0.01); + } + + @Test + public void whenRouteIsClosed_itCalculatesCostUpToEnd_v2(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + End nextAct = End.newInstance("j", 0.0, 0.0); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(true); + + AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts); + double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle); + assertEquals(6.0,costs,0.01); + } + + @Test + public void whenRouteIsOpen_itCalculatesCostUpToEnd_v1(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + TourActivity nextAct = mock(TourActivity.class); + when(nextAct.getLocationId()).thenReturn("j"); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(false); + + AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts); + double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle); + assertEquals(6.0,costs,0.01); + } + + @Test + public void whenRouteIsOpen_itCalculatesCostUpToEnd_v2(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + End nextAct = End.newInstance("j", 0.0, 0.0); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(false); + + AuxilliaryCostCalculator aCalc = new AuxilliaryCostCalculator(routingCosts, actCosts); + double costs = aCalc.costOfPath(Arrays.asList(prevAct,newAct,nextAct), 0.0, null, vehicle); + assertEquals(3.0,costs,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 0c621a74..141ed220 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 @@ -83,12 +83,14 @@ public class TestCalculatesServiceInsertionOnRouteLevel { when(vehicle.getLocationId()).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.getEarliestDeparture()).thenReturn(0.0); when(newVehicle.getLatestArrival()).thenReturn(100.0); + when(newVehicle.isReturnToDepot()).thenReturn(true); driver = DriverImpl.noDriver(); @@ -240,10 +242,5 @@ public class TestCalculatesServiceInsertionOnRouteLevel { assertEquals(2, iData.getDeliveryInsertionIndex()); } - @Test - public void whenInsertingAndRouteIsOpen(){ - assertTrue(false); - } - } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java index 824a04ce..b391adfa 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestLocalActivityInsertionCostsCalculator.java @@ -1,8 +1,16 @@ package jsprit.core.algorithm.recreate; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import jsprit.core.algorithm.recreate.ActivityInsertionCostsCalculator.ActivityInsertionCosts; import jsprit.core.problem.cost.VehicleRoutingActivityCosts; import jsprit.core.problem.cost.VehicleRoutingTransportCosts; +import jsprit.core.problem.misc.JobInsertionContext; +import jsprit.core.problem.solution.route.VehicleRoute; +import jsprit.core.problem.solution.route.activity.End; +import jsprit.core.problem.solution.route.activity.TourActivity; +import jsprit.core.problem.vehicle.Vehicle; import org.junit.Before; import org.junit.Test; @@ -15,28 +23,91 @@ public class TestLocalActivityInsertionCostsCalculator { LocalActivityInsertionCostsCalculator calc; + Vehicle vehicle; + + VehicleRoute route; + + JobInsertionContext jic; + @Before public void doBefore(){ + + vehicle = mock(Vehicle.class); + route = mock(VehicleRoute.class); + when(route.isEmpty()).thenReturn(false); + when(route.getVehicle()).thenReturn(vehicle); + + jic = mock(JobInsertionContext.class); + when(jic.getRoute()).thenReturn(route); + when(jic.getNewVehicle()).thenReturn(vehicle); + tpCosts = mock(VehicleRoutingTransportCosts.class); + when(tpCosts.getTransportCost("i", "j", 0.0, null, vehicle)).thenReturn(2.0); + when(tpCosts.getTransportTime("i", "j", 0.0, null, vehicle)).thenReturn(0.0); + when(tpCosts.getTransportCost("i", "k", 0.0, null, vehicle)).thenReturn(3.0); + when(tpCosts.getTransportTime("i", "k", 0.0, null, vehicle)).thenReturn(0.0); + when(tpCosts.getTransportCost("k", "j", 0.0, null, vehicle)).thenReturn(3.0); + when(tpCosts.getTransportTime("k", "j", 0.0, null, vehicle)).thenReturn(0.0); + actCosts = mock(VehicleRoutingActivityCosts.class); calc = new LocalActivityInsertionCostsCalculator(tpCosts, actCosts); } @Test public void whenInsertingActBetweenTwoRouteActs_itCalcsMarginalTpCosts(){ - VehicleRoutingTransportCosts tpCosts = mock(VehicleRoutingTransportCosts.class); - VehicleRoutingActivityCosts actCosts = mock(VehicleRoutingActivityCosts.class); + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + TourActivity nextAct = mock(TourActivity.class); + when(nextAct.getLocationId()).thenReturn("j"); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); - LocalActivityInsertionCostsCalculator calc = new LocalActivityInsertionCostsCalculator(tpCosts, actCosts); - } - - @Test - public void whenInsertingActBeforeEndANDRouteIsOpen_itReturnsTransportCostsToLastAct(){ + when(vehicle.isReturnToDepot()).thenReturn(true); + ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0); + assertEquals(4.0,costs.getAdditionalCosts(),0.01); } @Test - public void whenInsertingActBeforeEndANDRouteIsClosed_itReturnsMarginalTpCosts(){ + public void whenInsertingActBetweenLastActAndEnd_itCalcsMarginalTpCosts(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + End nextAct = End.newInstance("j", 0.0, 0.0); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + when(vehicle.isReturnToDepot()).thenReturn(true); + + ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0); + assertEquals(4.0,costs.getAdditionalCosts(),0.01); + } + + @Test + public void whenInsertingActBetweenTwoRouteActsAndRouteIsOpen_itCalcsMarginalTpCosts(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + TourActivity nextAct = mock(TourActivity.class); + when(nextAct.getLocationId()).thenReturn("j"); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(false); + + ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0); + assertEquals(4.0,costs.getAdditionalCosts(),0.01); + } + + @Test + public void whenInsertingActBetweenLastActAndEndAndRouteIsOpen_itCalculatesTpCostsFromPrevToNewAct(){ + TourActivity prevAct = mock(TourActivity.class); + when(prevAct.getLocationId()).thenReturn("i"); + End nextAct = End.newInstance("j", 0.0, 0.0); + TourActivity newAct = mock(TourActivity.class); + when(newAct.getLocationId()).thenReturn("k"); + + when(vehicle.isReturnToDepot()).thenReturn(false); + + ActivityInsertionCosts costs = calc.getCosts(jic, prevAct, nextAct, newAct, 0.0); + assertEquals(3.0,costs.getAdditionalCosts(),0.01); } } diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java b/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java deleted file mode 100644 index 55d4d9a1..00000000 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/recreate/TestRouteLevelActivityInsertionCostsCalculator.java +++ /dev/null @@ -1,7 +0,0 @@ -package jsprit.core.algorithm.recreate; - -public class TestRouteLevelActivityInsertionCostsCalculator { - - - -} diff --git a/jsprit-examples/input/bicycle_messenger_demand.txt b/jsprit-examples/input/bicycle_messenger_demand.txt deleted file mode 100644 index 42890e1b..00000000 --- a/jsprit-examples/input/bicycle_messenger_demand.txt +++ /dev/null @@ -1,31 +0,0 @@ -item id pickup_x pickup_y deliver_x deliver_y -envelope 1 13745 55419 13883 55756 -envelope 2 8406 53246 13937 55854 -envelope 3 15738 57396 35996 79499 -envelope 4 12045 60418 19349 57118 -envelope 5 13750 56416 35733 78403 -envelope 6 13190 57068 11860 59749 -envelope 7 15021 55768 14098 57379 -envelope 8 11513 58543 11501 59683 -envelope 9 12013 64155 14120 59301 -envelope 10 15006 57578 35511 78426 -envelope 11 11450 58819 11916 58338 -envelope 12 13728 56304 35524 79013 -envelope 13 15104 60923 17937 57066 -envelope 14 11373 58388 13983 53804 -envelope 15 18575 55186 18718 54381 -envelope 16 11639 50071 17363 58375 -envelope 17 11273 53410 10860 60441 -envelope 18 13766 59041 13963 57769 -envelope 19 16138 55801 16183 56024 -envelope 20 13728 56146 14301 61694 -envelope 21 12848 57059 13586 59734 -envelope 22 13645 56488 13955 55859 -envelope 23 12896 56838 13937 55908 -envelope 24 13341 58150 35709 78924 -envelope 25 13483 57303 13614 57820 -envelope 26 12741 63478 15230 59838 -envelope 27 14676 51691 16501 48361 -envelope 28 13748 54933 14120 56110 -envelope 29 17875 59565 20453 61903 -envelope 30 9772 56424 6404 55601 \ No newline at end of file diff --git a/jsprit-examples/input/bicycle_messenger_supply.txt b/jsprit-examples/input/bicycle_messenger_supply.txt deleted file mode 100644 index f25f8b66..00000000 --- a/jsprit-examples/input/bicycle_messenger_supply.txt +++ /dev/null @@ -1,6 +0,0 @@ -type id x y -messenger A 13750 57578 -messenger B 15104 53410 -messenger C 13728 55801 -messenger D 12741 63478 -messenger E 14676 18575 \ No newline at end of file diff --git a/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java b/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java deleted file mode 100644 index 123834d9..00000000 --- a/jsprit-examples/src/main/java/jsprit/examples/BicycleMessenger.java +++ /dev/null @@ -1,87 +0,0 @@ -package jsprit.examples; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.Collection; - -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.termination.IterationWithoutImprovementTermination; -import jsprit.core.problem.VehicleRoutingProblem; -import jsprit.core.problem.VehicleRoutingProblem.Builder; -import jsprit.core.problem.VehicleRoutingProblem.FleetSize; -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.VehicleType; -import jsprit.core.problem.vehicle.VehicleTypeImpl; -import jsprit.core.util.Coordinate; -import jsprit.core.util.Solutions; - -public class BicycleMessenger { - - /** - * @param args - * @throws IOException - */ - public static void main(String[] args) throws IOException { - - VehicleRoutingProblem.Builder problemBuilder = VehicleRoutingProblem.Builder.newInstance(); - readEnvelopes(problemBuilder); - readMessengers(problemBuilder); - problemBuilder.setFleetSize(FleetSize.FINITE); - - VehicleRoutingProblem bicycleMessengerProblem = problemBuilder.build(); - - VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(bicycleMessengerProblem, 6, "input/algorithmConfig_open.xml"); - algorithm.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(50)); - Collection solutions = algorithm.searchSolutions(); - - SolutionPrinter.print(Solutions.bestOf(solutions)); - Plotter plotter = new Plotter(bicycleMessengerProblem); - plotter.plotShipments(true); - plotter.plot("output/bicycleMessengerProblem.png", "bicycleMenssenger"); - - - Plotter plotter1 = new Plotter(bicycleMessengerProblem, Solutions.bestOf(solutions)); - plotter1.plotShipments(false); - plotter1.plot("output/bicycleMessengerSolution.png", "bicycleMenssenger"); - - - } - - private static void readEnvelopes(Builder problemBuilder) throws IOException { - BufferedReader reader = new BufferedReader(new FileReader(new File("input/bicycle_messenger_demand.txt"))); - String line = null; - boolean firstLine = true; - while((line = reader.readLine()) != null){ - if(firstLine) { firstLine = false; continue; } - String[] tokens = line.split("\\s+"); - Shipment envelope = Shipment.Builder.newInstance(tokens[1], 1).setPickupCoord(Coordinate.newInstance(Double.parseDouble(tokens[2]), Double.parseDouble(tokens[3]))) - .setDeliveryCoord(Coordinate.newInstance(Double.parseDouble(tokens[4]), Double.parseDouble(tokens[5]))).build(); - problemBuilder.addJob(envelope); - } - reader.close(); - } - - private static void readMessengers(Builder problemBuilder) throws IOException { - BufferedReader reader = new BufferedReader(new FileReader(new File("input/bicycle_messenger_supply.txt"))); - String line = null; - boolean firstLine = true; - VehicleType messengerType = VehicleTypeImpl.Builder.newInstance("messengerType", 15).setCostPerDistance(1).build(); - while((line = reader.readLine()) != null){ - if(firstLine) { firstLine = false; continue; } - String[] tokens = line.split("\\s+"); - Vehicle vehicle = VehicleImpl.Builder.newInstance(tokens[1]).setLocationCoord(Coordinate.newInstance(Double.parseDouble(tokens[2]), Double.parseDouble(tokens[3]))) - .setReturnToDepot(false).setType(messengerType).build(); - problemBuilder.addVehicle(vehicle); - } - reader.close(); - } - -} From 42b6237c2e8acf855c68682ea62721c7c361f147 Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Mon, 2 Dec 2013 17:49:37 +0100 Subject: [PATCH 09/10] add javadoc to vehicle.builder --- .../java/jsprit/core/problem/vehicle/VehicleImpl.java | 8 ++++++++ 1 file changed, 8 insertions(+) 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 3be48623..9778d633 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 @@ -45,6 +45,14 @@ public class VehicleImpl implements Vehicle { } + /** + * builds the vehicle. + * + *

by default, it returns to the depot. + * + * @author stefan + * + */ public static class Builder { static Logger log = Logger.getLogger(Builder.class); private String id; From 39859f379e6b4dee4ed8bdcdf635b80d1f0b1834 Mon Sep 17 00:00:00 2001 From: Stefan Schroeder <4sschroeder@gmail.com> Date: Mon, 2 Dec 2013 17:50:09 +0100 Subject: [PATCH 10/10] delete import not used --- .../src/main/java/jsprit/examples/SolomonOpenExample.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java b/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java index 6cba5e5c..ae2be7ca 100644 --- a/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java +++ b/jsprit-examples/src/main/java/jsprit/examples/SolomonOpenExample.java @@ -27,7 +27,6 @@ import jsprit.core.algorithm.selector.SelectBest; import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.io.VrpXMLReader; import jsprit.core.problem.solution.VehicleRoutingProblemSolution; -import jsprit.instance.reader.SolomonReader; public class SolomonOpenExample {