From 4378351dedce09be3768028f134315be4af748dd Mon Sep 17 00:00:00 2001 From: oblonski Date: Thu, 1 Sep 2016 12:03:14 +0200 Subject: [PATCH] create and add docs --- docs/Acknowledgement.md | 3 + docs/Bigger Multiple Depot VRP.md | 90 ++++++++ docs/Classical-Problems-Examples.md | 9 + docs/Dial-a-ride-problem.md | 1 + docs/Features.textile | 19 ++ docs/Heterogeneous-Fleet.md | 154 +++++++++++++ docs/Home.md | 16 +- docs/Meta-Heuristic.md | 27 +++ docs/More-Examples.md | 26 +++ docs/Multiple-Depot-VRP.md | 215 ++++++++++++++++++ docs/Other-Projects.md | 26 +++ ...ssical-VRP-instance---with-time-windows.md | 67 ++++++ docs/Traveling salesman problem.md | 28 +++ docs/VRP-with-backhauls-example.md | 15 ++ ...th-depot-bounded-pickups-and-deliveries.md | 37 +++ docs/VRP-with-time-windows-example.md | 111 +++++++++ docs/Vrp-with-pickups-and-deliveries.md | 34 +++ 17 files changed, 870 insertions(+), 8 deletions(-) create mode 100644 docs/Acknowledgement.md create mode 100644 docs/Bigger Multiple Depot VRP.md create mode 100644 docs/Classical-Problems-Examples.md create mode 100644 docs/Dial-a-ride-problem.md create mode 100644 docs/Features.textile create mode 100644 docs/Heterogeneous-Fleet.md create mode 100644 docs/Meta-Heuristic.md create mode 100644 docs/More-Examples.md create mode 100644 docs/Multiple-Depot-VRP.md create mode 100644 docs/Other-Projects.md create mode 100644 docs/Read-classical-VRP-instance---with-time-windows.md create mode 100644 docs/Traveling salesman problem.md create mode 100644 docs/VRP-with-backhauls-example.md create mode 100644 docs/VRP-with-depot-bounded-pickups-and-deliveries.md create mode 100644 docs/VRP-with-time-windows-example.md create mode 100644 docs/Vrp-with-pickups-and-deliveries.md diff --git a/docs/Acknowledgement.md b/docs/Acknowledgement.md new file mode 100644 index 00000000..7f334b53 --- /dev/null +++ b/docs/Acknowledgement.md @@ -0,0 +1,3 @@ +* YourKit supports jsprit with its full-featured Java Profiler. YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications. Take a look at YourKit's leading software products: YourKit Java Profiler and YourKit .NET Profiler. + +* JetBrains kindly provides jsprit with a free open-source licence for their IntelliJ IDEA Ultimate edition. \ No newline at end of file diff --git a/docs/Bigger Multiple Depot VRP.md b/docs/Bigger Multiple Depot VRP.md new file mode 100644 index 00000000..e94b7795 --- /dev/null +++ b/docs/Bigger Multiple Depot VRP.md @@ -0,0 +1,90 @@ +This example covers: +- defining and creating different 'depots', vehicles and their types +- defining a problem with finite fleet-size +- reading and creating an algorithm +- plotting the solution + +It is based on the problem instance P08 defined by + +Cordeau, J.-F., Gendreau, M. and Laporte, G. (1997), A tabu search heuristic for periodic and multi-depot vehicle routing problems. Networks, 30: 105–119. + +Please visit for example this site to get more information on Multiple Depot VRP. + +Before you start, [add the latest release to your pom](https://github.com/jsprit/jsprit/wiki/Add-latest-release-to-your-pom). Additionally, create an output folder in your project directory. Either do it manually or add the following lines to your code: +
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");  
+}
+
+ +All services of P08 are stored in an xml-file called vrp_cordeau_08.xml (you can find it [here](https://github.com/jsprit/jsprit/tree/master/jsprit-examples/input)). You read them into your problemBuilder as follows + +
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
+/*
+ * Read cordeau-instance p08, BUT only its services without any vehicles 
+ */
+new VrpXMLReader(vrpBuilder).read("input/vrp_cordeau_08.xml");
+
+ +Define depots and vehicles: + +
/*
+ * add vehicles with its depots
+ * 2 depots with the following coordinates:
+ * (-33,33), (33,-33)
+ * 
+ * each with 14 vehicles each with a capacity of 500 and a maximum duration of 310
+ */
+int nuOfVehicles = 14;
+int capacity = 500;
+double maxDuration = 310;
+Coordinate firstDepotCoord = Coordinate.newInstance(-33, 33);
+Coordinate second = Coordinate.newInstance(33, -33);		
+int depotCounter = 1;
+
+for(Coordinate depotCoord : Arrays.asList(firstDepotCoord,second)){
+    for(int i=0;i<nuOfVehicles;i++){
+        String typeId = depotCounter + "_type";
+        VehicleType vehicleType = VehicleTypeImpl.Builder.newInstance(typeId).addCapacityDimension(0,capacity).setCostPerDistance(1.0).build();
+        String vehicleId = depotCounter + "_" + (i+1) + "_vehicle";
+        VehicleImpl.VehicleBuilder vehicleBuilder = VehicleImpl.Builder.newInstance(vehicleId);
+        vehicleBuilder.setStartLocation(depotCoord);  //defines the location of the vehicle and thus the depot
+        vehicleBuilder.setType(vehicleType)
+        vehicleBuilder.setLatestArrival(maxDuration);
+        Vehicle vehicle = vehicleBuilder.build();
+        vrpBuilder.addVehicle(vehicle);
+	}
+	depotCounter++;
+}
+
+ +Build the problem, and define and run an algorithm like this: +

+/*
+ * define problem with finite fleet
+ */
+vrpBuilder.setFleetSize(FleetSize.FINITE);
+		
+/*
+ * build the problem
+ */
+VehicleRoutingProblem vrp = vrpBuilder.build();
+/*
+ * solve the problem
+ */
+VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp,"input/algorithmConfig.xml");
+Collection solutions = vra.searchSolutions();
+
+ +The problem will be looking like this: + +![p08](https://github.com/jsprit/misc-rep/raw/master/wiki-images/problem08.png) + +Running this algorithm yields to the following solution: + +![solution_p08](https://github.com/jsprit/misc-rep/raw/master/wiki-images/p08_solution.png) + +You can find the entire code here. \ No newline at end of file diff --git a/docs/Classical-Problems-Examples.md b/docs/Classical-Problems-Examples.md new file mode 100644 index 00000000..67e44f95 --- /dev/null +++ b/docs/Classical-Problems-Examples.md @@ -0,0 +1,9 @@ +- Capacitated VRP +- Multiple Depot VRP +- VRP with Time Windows +- VRP with Backhauls (Deliveries first) +- VRP with Backhauls (mixed Pickups and Deliveries) +- VRP with Pickups and Deliveries +- VRP with Heterogeneous Fleet +- Traveling Salesman Problem +- Dial-a-Ride Problem \ No newline at end of file diff --git a/docs/Dial-a-ride-problem.md b/docs/Dial-a-ride-problem.md new file mode 100644 index 00000000..6b678523 --- /dev/null +++ b/docs/Dial-a-ride-problem.md @@ -0,0 +1 @@ +You model a dial-a-ride problem much like a vehicle routing problem with pickups and deliveries. The capacity of vehicles can be interpreted as number of seats available. A shipment is here understood as a ride from one location to another (probably you want the shipment to have a capacity-demand of 1). See [VRP with pickups and deliveries](https://github.com/jsprit/jsprit/wiki/VRP-with-pickups-and-deliveries). \ No newline at end of file diff --git a/docs/Features.textile b/docs/Features.textile new file mode 100644 index 00000000..36f6ed0b --- /dev/null +++ b/docs/Features.textile @@ -0,0 +1,19 @@ +- infinite and finite fleets +- heterogeneous fleet +- multiple depots +- open routes +- routes with different start and end locations +- multiple capacity dimensions/compartments +- en-route pickups and deliveries +- service times +- time windows +- skills +- priorities +- possibility to define additional stateless and stateful constraints/conditions to account for the richness of your problem + +- benchmarks against classical problem instances +- visualization tools +- active development +- comprehensive unit and integration tests +- a number of code examples +- open source (Apache v2) diff --git a/docs/Heterogeneous-Fleet.md b/docs/Heterogeneous-Fleet.md new file mode 100644 index 00000000..c6853f3f --- /dev/null +++ b/docs/Heterogeneous-Fleet.md @@ -0,0 +1,154 @@ +This example covers +- illustrating different problem types, +- specifying heterogeneous fleet with its vehicles and vehicle-types, +- specifying the algorithm +- benchmarking the algorithm + +#### Specifying the problem + +Penna et al. (2013) distinguish 5 types of VRP dealing with heterogeneous fleet. + +FSMD - Fleet Size and Mix with Dependent costs +

FSMF - Fleet Size and Mix with Fixed costs +

FSMFD - Fleet Size and Mix with Fixed and Dependent costs +

HVRPD - Heterogeneous Vehicle Routing Problem with Dependent costs and finite (limited) fleet +

HVRPFD - Heterogeneous Vehicle Routing Problem with Fixed and Dependent costs and finite (limited) fleet + +Generally, Fleet Size and Mix (FSM) is applied on tactical level to design a vehicle fleet, whereas HVRP is applied on operational level to employ existing vehicles/fleet as efficient as possible. + +Assuming you know the basics of jsprit, implementing these types is fairly straightforward. Basically, you specify these types with the VehicleRoutingProblem.Builder and a specification of different VehicleType(s). + +Lets assume a single depot @(40,40) and the following 3 vehicle types: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
vehicleIdcapacityfixed costsvariable costs#vehicles
112010001.02
216015001.12
330035001.41
+ +To implement the above problem types you need to code: +

FSMD +

/*
+ * build the types and vehicles from table above 
+ * here it is assumed the variable costs are dependent on distance (rather than time or any other measure)
+ */
+VehicleTypeImpl vehicleType1 = VehicleTypeImpl.Builder.newInstance("type1").addCapacityDimension(0,120).setCostPerDistance(1.0).build();
+VehicleImpl vehicle1 = VehicleImpl.Builder.newInstance("vehicle1").setStartLocation(Location.newInstance(40, 40)).setType(vehicleType1).build();
+
+VehicleTypeImpl vehicleType2 = VehicleTypeImpl.Builder.newInstance("type2").addCapacityDimension(0,160).setCostPerDistance(1.2).build();
+VehicleImpl vehicle2 = VehicleImpl.Builder.newInstance("vehicle2").setStartLocation(Location.newInstance(40, 40)).setType(vehicleType2).build();
+
+VehicleTypeImpl vehicleType3 = VehicleTypeImpl.Builder.newInstance("type3").addCapacityDimension(0,300).setCostPerDistance(1.4).build();
+VehicleImpl vehicle3 = VehicleImpl.Builder.newInstance("vehicle3").setStartLocation(Location.newInstance(40, 40)).setType(vehicleType3).build();
+
+//Use VehicleRoutingProblem.Builder to specify the problem
+VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
+vrpBuilder.addVehicle(vehicle1).addVehicle(vehicle2).addVehicle(vehicle3);
+
+//set fleetSize to FleetSize.INFINITE (which you actually do not need to set since it is the default option)
+vrpBuilder.setFleetSize(FleetSize.INFINITE);
+
+//add jobs as you know it from SimpleExample and build the routing problem
+...
+VehicleRoutingProblem vrp = vrpBuilder.build();
+
+

FSMF + +The only difference to the FSMD is that you specify fixed costs rather than distance-dependent costs such as +

/*
+ * Still you probably want to somehow consider variable distance costs, thus distance-costs are equally set
+ * to 1.0 (which is the default value - thus you do not need to set explicitly).
+ */
+VehicleTypeImpl vehicleType1 = VehicleTypeImpl.Builder.newInstance("type1").addCapacityDimension(0,120).setFixedCosts(1000).build();
+VehicleImpl vehicle1 = VehicleImpl.Builder.newInstance("vehicle1").setStartLocation(Location.newInstance(40, 40)).setType(vehicleType1).build();
+
+ +

FSMFD + +Both fixed and variable costs are specified here such as +

VehicleTypeImpl vehicleType2 = VehicleTypeImpl.Builder.newInstance("type2").addCapacityDimension(0,160).setFixedCosts(1500).setCostPerDistance(1.2).build();
+VehicleImpl vehicle2 = VehicleImpl.Builder.newInstance("vehicle2").setStartLocation(Location.newInstance(40, 40)).setType(vehicleType2).build();
+
+ +

HVRPD + +As already mentioned, the HVRP distinguishes itself from FSM such that the vehicle fleet is given. Thus you need to implement each and every vehicle and set the fleet-size to FINITE. If you have a lean fleet, i.e. sum of available capacities is not much greater than the total demand, you need to allow the algorithm to temporarilly generate infeasable solution (i.e. with vehicles you actually do not have in your fleet). By setting sufficient penalties, you should end up with a feasible solution (assuming there is one). + +

/*
+ * build the types and vehicles from table above 
+ * here it is assumed the variable costs are dependent on distance (rather than time or any other measure)
+ */
+VehicleTypeImpl vehicleType1 = VehicleTypeImpl.Builder.newInstance("type1").addCapacityDimension(0,120).setCostPerDistance(1.0).build();
+VehicleImpl vehicle1_1 = VehicleImpl.Builder.newInstance("vehicle1_1").setStartLocation(Location.newInstance(40, 40)).setType(vehicleType1).build();
+VehicleImpl vehicle1_2 = VehicleImpl.Builder.newInstance("vehicle1_2").setStartLocation(Location.newInstance(40, 40)).setType(vehicleType1).build();
+
+VehicleTypeImpl vehicleType2 = VehicleTypeImpl.Builder.newInstance("type2").addCapacityDimension(0,160).setCostPerDistance(1.2).build();
+VehicleImpl vehicle2_1 = VehicleImpl.Builder.newInstance("vehicle2_1").setStartLocation(Location.newInstance(40, 40)).setType(vehicleType2).build();
+VehicleImpl vehicle2_2 = VehicleImpl.Builder.newInstance("vehicle2_2").setStartLocation(Location.newInstance(40, 40)).setType(vehicleType2).build();
+
+VehicleTypeImpl vehicleType3 = VehicleTypeImpl.Builder.newInstance("type3").addCapacityDimension(0,300).setCostPerDistance(1.4).build();
+VehicleImpl vehicle3 = VehicleImpl.Builder.newInstance("vehicle3").setStartLocation(Location.newInstance(40, 40)).setType(vehicleType3).build();
+
+//Use VehicleRoutingProblem.Builder to specify the problem
+VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
+vrpBuilder.addVehicle(vehicle1_1).addVehicle(vehicle1_2).addVehicle(vehicle2_1).addVehicle(vehicle2_2).addVehicle(vehicle3);
+
+//set fleetSize to FleetSize.FINITE 
+vrpBuilder.setFleetSize(FleetSize.FINITE);
+
+//add jobs as you know it from SimpleExample and build the routing problem
+...
+VehicleRoutingProblem vrp = vrpBuilder.build();
+
+ +Accordingly, you implement the HVRPFD problem by additionally setting fixed costs as illustrated above (see FSMF). + +#### Specifying the algorithm + +Have a look at the following xml-file: algorith-config.xml + +The insertion heuristic is specified in line 28-30. Once you ommit 'id' as attribute in insertion-tag all subsequent insertion calls in the xml-file are referred the specification made in line 28-30. The tag 'considerFixedCosts' triggers an approach to consider fixed costs when inserting a job. + +It is a fixed costs allocation approach that distinguishes between different insertion phases depending on the completeness of the solution. It is based on Dell' Amico et al. (2007) and basically works as follows: If a significant share of jobs still have to be inserted, vehicles with a low fixed costs per capacity ratio (which they call relative fixed costs) are preferred which usually prefers bigger vehicles. Thus total capacity is expanded. If almost all jobs are already in the solution, vehicles with low absolute fixed costs are preferred which in turn prefers smaller vehicles. Thus total capacity is tighten and kept lean, respectively. It is implemented here. + +The 'weight' attribute specifies a fixed costs scaling parameter and determines the importance of fixed costs compared to variable costs. If weight is 0.0, fixed costs do not matter (are not considered). You need to find out an appropriate parameter for your problem. 'weight=1.0' is a good point to start from. + +Play around with this option and also omit 'considerFixedCosts' to get a notion of its impact. + +Loading and using the above algorithm is as simple as taking the following two steps: + +1. Download config-file (open config-file in Browser (just click on link), right click 'Raw' and save target as) and +2. Code VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(yourProblem,"yourPath/downloadedConfigFile.xml") + +#### Benchmarking the algorithm + +Have a look at [this example](https://github.com/jsprit/jsprit/blob/v1.6/jsprit-examples/src/main/java/jsprit/examples/HVRPBenchmarkExample.java). It shows you how to benchmark an algorithm on classical VRP instances with heterogeneous fleet. + +For two algorithm-configuration (an extensive search and a greedy one) you can find benchmarking results for the above problem types [here](https://github.com/jsprit/jsprit/wiki/Benchmark-VRPH). + + \ No newline at end of file diff --git a/docs/Home.md b/docs/Home.md index 7e24660e..21f99537 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -1,13 +1,13 @@ -## [Get Started](https://github.com/jsprit/jsprit/wiki/Getting-Started) +## [Get Started](Getting-Started) Setting up jsprit and the like. -## Examples +## Examples -* [Simple Example](https://github.com/jsprit/jsprit/wiki/Simple-Example) -* [More Examples](https://github.com/jsprit/jsprit/wiki/More-Examples) +* [Simple Example](Simple-Example) +* [More Examples](More-Examples) -## [Meta-Heuristic](https://github.com/jsprit/jsprit/wiki/Meta-Heuristic) +## [Meta-Heuristic](Meta-Heuristic) Gives a basic description of the applied meta-heuristic. @@ -28,19 +28,19 @@ mvn clean install If you want to contribute to jsprit (which would be great), fork the project and build your fork, make changes, run your and jsprit's test cases and make a pull request (see [help.github.contribute](https://help.github.com/articles/fork-a-repo) or [stackoverflow.contribute](http://stackoverflow.com/questions/4384776/how-do-i-contribute-to-others-code-in-github) for details). -## [Acknowledgement](https://github.com/jsprit/jsprit/wiki/Acknowledgement) +## [Acknowledgement](Acknowledgement) Sponsors/Acknowledgement/Testimonials ##Contact -####Mailing List: +####Mailing List: In the [forum](https://discuss.graphhopper.com/) you can discuss jsprit related issues and you will probably get answers to your questions. ####Issue Tracker: For bugs, feature requests or similar use the [issue tracker](https://github.com/jsprit/jsprit/issues). -####Email: +####Email: If you cannot get help in the mailing list or you just do not want to discuss your topic publicly, send an email to: info@graphhopper.com diff --git a/docs/Meta-Heuristic.md b/docs/Meta-Heuristic.md new file mode 100644 index 00000000..aa01e173 --- /dev/null +++ b/docs/Meta-Heuristic.md @@ -0,0 +1,27 @@ +#### The Meta-Heuristic +The idea of the meta-heuristic that is applied to solve the various vehicle routing problems +with jsprit was developed by Schrimpf et al. (2000) +who formulated the ruin-and-recreate principle. +It is a large neighborhood search that combines elements of simulated annealing +and threshold-accepting algorithms (Schrimpf et al. [2000, pg. 142]). +Essentially, it works as follows: starting with an initial solution, it disintegrates +parts of the solution leading to (i) a set of jobs that are not served by a vehicle anymore and to +(ii) a partial solution containing all other jobs. Thus, this step is called ruin step. +Based on the partial solution (ii) all jobs from (i) are re-integrated again, which is therefore referred +to as recreation yielding to a new solution. If the new solution has a certain quality, +it is accepted as new best solution, whereupon a new ruin-and-recreate iteration starts. +These steps are repeated over and over again until a certain termination criterion is met +(e.g. computation time, #iterations, etc.). + +We extended the core algorithm described by [Schrimpf et al. (2000)](http://www.sciencedirect.com/science/article/pii/S0021999199964136) with strategies inspired by the great work of +[Pisinger and Ropke (2007)](http://www.sciencedirect.com/science/article/pii/S0305054805003023). + +Why this approach? +* it is best suited for complex problems that have many constraints and a discontinue solution space (Schrimpf et al. [2000, pg. 142]), +* it is an all-purpose meta-heuristic that can be used to solve a number of classical VRP types, +* it can be computed concurrently in an intuitive way, +* basic search strategies (or local moves) can be easily varied to small and large moves according to the complexity of the problem, +* it can generate whole new neighborhood structures, +* the number of search strategies can be kept low and thus +* it is appealing simple in structure and comparably easy to understand and +* there is a clear distinction between ruin and recreate which - we think - makes constraint checking much easier. diff --git a/docs/More-Examples.md b/docs/More-Examples.md new file mode 100644 index 00000000..e855bb89 --- /dev/null +++ b/docs/More-Examples.md @@ -0,0 +1,26 @@ +#### [Multiple Depot VRP](Multiple-Depot-VRP) +- setting up a VRP with Multiple Depots +- defining depots, vehicles and their types +- dealing with finite fleet size + +#### [VRP with time windows](VRP-with-time-windows-example) +- defining and creating vehicles and their types +- defining services with time-windows and service times +- defining a problem with infinite fleet-size +- reading, creating and running an algorithm + +#### [VRP with backhauls](VRP-with-backhauls-example) +- defining and creating pickup and deliveries +- defining backhaul constraint + +#### [VRP with backhauls (with mixed pickup and deliveries)](VRP-with-depot-bounded-pickups-and-deliveries) +- defining and creating depot-bounded pickups and deliveries + +#### [VRP with pickup and delivieries](VRP-with-pickups-and-deliveries) +- defining and creating pickups and deliveries + +#### [VRP with heterogeneous fleet](Heterogeneous-Fleet) +- illustrating different problem types, +- specifying heterogeneous fleet with its vehicles and vehicle-types, +- specifying the algorithm, +- benchmarking the algorithm diff --git a/docs/Multiple-Depot-VRP.md b/docs/Multiple-Depot-VRP.md new file mode 100644 index 00000000..7a2df1ab --- /dev/null +++ b/docs/Multiple-Depot-VRP.md @@ -0,0 +1,215 @@ +This example covers: +- defining and creating different 'depots', vehicles and their types +- defining a problem with finite fleet-size +- reading and creating an algorithm +- plotting the solution + +It is based on the problem instance P01 defined by + +Cordeau, J.-F., Gendreau, M. and Laporte, G. (1997), A tabu search heuristic for periodic and multi-depot vehicle routing problems. Networks, 30: 105–119. + +Please visit for example this site to get more information on Multiple Depot VRP. + +Before you start, [add the latest release to your pom](https://github.com/jsprit/jsprit/wiki/Add-latest-release-to-your-pom). Additionally, create an output folder in your project directory. Either do it manually or add the following lines to your code (even this obfuscates the code-example a bit): +
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");  
+}
+
+ +All services of P01 are stored in an xml-file called vrp_cordeau_01.xml (you can find it [here](https://github.com/jsprit/jsprit/tree/master/jsprit-examples/input)). To read them into your problemBuilder, code the following lines: + +
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
+/*
+ * Read cordeau-instance p01, BUT only its services without any vehicles 
+ */
+new VrpXMLReader(vrpBuilder).read("input/vrp_cordeau_01.xml");
+
+ +Define and add depots, vehicles and their types as follows: + +
/*
+ * add vehicles with its depots
+ * 4 depots with the following coordinates:
+ * (20,20), (30,40), (50,30), (60,50)
+ * 
+ * each with 4 vehicles each with a capacity of 80
+ */
+int nuOfVehicles = 4;
+int capacity = 80;
+Coordinate firstDepotCoord = Coordinate.newInstance(20, 20);
+Coordinate second = Coordinate.newInstance(30, 40);
+Coordinate third = Coordinate.newInstance(50, 30);
+Coordinate fourth = Coordinate.newInstance(60, 50);
+		
+int depotCounter = 1;
+for(Coordinate depotCoord : Arrays.asList(firstDepotCoord,second,third,fourth)){
+    for(int i=0;i<nuOfVehicles;i++){
+        String typeId = depotCounter + "_type";
+        VehicleType vehicleType = VehicleTypeImpl.Builder.newInstance(typeId).addCapacityDimension(0,capacity).setCostPerDistance(1.0).build();
+        String vehicleId = depotCounter + "_" + (i+1) + "_vehicle";
+        VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance(vehicleId);
+        vehicleBuilder.setStartLocation(Location.newInstance(depotCoord.getX(),depotCoord.getY()));  //defines the location of the vehicle and thus the depot
+        vehicleBuilder.setType(vehicleType)
+        VehicleImpl vehicle = vehicleBuilder.build();
+        vrpBuilder.addVehicle(vehicle);
+	}
+	depotCounter++;
+}
+
+ +Note that there is no explicit depot definition. Depots are defined by the location of vehicles. + +Set finite fleet-size and build the problem. +
/*
+ * define problem with finite fleet
+ */
+vrpBuilder.setFleetSize(FleetSize.FINITE);
+		
+/*
+ * build the problem
+ */
+VehicleRoutingProblem vrp = vrpBuilder.build();
+
+ +Plot it, to see how it looks like. +
Plotter plotter = new Plotter(vrp).plot("output/problem01.png", "p01");
+
+ +It looks like this: +![p01](https://github.com/jsprit/misc-rep/raw/master/wiki-images/problem01.png) + +Define and run an algorithm to solve the problem. +
/*
+ * solve the problem
+ */
+VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);
+Collection solutions = vra.searchSolutions();
+
+ +You can plot it by: + +
Plotter plotter = new Plotter(vrp,Solutions.bestOf(solutions));
+plotter.plot("output/p01_solution.png", "p01");
+
+ +![p01](https://github.com/jsprit/misc-rep/raw/master/wiki-images/p01_solution.png) + +and print the results to your console by: + +
SolutionPrinter.print(vrp,Solutions.bestOf(solutions),Print.VERBOSE);
+
+ +
+--------------------------+
+| problem                  |
++---------------+----------+
+| indicator     | value    |
++---------------+----------+
+| nJobs         | 50       | 
+| nServices     | 50       | 
+| nShipments    | 0        | 
+| fleetsize     | FINITE   | 
++--------------------------+
++----------------------------------------------------------+
+| solution                                                 |
++---------------+------------------------------------------+
+| indicator     | value                                    |
++---------------+------------------------------------------+
+| costs         | 582.9805315622696                        | 
+| nVehicles     | 11                                       | 
++----------------------------------------------------------+
++--------------------------------------------------------------------------------------------------------------------------------+
+| detailed solution                                                                                                              |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| route   | vehicle              | activity              | job             | arrTime         | endTime         | costs           |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| 1       | 3_1_vehicle          | start                 | -               | undef           | 0               | 0               |
+| 1       | 3_1_vehicle          | service               | 9               | 4               | 4               | 4               |
+| 1       | 3_1_vehicle          | service               | 34              | 13              | 13              | 13              |
+| 1       | 3_1_vehicle          | service               | 30              | 19              | 19              | 19              |
+| 1       | 3_1_vehicle          | service               | 39              | 31              | 31              | 31              |
+| 1       | 3_1_vehicle          | service               | 10              | 41              | 41              | 41              |
+| 1       | 3_1_vehicle          | end                   | -               | 50              | undef           | 50              |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| 2       | 2_2_vehicle          | start                 | -               | undef           | 0               | 0               |
+| 2       | 2_2_vehicle          | service               | 11              | 12              | 12              | 12              |
+| 2       | 2_2_vehicle          | service               | 32              | 18              | 18              | 18              |
+| 2       | 2_2_vehicle          | service               | 1               | 25              | 25              | 25              |
+| 2       | 2_2_vehicle          | service               | 22              | 32              | 32              | 32              |
+| 2       | 2_2_vehicle          | service               | 28              | 42              | 42              | 42              |
+| 2       | 2_2_vehicle          | service               | 31              | 48              | 48              | 48              |
+| 2       | 2_2_vehicle          | service               | 26              | 58              | 58              | 58              |
+| 2       | 2_2_vehicle          | end                   | -               | 86              | undef           | 86              |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| 3       | 2_4_vehicle          | start                 | -               | undef           | 0               | 0               |
+| 3       | 2_4_vehicle          | service               | 46              | 2               | 2               | 2               |
+| 3       | 2_4_vehicle          | service               | 12              | 9               | 9               | 9               |
+| 3       | 2_4_vehicle          | service               | 47              | 15              | 15              | 15              |
+| 3       | 2_4_vehicle          | end                   | -               | 25              | undef           | 25              |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| 4       | 2_1_vehicle          | start                 | -               | undef           | 0               | 0               |
+| 4       | 2_1_vehicle          | service               | 23              | 22              | 22              | 22              |
+| 4       | 2_1_vehicle          | service               | 7               | 28              | 28              | 28              |
+| 4       | 2_1_vehicle          | service               | 43              | 40              | 40              | 40              |
+| 4       | 2_1_vehicle          | service               | 24              | 53              | 53              | 53              |
+| 4       | 2_1_vehicle          | service               | 14              | 63              | 63              | 63              |
+| 4       | 2_1_vehicle          | end                   | -               | 81              | undef           | 81              |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| 5       | 4_2_vehicle          | start                 | -               | undef           | 0               | 0               |
+| 5       | 4_2_vehicle          | service               | 20              | 9               | 9               | 9               |
+| 5       | 4_2_vehicle          | service               | 3               | 16              | 16              | 16              |
+| 5       | 4_2_vehicle          | service               | 36              | 28              | 28              | 28              |
+| 5       | 4_2_vehicle          | service               | 35              | 35              | 35              | 35              |
+| 5       | 4_2_vehicle          | end                   | -               | 48              | undef           | 48              |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| 6       | 1_2_vehicle          | start                 | -               | undef           | 0               | 0               |
+| 6       | 1_2_vehicle          | service               | 44              | 11              | 11              | 11              |
+| 6       | 1_2_vehicle          | service               | 45              | 21              | 21              | 21              |
+| 6       | 1_2_vehicle          | service               | 33              | 28              | 28              | 28              |
+| 6       | 1_2_vehicle          | service               | 15              | 40              | 40              | 40              |
+| 6       | 1_2_vehicle          | service               | 37              | 47              | 47              | 47              |
+| 6       | 1_2_vehicle          | service               | 17              | 52              | 52              | 52              |
+| 6       | 1_2_vehicle          | end                   | -               | 60              | undef           | 60              |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| 7       | 3_2_vehicle          | start                 | -               | undef           | 0               | 0               |
+| 7       | 3_2_vehicle          | service               | 49              | 3               | 3               | 3               |
+| 7       | 3_2_vehicle          | service               | 5               | 11              | 11              | 11              |
+| 7       | 3_2_vehicle          | service               | 38              | 18              | 18              | 18              |
+| 7       | 3_2_vehicle          | end                   | -               | 25              | undef           | 25              |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| 8       | 1_3_vehicle          | start                 | -               | undef           | 0               | 0               |
+| 8       | 1_3_vehicle          | service               | 25              | 22              | 22              | 22              |
+| 8       | 1_3_vehicle          | service               | 18              | 33              | 33              | 33              |
+| 8       | 1_3_vehicle          | service               | 4               | 41              | 41              | 41              |
+| 8       | 1_3_vehicle          | end                   | -               | 47              | undef           | 47              |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| 9       | 2_3_vehicle          | start                 | -               | undef           | 0               | 0               |
+| 9       | 2_3_vehicle          | service               | 6               | 11              | 11              | 11              |
+| 9       | 2_3_vehicle          | service               | 48              | 20              | 20              | 20              |
+| 9       | 2_3_vehicle          | service               | 8               | 30              | 30              | 30              |
+| 9       | 2_3_vehicle          | service               | 27              | 44              | 44              | 44              |
+| 9       | 2_3_vehicle          | end                   | -               | 52              | undef           | 52              |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| 10      | 4_3_vehicle          | start                 | -               | undef           | 0               | 0               |
+| 10      | 4_3_vehicle          | service               | 29              | 3               | 3               | 3               |
+| 10      | 4_3_vehicle          | service               | 2               | 12              | 12              | 12              |
+| 10      | 4_3_vehicle          | service               | 16              | 20              | 20              | 20              |
+| 10      | 4_3_vehicle          | service               | 50              | 26              | 26              | 26              |
+| 10      | 4_3_vehicle          | service               | 21              | 34              | 34              | 34              |
+| 10      | 4_3_vehicle          | end                   | -               | 42              | undef           | 42              |
++---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
+| 11      | 1_4_vehicle          | start                 | -               | undef           | 0               | 0               |
+| 11      | 1_4_vehicle          | service               | 13              | 16              | 16              | 16              |
+| 11      | 1_4_vehicle          | service               | 41              | 25              | 25              | 25              |
+| 11      | 1_4_vehicle          | service               | 40              | 37              | 37              | 37              |
+| 11      | 1_4_vehicle          | service               | 19              | 48              | 48              | 48              |
+| 11      | 1_4_vehicle          | service               | 42              | 57              | 57              | 57              |
+| 11      | 1_4_vehicle          | end                   | -               | 67              | undef           | 67              |
++--------------------------------------------------------------------------------------------------------------------------------+
+
+
+ +You can find the entire code here. diff --git a/docs/Other-Projects.md b/docs/Other-Projects.md new file mode 100644 index 00000000..f61ccecb --- /dev/null +++ b/docs/Other-Projects.md @@ -0,0 +1,26 @@ +### VRP + +#### [Chris Groer's VRPH library](https://sites.google.com/site/vrphlibrary/) +An open source library for solving the capacitated vehicle routing problem written in C++. + +#### [OptaPlanner](https://www.optaplanner.org/) +OptaPlanner is a lightweight, embeddable planning engine written in Java™. It can be used to solve the capacitated vehicle routing problem (with time windows). + +#### [Open-VRP](https://github.com/mck-/Open-VRP) +Open-VRP is a framework to model and solve various vehicle routing problems. + +#### [VROOM](https://github.com/jcoupey/vroom) +VROOM is an optimization engine written in C++14 that aim at providing good solutions to various real-life vehicle routing problems within a small computing time. It is free software, distributed under the term of the GNU General Public License V3. + +#### [Hipster4j](http://www.hipster4j.org/) +Hipster is an easy to use yet powerful and flexible type-safe library for heuristic search, written in pure Java. It relies on a flexible model with generic operators to define search problems. So you can also model and solve vehicle routing problems. + +### Territory Design + +#### [OpenDoorLogistics](http://www.opendoorlogistics.com) +Open Door Logistics Studio is an easy-to-use +standalone open source application for performing geographic analysis of your customer base and sales territory design, mapping and management. + + + +If you know another promising open source implementation, report it. \ No newline at end of file diff --git a/docs/Read-classical-VRP-instance---with-time-windows.md b/docs/Read-classical-VRP-instance---with-time-windows.md new file mode 100644 index 00000000..93c99046 --- /dev/null +++ b/docs/Read-classical-VRP-instance---with-time-windows.md @@ -0,0 +1,67 @@ +This example covers +- reading a classical VRP instance (here the Solomon instance C101), +- plotting the problem, +- reading and running a predefined algorithm, +- plotting the solution. + +Make sure, your pom is prepared (see [Add the latest snapshot to your pom](https://github.com/jsprit/jsprit/wiki/Add-latest-snapshot-to-your-pom)). Additionally, create an output folder in your project directory. Either do it manually or add the following lines to your code (even this obfuscates the code-example a bit): +
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");  
+}
+
+ +Download the solomon problem instance (for instance [here](http://neo.lcc.uma.es/vrp/vrp-instances/capacitated-vrp-with-time-windows-instances/)) or download [C101_solomon.txt](https://github.com/jsprit/jsprit/tree/master/jsprit-examples/input). It is assumed you put the instance file into a folder called 'input'. + +Read and build the problem: +
/*
+ * define problem-builder first
+ */
+VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
+
+/*
+ * Read solomon instance with SolomonReader
+ * Note that the reader assigns fixed costs of 100 to each vehicle used (even the original problem does not
+ * exhibit any fixed cost components). Total costs should indicate then
+ * nuOfVehicles * 100 + variable costs
+ */
+new SolomonReader(vrpBuilder).read("input/C101_solomon.txt");
+
+/*
+ * Build the problem. By default, transport costs are calculated as Euclidean distances.
+ */
+VehicleRoutingProblem vrp = vrpBuilder.build();
+
+ +Plot the problem to see how it looks like: +
SolutionPlotter.plotVrpAsPNG(vrp, "output/solomon_C101.png", "C101");
+ +It looks like [this](https://github.com/jsprit/misc-rep/raw/master/wiki-images/solomon_C101.png). + +To solve it, define an algorithm. Here, it comes out-of-the-box. The SchrimpfFactory creates an algo which is an implemenation of [Schrimpf et al.](http://www.sciencedirect.com/science/article/pii/S0021999199964136). In this configuration, it is best suited to solve the VRP with time windows. + +
/*
+* get the algorithm out-of-the-box. 
+*/
+VehicleRoutingAlgorithm algorithm = new SchrimpfFactory().createAlgorithm(problem);		
+
+/*
+* and search a solution which returns a collection of solution (here only one solution is in the collection)
+*/
+Collection solutions = algorithm.searchSolutions();
+	
+/*
+ * use helper to get the best 
+ */
+VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions);
+
+ +Plot the solution now to analyse how it looks like: +
SolutionPlotter.plotSolutionAsPNG(vrp, "output/solomon_C101_solution.png", "C101");
+ +It looks like [this](https://github.com/jsprit/misc-rep/raw/master/wiki-images/solomon_C101_solution.png). + +Get the entire code of this example [here](https://github.com/jsprit/jsprit/blob/v1.6/jsprit-examples/src/main/java/jsprit/examples/SolomonExample.java). diff --git a/docs/Traveling salesman problem.md b/docs/Traveling salesman problem.md new file mode 100644 index 00000000..3dd22e55 --- /dev/null +++ b/docs/Traveling salesman problem.md @@ -0,0 +1,28 @@ +TSP problem can be modelled by defining a vehicle routing problem with either a vehicle that has a sufficiently high capacity (to accomodate all services) + +
/*
+ * get a vehicle type-builder and build a type with the typeId "vehicleType" and a sufficently high capacity
+ */
+VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType").addCapacityDimension(0,Integer.MAX_VALUE);
+VehicleType vehicleType = vehicleTypeBuilder.build();
+
+/*
+ * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType"
+ */
+VehicleBuilder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle");
+vehicleBuilder.setStartLocation(Location.newInstance(10, 10));
+vehicleBuilder.setType(vehicleType); 
+Vehicle vehicle = vehicleBuilder.build();
+
+ +or services that have a capacity-demand of 0. + +
/*
+ * build services with id 1...4 at the required locations, each with a capacity-demand of 0 (which is the default).
+ * Note, that the builder allows chaining which makes building quite handy
+ */
+Service service1 = Service.Builder.newInstance("1").setLocation(Location.newInstance(5, 7)).build();
+Service service2 = Service.Builder.newInstance("2").setLocation(Location.newInstance(5, 13)).build();
+Service service3 = Service.Builder.newInstance("3").setLocation(Location.newInstance(15, 7)).build();
+Service service4 = Service.Builder.newInstance("4").setLocation(Location.newInstance(15, 13)).build();
+
\ No newline at end of file diff --git a/docs/VRP-with-backhauls-example.md b/docs/VRP-with-backhauls-example.md new file mode 100644 index 00000000..bda68724 --- /dev/null +++ b/docs/VRP-with-backhauls-example.md @@ -0,0 +1,15 @@ +The entire code of more advanced examples dealing with VRP with backhauls can be found here: +- Example 1 which is an adopted problem from Christophides vrpnc1 with random pickups and deliveries and a vehicle capacity of 50 +- Example 2 which is an adopted problem from Solomon R101 with random pickups and deliveries with time-windows yielding to the results below. Additionally, the impact of the backhaul-constraint and time-windows are illustrated. + +R101 without time-windows and without backhaul-constraint: + + +The first customer in a route is marked with a red circle to indicate the orientation of the route. The labels represent the size of the pickup and delivery respectively. + +R101 without time-windows and with backhaul-constraint: + + +R101 with time-windows and with backhaul-constraint: + + diff --git a/docs/VRP-with-depot-bounded-pickups-and-deliveries.md b/docs/VRP-with-depot-bounded-pickups-and-deliveries.md new file mode 100644 index 00000000..4a04d780 --- /dev/null +++ b/docs/VRP-with-depot-bounded-pickups-and-deliveries.md @@ -0,0 +1,37 @@ +This example assumes that you know [SimpleExample](https://github.com/jsprit/jsprit/wiki/Simple-Example) and covers: +- defining pickups and deliveries + +Note that the VRP with Backhauls with mixed pickups and deliveries described here assumes that all deliveries are loaded in the depot at the beginning of a tour and all pickups are unloaded in the depot as well (at the end of the tour). En route pickup and deliveries such that a shipment is loaded at location A and unloaded again at location B within the same route (where A and B are unequal to the depot location) is covered [here](https://github.com/jsprit/jsprit/wiki/VRP-with-pickups-and-deliveries/). + +The only difference compared to SimpleExample is the creation of pickups and deliveries instead of the more general services. However, you define them much like you define services: +
/*
+ * build pickups and deliveries at the required locations, each with a capacity-demand of 1.
+ */
+Pickup pickup1 = (Pickup) Pickup.Builder.newInstance("1").addSizeDimension(0,1).setCoord(Coordinate.newInstance(5, 7)).build();
+Delivery delivery1 = (Delivery) Delivery.Builder.newInstance("2").addSizeDimension(0,1).setCoord(Coordinate.newInstance(5, 13)).build();
+		
+Pickup pickup2 = (Pickup) Pickup.Builder.newInstance("3").addSizeDimension(0,1).setCoord(Coordinate.newInstance(15, 7)).build();
+Delivery delivery2 = (Delivery) Delivery.Builder.newInstance("4").addSizeDimension(0,1).setCoord(Coordinate.newInstance(15, 13)).build();
+
+VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
+vrpBuilder.addVehicle(vehicle);
+
+/*
+ * add pickups and deliveries to the problem
+ */
+vrpBuilder.addJob(pickup1).addJob(pickup2).addJob(delivery1).addJob(delivery2);
+
+VehicleRoutingProblem problem = vrpBuilder.build();
+
+ +and proceed with what you know from SimpleExample. The entire code of the example can be found here. + +The code of more advanced examples dealing with the pickup and deliveries can be found here: +- Example 1 which is an adopted problem from Solomon R101 with random pickups and deliveries with time-windows +- Example 2 which is an adopted problem from Christophides vrpnc1 with random pickups and deliveries and a vehicle capacity of 50 yielding to the following solution: + + + +The first customer in a route is marked with a red circle to indicate the orientation of the route. The labels represent the size of the pickup and delivery respectively. It is interesting to compare this with the solution of the same problem but with backhauls constraint, i.e. deliveries have to be conducted first (before pickups can be loaded) (see [VRP with backhauls](https://github.com/jsprit/jsprit/wiki/VRP-with-backhauls-example)). + + \ No newline at end of file diff --git a/docs/VRP-with-time-windows-example.md b/docs/VRP-with-time-windows-example.md new file mode 100644 index 00000000..5a768916 --- /dev/null +++ b/docs/VRP-with-time-windows-example.md @@ -0,0 +1,111 @@ +This example covers: +- defining and creating vehicles and their types +- defining services with time-windows and service times +- defining a problem with infinite fleet-size +- reading, creating and running an algorithm + +Before you start, [add the latest release to your pom](https://github.com/jsprit/jsprit/wiki/Add-latest-release-to-your-pom). Additionally, create an output folder in your project directory. Either do it manually or add the following lines to your code (even this obfuscates the code-example a bit): +
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");  
+}
+
+ +Let us assume the following problem setup (being an excerpt of Solomon's C101 problem instance). + + + +First, build a vehicle with a capacity of 200. Its maximum operating time is 1236 and it is located at (40,50): + +
/*
+ * get a vehicle type-builder and build a type with the typeId "vehicleType" and a capacity of 200
+ */
+VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType").addCapacityDimension(0,200);
+VehicleType vehicleType = vehicleTypeBuilder.build();
+
+/*
+ * get a vehicle-builder and build a vehicle located at (40,50) with type "vehicleType" and a latest arrival
+ * time of 1236 (which corresponds to a operation time of 1236 since the earliestStart of the vehicle is set
+ * to 0 by default).
+ */
+VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle");
+vehicleBuilder.setStartLocation(Location.newInstance(40, 50));
+vehicleBuilder.setLatestArrival(1236);
+vehicleBuilder.setType(vehicleType); 
+Vehicle vehicle = vehicleBuilder.build();
+
+ +Build services 1-6 now by coding: + +
/*
+ * build services with id 1...6 at the required locations
+ * Note, that the builder allows chaining which makes building quite handy
+ */
+//define a service-builder and initialise it with serviceId=1 and demand=10
+Service.Builder sBuilder1 = Service.Builder.newInstance("1").addSizeDimension(0,10);
+//set coordinate
+sBuilder1.setLocation(Location.newInstance(45, 68));
+//set service-time
+sBuilder1.setServiceTime(90);
+//set time-window
+sBuilder1.setTimeWindow(TimeWindow.newInstance(912,967));
+//and build service
+Service service1 = sBuilder1.build();
+
+Service.Builder sBuilder2 = Service.Builder.newInstance("2").addSizeDimension(0,30);
+sBuilder2.setLocation(Location.newInstance(45, 70));
+sBuilder2.setServiceTime(90);
+sBuilder2.setTimeWindow(TimeWindow.newInstance(825,870));
+Service service2 = sBuilder2.build();
+/*
+Service service3 = ...
+Service service4 = ...
+Service service5 = ...
+Service service6 = ...
+*/
+
+ +Put vehicle and services together to setup the problem. +
/*
+ * again define a builder to build the VehicleRoutingProblem
+ */
+VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
+vrpBuilder.addVehicle(vehicle);
+vrpBuilder.addJob(service1).addJob(service2);
+/*
+vrpBuilder.addJob(service3).addJob(service4).addJob(service5).addJob(service6);
+*/
+/*
+ * build the problem
+ * by default, the problem is specified such that FleetSize is INFINITE, i.e. an infinite number of 
+ * the defined vehicles can be used to solve the problem
+ * by default, transport costs are computed as Euclidean distances
+ */
+VehicleRoutingProblem problem = vrpBuilder.build();
+
+ + +To solve it, define an algorithm. Here, it comes out-of-the-box. The SchrimpfFactory creates an algo which is an implemenation of [Schrimpf et al.](http://www.sciencedirect.com/science/article/pii/S0021999199964136). + +You might be interested in other algorithm configurations, here you can find a set of ready-to-use and benchmarked algorithms. + +
/*
+* get the algorithm out-of-the-box. 
+*/
+VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(problem);
+
+/*
+* and search a solution which returns a collection of solution (here only one solution is in the collection)
+*/
+Collection solutions = algorithm.searchSolutions();
+	
+/*
+ * use helper to get the best 
+ */
+VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions);
+
+ +Please visit Simple Example to get to know how you can analyse the solution. \ No newline at end of file diff --git a/docs/Vrp-with-pickups-and-deliveries.md b/docs/Vrp-with-pickups-and-deliveries.md new file mode 100644 index 00000000..a8868fbf --- /dev/null +++ b/docs/Vrp-with-pickups-and-deliveries.md @@ -0,0 +1,34 @@ +This example assumes that you know [SimpleExample](https://github.com/jsprit/jsprit/wiki/Simple-Example) and covers: +- defining shipments + +The only difference compared to SimpleExample is the creation of shipments instead of services. However, you define them much like you define services: +
/*
+* 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").addSizeDimension(0,1).setPickupLocation(Location.newInstance(5,7))
+.setDeliveryLocation(Location.newInstance(6, 9)).build();
+Shipment shipment2 = Shipment.Builder.newInstance("2").addSizeDimension(0,1).setPickupLocation(Location.newInstance(5,13))
+.setDeliveryLocation(Location.newInstance(6, 11)).build();
+Shipment shipment3 = Shipment.Builder.newInstance("3").addSizeDimension(0,1).setPickupLocation(Location.newInstance(15,7))
+.setDeliveryLocation(Location.newInstance(14, 9)).build();
+Shipment shipment4 = Shipment.Builder.newInstance("4").addSizeDimension(0,1).setPickupLocation(Location.newInstance(15,13))
+.setDeliveryLocation(Location.newInstance(14, 11)).build();
+                
+VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
+
+/*
+ * add these shipments to the problem
+ */
+vrpBuilder.addJob(shimpent1).addJob(shimpent2).addJob(shimpent3).addJob(shimpent4);
+
+
+ +and proceed with what you know from SimpleExample. The entire code of the example can be found here. + +You might also be interested in combining shipments and (depot-bounded) services. Look at the code of [this](https://github.com/jsprit/jsprit/blob/v1.6/jsprit-examples/src/main/java/jsprit/examples/SimpleEnRoutePickupAndDeliveryWithDepotBoundedDeliveriesExample.java) example.