1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00
graphhopper-jsprit/docs/before-1.7/Simple-Example.md
2016-09-01 12:17:08 +02:00

8.2 KiB

This example covers

  • building a problem,
  • building vehicleTypes and vehicles with capacity restriction,
  • building services (or customer locations),
  • plotting the problem,
  • reading and running a predefined algorithm,
  • writing out problem and solution,
  • plotting the solution,
  • printing solution stats.

Add the latest release to your pom.

Assume the following problem. We can employ one vehicle(-type) located at (10,10) with one capacity dimension, e.g. weight, and a capacity value of 2 to deliver four customers located at [(5,7),(5,13),(15,7),(15,13)], each with a demand that has a weight of 1. All employed vehicles need to return to their start-locations. Setting up this problem and solving it is as simple as coding the following lines:

First, build a vehicle with its vehicle-type:

/*
 * get a vehicle type-builder and build a type with the typeId "vehicleType" and a capacity of 2
 * you are free to add an arbitrary number of capacity dimensions with .addCacpacityDimension(dimensionIndex,dimensionValue)
 */
final int WEIGHT_INDEX = 0;
VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType").addCapacityDimension(WEIGHT_INDEX,2);
VehicleType vehicleType = vehicleTypeBuilder.build();

/*
 * get a vehicle-builder and build a vehicle located at (10,10) with type "vehicleType"
 */
VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle");
vehicleBuilder.setStartLocation(Location.newInstance(10, 10));
vehicleBuilder.setType(vehicleType); 
VehicleImpl vehicle = vehicleBuilder.build();

Second, define the deliveries as services. Make sure their size dimensions are in line with your vehicle capacity dimensions (thus here the weight-index is made final and also used to define services).

/*
 * build services with id 1...4 at the required locations, each with a capacity-demand of 1.
 * Note, that the builder allows chaining which makes building quite handy
 */
Service service1 = Service.Builder.newInstance("1").addSizeDimension(WEIGHT_INDEX,1).setLocation(Location.newInstance(5, 7)).build();
Service service2 = Service.Builder.newInstance("2").addSizeDimension(WEIGHT_INDEX,1).setLocation(Location.newInstance(5, 13)).build();
Service service3 = Service.Builder.newInstance("3").addSizeDimension(WEIGHT_INDEX,1).setLocation(Location.newInstance(15, 7)).build();
Service service4 = Service.Builder.newInstance("4").addSizeDimension(WEIGHT_INDEX,1).setLocation(Location.newInstance(15, 13)).build();

and put vehicles 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).addJob(service3).addJob(service4);
/*
 * 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();

Third, solve the problem by defining and running an algorithm. Here it comes out-of-the-box.

/*
* get the algorithm out-of-the-box. 
*/
VehicleRoutingAlgorithm algorithm = Jsprit.createAlgorithm(problem);

/*
* and search a solution which returns a collection of solutions (here only one solution is constructed)
*/
Collection<VehicleRoutingProblemSolution> solutions = algorithm.searchSolutions();

/*
 * use the static helper-method in the utility class Solutions to get the best solution (in terms of least costs)
 */
VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(solutions);

Analysing the solution here, requires an output folder in your project-directory. If you do not have one, either create it manually or add the following line 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");  
}

Write out problem and solution (for analysis or later use in another algorithm)

new VrpXMLWriter(problem, solutions).write("output/problem-with-solution.xml");

which looks like this: problem-with-solution.xml.

Or print the results to the console concisely with

SolutionPrinter.print(problem, bestSolution, Print.CONCISE);

which results in

+--------------------------+
| problem                  |
+---------------+----------+
| indicator     | value    |
+---------------+----------+
| nJobs         | 4        | 
| nServices     | 4        | 
| nShipments    | 0        | 
| fleetsize     | INFINITE | 
+--------------------------+
+----------------------------------------------------------+
| solution                                                 |
+---------------+------------------------------------------+
| indicator     | value                                    |
+---------------+------------------------------------------+
| costs         | 35.3238075793812                         | 
| nVehicles     | 2                                        | 
+----------------------------------------------------------+

or you use the Print.VERBOSE level such as

SolutionPrinter.print(problem, bestSolution, Print.VERBOSE);

and you get this addtionally:

+--------------------------------------------------------------------------------------------------------------------------------+
| detailed solution                                                                                                              |
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| route   | vehicle              | activity              | job             | arrTime         | endTime         | costs           |
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| 1       | vehicle              | start                 | -               | undef           | 0               | 0               |
| 1       | vehicle              | service               | 2               | 6               | 6               | 6               |
| 1       | vehicle              | service               | 1               | 12              | 12              | 12              |
| 1       | vehicle              | end                   | -               | 18              | undef           | 18              |
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| 2       | vehicle              | start                 | -               | undef           | 0               | 0               |
| 2       | vehicle              | service               | 3               | 6               | 6               | 6               |
| 2       | vehicle              | service               | 4               | 12              | 12              | 12              |
| 2       | vehicle              | end                   | -               | 18              | undef           | 18              |
+--------------------------------------------------------------------------------------------------------------------------------+

or plot the results with

new Plotter(problem,bestSolution).plot("output/solution.png", "solution");

and you get solution.png

or use the very basic version of the GraphStreamViewer which dynamically renders the problem and its according solution by coding

new GraphStreamViewer(problem, bestSolution).setRenderDelay(100).display();

You can find the entire code here.