Optaweb Vehicle Routing Docs
Optaweb Vehicle Routing Docs
Version 7.45.0.Final
Table of Contents
1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1. What is OptaWeb Vehicle Routing? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Quickstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1. Install Java 8 or higher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2. Download distribution archive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3. Run OptaWeb Vehicle Routing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3. Run locally using the script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.1. Quickstart mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.2. Interactive mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.2.1. Download a new region using the script. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.2.2. Select a region and run OptaWeb Vehicle Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.3. Non-interactive mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.4. Air distance mode. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.5. Tweak the data directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
4. Run locally without the script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.1. Download routing data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.2. Create data directory structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.3. Run using the java command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5. Run on OpenShift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
5.1. Running on a local OpenShift cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
5.1.1. Updating the deployed application with local changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
6. Using OptaWeb Vehicle Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6.1. Creating a route . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6.2. Viewing and setting other details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6.3. Creating custom data sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
6.4. Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
7. Development guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
7.1. Project structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
7.2. Developing OptaWeb Vehicle Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
7.3. Back end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
7.3.1. Running the back end using Spring Boot Maven plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
7.3.2. Automatic restart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
7.3.3. Running the back end from IntelliJ IDEA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
7.3.4. Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
7.3.5. Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
7.4. Front end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
7.4.1. Setting up the development environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
7.4.2. Install npm dependencies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
7.4.3. Running the development server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
7.4.4. Running tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
7.4.5. Changing the back end location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
7.5. Building the project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Appendix A: Back end architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
A.1. Code organization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
A.2. Dependency rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
A.3. The domain package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
A.4. The service package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
A.5. The plugin package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Appendix B: Back end configuration properties. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
As a developer, you can use OptaWeb Vehicle Routing to optimize your vehicle fleet deliveries. In
this guide, you will create and run a sample OptaWeb Vehicle Routing application.
1
Chapter 1. Introduction
1.1. What is OptaWeb Vehicle Routing?
The main purpose of many types of businesses is to transport various types of cargo. The goal of
these businesses is to deliver a piece of cargo from the loading point to a destination and use its
vehicle fleet in the most efficient way. This type of optimization problem is referred to as the
vehicle routing problem (VRP) and has many variations.
OptaPlanner can solve many of these vehicle routing variations and provides solution examples.
OptaPlanner enables developers to focus on modeling business rules and requirements instead of
learning constraint programming theory. OptaWeb Vehicle Routing expands OptaPlanner’s vehicle
routing capabilities by providing a reference implementation that answers questions such as these:
2
Chapter 2. Quickstart
You can get up and running with OptaWeb Vehicle Routing in just a few steps. In this chapter you
will download the OptaWeb Vehicle Routing distribution archive containing a binary build of
OptaWeb Vehicle Routing. You will use a Bash script to run the binary without having to build the
project.
Procedure
1. To verify the current Java installation, enter the following command:
java -version
If you want to modify OptaWeb Vehicle Routing and build it yourself or contribute
to upstream, see Development guide.
Procedure
1. Go to https://www.optaplanner.org/download/download.html and click the OptaWeb Vehicle
Routing tab.
3
Figure 1. OptaPlanner download page
3. Extract the downloaded distribution ZIP file. The archive contains source files and a binary
build of OptaWeb Vehicle Routing as well as the OptaWeb Vehicle Routing documentation.
If the standalone JAR is not part of the distribution, build the project from source
by using the sources directory. You can use the sources directory inside the
distribution as if you have cloned the source repository from GitHub.
If Bash is not available on your system, continue to Run locally without the script.
4
Prerequisites
• Internet access is available. When OptaWeb Vehicle Routing runs it uses third-party public
services such as OpenStreetMap to display map tiles and provide search results.
Procedure
Enter the following command:
./bin/runLocally.sh
The script will download an OSM file that is needed to work with the sample data set that is
included with the application. The script also has an interactive mode you can use to download
additional regions. See Run locally using the script to learn more about the script.
5
Chapter 3. Run locally using the script
Linux and macOS users can use a Bash script called runLocally.sh to run OptaWeb Vehicle Routing.
The script automates some setup steps that would otherwise have to be carried out manually. The
script will:
• Try to associate a country code with each downloaded OSM file automatically.
• Build the project if the standalone JAR file does not exist.
• Launch OptaWeb Vehicle Routing by taking a single region argument or by selecting the region
interactively.
Prerequisites
• optaweb-vehicle-routing repository is cloned on your computer.
Procedure
1. Change directory to the project root.
2. Run ./runLocally.sh.
3. Confirm the download of the OSM file needed to work with the built-in data set.
The application starts after the OSM file is downloaded. Open http://localhost:8080 in a web
browser to work with OptaWeb Vehicle Routing.
The first start may take a few minutes because the OSM file needs to be imported
by GraphHopper and stored as a road network graph. Subsequent runs will load
the graph from the file system without importing the OSM file and will be
significantly faster.
6
3.2.1. Download a new region using the script
Procedure
1. Run ./runLocally.sh -i.
4. Repeat the previous step until you see a list with the region you want to download.
2. Select a region from the list of downloaded regions by entering its ID.
Procedure
Run ./runLocally.sh <REGION>.
Procedure
Run the runLocally.sh script with --air argument to start OptaWeb Vehicle Routing in air distance
mode:
./bin/run.sh --air
7
3.5. Tweak the data directory
• To use a different data directory, write its absolute path to the .DATA_DIR_LAST file at the project
root.
• To change country codes associated with a region, edit the corresponding file under
DATA_DIR/country_codes/.
For example, you could have downloaded an OSM file for Scotland, for which the script fails to
guess the country code. In this case, set the content of DATA_DIR/country_codes/scotland-latest
to GB.
• To remove a region, delete the corresponding OSM file from DATA_DIR/openstreetmap/ and
GraphHopper directory from DATA_DIR/graphhopper/.
8
Chapter 4. Run locally without the script
Follow this section if you cannot use runLocally.sh to run OptaWeb Vehicle Routing because Bash is
not available on your system.
The OSM data files are typically between 100 MB to 1 GB and take time to
download so it is a good idea to download the files before building or starting the
OptaWeb Vehicle Routing application.
Procedure
1. Open http://download.geofabrik.de/ in a web browser.
2. Click a region in the Sub Region list, for example Europe. The sub region’s page opens.
3. In the Sub Regions table, download the OSM file (.osm.pbf) for a country, for example Belgium.
Procedure
1. Create the openstreetmap directory in your user account home directory, for example:
$HOME/.optaweb-vehicle-routing
└── openstreetmap
2. Move all of your downloaded OSM files (files with the extension .osm.pbf) to the openstreetmap
directory.
The rest of the directory structure will be created by the OptaWeb Vehicle Routing application
when it runs for the first time. After that, your directory structure will look similar to the following
example:
9
$HOME/.optaweb-vehicle-routing
├── db
│ └── vrp.mv.db
├── graphhopper
│ └── belgium-latest
└── openstreetmap
└── belgium-latest.osm.pbf
Procedure
Enter the following command:
10
Chapter 5. Run on OpenShift
Linux and macOS users can use the runOnOpenShift.sh Bash script to install OptaWeb Vehicle
Routing on OpenShift.
Prerequisites
You have successfully built the project with Maven.
Procedure
1. To install CRC, follow the Red Hat CodeReady Containers Getting Started Guide.
b. Log in as "developer":
oc new-project <em>project_name</em>
e. Enter the following command for information about how to use the script:
./runOnOpenShift.sh --help
11
Back end
1. Change the source code and build the back end module with Maven.
cd optaweb-vehicle-routing-backend
oc start-build backend --from-dir=. --follow
Front end
1. Change the source code and build the front end module with npm.
cd optaweb-vehicle-routing-frontend
oc start-build frontend --from-dir=docker --follow
12
Chapter 6. Using OptaWeb Vehicle Routing
In the OptaWeb Vehicle Routing application, you can mark a number of locations on the map. The
first location is assumed to be the depot. Vehicles must deliver goods from this depot to every other
location that you marked.
You can set the number of vehicles and the carrying capacity of every vehicle. However, the route is
not guaranteed to use all vehicles. The application uses as many vehicles as required for an optimal
route.
• Every delivery to a location is supposed to take 1 point of vehicle capacity. For example, a
vehicle with a capacity of 10 can visit up to 10 locations before returning to the depot.
• Error information is not supported in the user interface. You must view the terminal output of
the back end to see detailed error messages.
2. Use the blue and buttons above the map to set the number of vehicles. Each vehicle has a
default capacity of 10.
a. Hover the mouse cursor over the location to see the location name.
b. Find the location name in the list in the left part of the screen.
Every time you add or remove a location or change the number of vehicles, the application creates
and displays a new optimal route. If the solution uses several vehicles, the application shows the
route for every vehicle in a different color.
13
• In the Vehicles tab, you can view, add, and remove vehicles, and also set the capacity for every
vehicle.
• In the Route tab, you can select every vehicle and view the route for this vehicle.
1. Add a depot and a number of visits by clicking on the map or using geosearch.
2. Click Export and save the file in the data set directory.
3. Edit the YAML file and choose a unique name for the data set.
After you restart the back end, files in the data set directory will be made available in the Load
demo dropdown.
6.4. Troubleshooting
If the application behaves unexpectedly, review the back end terminal output log.
1. Stop the back end by pressing Ctrl + C in the back end terminal window.
14
Chapter 7. Development guide
7.1. Project structure
The project is a multi-module Maven project.
distribution
docs standalone
backend frontend
At the bottom of the module tree there are the back end and front end modules, which contain the
application source code.
The standalone module is an assembly module that combines the back end and front end into a
single executable JAR file.
The distribution module represents the final assembly step. It takes the standalone application and
the documentation and wraps them in an archive that is easy to distribute.
In the next sections you will learn how to run both back end and front end projects in development
mode.
When a new location is entered, we calculate the travel cost between the new location and every
other location that has been entered so far, and store the travel cost in the distance matrix. The
15
travel cost calculation is performed by a routing engine called GraphHopper.
Finally, the back end module implements additional supporting functionality, such as:
• persistence,
In the next sections you will learn how to configure and run the back end in development mode. To
learn more about the back end code architecture, see Back end architecture.
7.3.1. Running the back end using Spring Boot Maven plugin
Prerequisites
• Java 8 or higher is installed.
You can manually set up the data directory and download the OSM file or you can use the run script
to complete these tasks.
Procedure
To run the back end in development mode, enter the following command:
mvn spring-boot:run
Automatic restart is provided by Spring Boot DevTools and only works when the back end is
running using Spring Boot Maven Plugin. It scans files on the classpath, so you only need to
recompile your changes to trigger application restart. No IDE configuration is needed.
If your IDE has a compile-on-save feature (for example Eclipse or NetBeans), you just need to save
the files that have changed since the last compilation.
IntelliJ IDEA saves changes automatically and you need to select either Build › Recompile, which
recompiles the file in the active tab, or Build › Build Project which recompiles all changes. See
Compile and build applications with IntelliJ IDEA.
b. Click the green symbol in the editor window gutter and select Run
'OptaWebVehicleRoutingApplication'.
16
The run fails because the working directory is set to the root of the project,
whereas the back end module directory is expected. You are going to
change the working directory in the next step.
5. Optionally, set On Update action to Hot swap classes and update trigger file if failed. This
will allow you to use the Update action to quickly restart the application.
See Spring and Spring Boot in IntelliJ IDEA 2018.1 for more details.
7.3.4. Configuration
There are many ways that you can set configuration properties. If you are running locally, you will
probably want to use one of these:
• Use a command line argument when running the packaged application (for example java -jar
optaweb-vehicle-routing-backend.jar --app.my-property=value1).
You can learn more about configuring a Spring Boot application on the Spring Boot Externalized
Configuration page.
The backend has a strictly enforced code style. Code formatting is done by the Eclipse code
formatter, using the config files found in the ide-configuration directory. By default when you run
./mvnw install the code will be formatted automatically. When submitting a pull request the CI
build will fail if running the formatter results in any code changes, so it is recommended that you
always run a full Maven build before submitting a pull request.
17
If you want to run the formatting without doing a full build, you can run ./mvnw process-sources.
Eclipse Setup
Open the Preferences window, and then navigate to Java → Code Style → Formatter. Click Import
and then select the eclipse-format.xml file in the ide-configuration directory.
Next navigate to Java → Code Style → Organize Imports. Click Import and select the
eclipse.importorder file.
IDEA Setup
Open the Preferences window (or Settings depending on your edition), navigate to Plugins and
install the Eclipse Code Formatter Plugin from the Marketplace.
Restart your IDE, open the Preferences (or Settings) window again and navigate to Other Settings
→ Eclipse Code Formatter.
Select Use the Eclipse Code Formatter, then change the Eclipse Java Formatter Config File to point to
the eclipse-format.xml file in the ide-configuration directory. Make sure the Optimize Imports box
is ticked, and select the eclipse.importorder file as the import order config file.
See also the complete list of common application properties available in Spring Boot.
7.3.5. Logging
OptaWeb uses the SLF4J API and Logback as the logging framework. The Spring environment
enables you to configure most logging aspects including levels, patterns, and log files in the same
way as any other Configuration (most often using application.properties or arguments
--property=value). See the Spring Boot Logging documentation for more information.
Following are examples of properties you can use to control logging level of some parts of the
application:
18
for production.
See Downloading and installing Node.js and npm for more information about installing npm.
Unlike Maven, the npm package manager installs dependencies in node_modules under the project
directory and does that only when requested by running npm install. Whenever the dependencies
listed in package.json change (for example when you pull changes to the master branch) you must
run npm install before you run the development server.
Procedure
1. Change directory to the front end module:
cd optaweb-vehicle-routing-frontend
2. Install dependencies:
npm install
Procedure
1. Run the development server:
npm start
2. Open http://localhost:3000/ in a web browser. By default, the npm start command attempts to
open this URL in your default browser.
19
Prevent npm start from launching your default browser
If you don’t want npm start to open a new browser tab each time you run it, export
an environment variable BROWSER=none.
You can use .env.local file to make this preference permanent. To do that, enter
the following command:
The browser refreshes the page whenever you make changes in the front end source code. The
development server process running in the terminal picks up the changes as well and prints
compilation and lint errors to the console.
Use an environment variable called REACT_APP_BACKEND_URL to change the backend URL when
running npm start or npm run build. For example:
REACT_APP_BACKEND_URL=http://10.0.0.123:8081
Note that environment variables will be "baked" inside the JavaScript bundle during the npm build,
so you need to know the back end location before you build and deploy the front end.
Learn more about the React environment variables in Adding Custom Environment Variables.
20
Appendix A: Back end architecture
Domain model and use cases are essential for the application. We put domain model at the center
of the architecture and surround it by the application layer that embeds use cases. Functions such
as route optimization, distance calculation, persistence, and network communication are
considered implementation details and are placed at the outermost layer of the architecture.
Infrastructure
Use cases
Domain
persistence coordinates network
vehicle route
distance
optimization routing
21
org.optaweb.vehiclerouting
├── domain
├── plugin # Infrastructure layer
│ ├── persistence
│ ├── planner
│ ├── routing
│ └── websocket
└── service # Application layer
├── demo
├── distance
├── location
├── region
├── reload
├── route
└── vehicle
The service package contains the application layer that implements use cases. The plugin package
contains the infrastructure layer.
Code in each layer is further organized by function. This means that each service or plugin has its
own package.
Services only depend on the domain. If a service needs to send a result (for example to the database
or to the client), it uses an output boundary interface. Its implementation is injected by the
Inversion of Control (IoC) container.
Plugins depend on services in two ways. Firstly, they invoke services based on events such as a user
input or a route update coming from the optimization engine. Services are injected into plugins
which moves the burden of their construction and dependency resolution to the IoC container.
Secondly, plugins implement service output boundary interfaces to handle use case results, for
example persisting changes to the database or sending a response to the web UI.
22
A.4. The service package
The service package contains classes that implement use cases. A use case describes something that
you want to do, for example adding new location, changing vehicle capacity, or finding coordinates
for an address. The business rules that govern use cases are expressed using the domain objects.
Services often need to interact with plugins in the outer layer, such as persistence, web, and
optimization. To satisfy the dependency rules between layers, the interaction between services and
plugins is expressed in terms of interfaces that define the dependencies of a service. A plugin can
satisfy a dependency of a service by providing a bean that implements the service’s boundary
interface. The Spring IoC container creates an instance of the plugin bean and injects it to the
service at runtime. This is an example of the inversion of control principle.
23
Appendix B: Back end configuration
properties
Property Type Example Description
app.demo.data-set-dir Relative or absolute /home/user/.optaweb- Custom data sets are
path vehicle-routing/dataset loaded from this
directory. Defaults to
local/dataset.
app.persistence.h2-dir Relative or absolute /home/user/.optaweb- The directory used by
path vehicle-routing/db H2 to store the
database file. Defaults
to local/db.
app.region.country- List of ISO 3166-1 US, GB,IE, DE,AT,CH, may Restricts geosearch
codes alpha-2 country codes be empty results.
24
Property Type Example Description
server.port Port number 4000, 8081 Server HTTP port.
25