Getting Started#
This guide walks you through installing and using the Routing library for the first time.
Prerequisites#
For Python Users#
Python 3.9 or later
pip
For C++ Users#
CMake 3.16+
C++20 compatible compiler (GCC 10+, Clang 12+, MSVC 2019+)
Git
Optional Dependencies#
Dependency |
Purpose |
Required For |
|---|---|---|
CPLEX |
Commercial MIP/CP solver |
|
HiGHS |
Open-source MIP solver |
|
OR-Tools |
Open-source CP-SAT solver |
|
CP modeling format export |
|
Installation#
Quick Install
# Clone the repository
git clone https://github.com/sohaibafifi/routing.git
cd routing
# Install Python package
cd python
pip install -e .
Verify Installation
import routing
# Initialize
routing.init()
# Check available solvers
print("Available solvers:", routing.list_solvers())
Expected output:
Available solvers: ['ga', 'ma', 'vns', 'cp/cplex', 'cp/ortools', 'mip/cplex', 'mip/highs', ...]
Build from Source
# Clone with submodules
git clone https://github.com/sohaibafifi/routing.git
cd routing
git submodule update --init --recursive
# Configure
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
# Build
cmake --build build --parallel
CMake Options
Option |
Default |
Description |
|---|---|---|
|
ON |
Build example CLIs |
|
ON |
Build test suite |
|
ON |
Build CP Optimizer backend |
|
OFF |
Build Gurobi support |
Verify Installation
# Run tests
ctest --test-dir build --output-on-failure
# Run example
./build/examples/composable/example_composable
Your First Problem#
Let’s solve a small Capacitated Vehicle Routing Problem with Time Windows (CVRPTW).
import routing
from routing.problem import ProblemBuilder
# Initialize the library
routing.init()
# Build a small problem
problem = (ProblemBuilder()
# Depot at origin, open 0-1000
.with_depot(0, 0, tw_open=0, tw_close=1000)
# 3 clients with coordinates, demand, and time windows
.add_client(1, x=10, y=0, demand=5, tw_open=0, tw_close=200, service_time=10)
.add_client(2, x=0, y=10, demand=5, tw_open=0, tw_close=200, service_time=10)
.add_client(3, x=10, y=10, demand=5, tw_open=0, tw_close=200, service_time=10)
# 2 vehicles with capacity 20
.add_vehicles(count=2, capacity=20)
.build())
# Solve with genetic algorithm
solver = routing.create_solver("ga", problem)
solver.set_param_int("iterMax", 1000)
if solver.solve(10.0):
print(f"Solution found!")
print(f"Total distance: {solver.get_objective_value():.2f}")
# Print routes
solution = solver.get_solution()
for i, route in enumerate(solution.get_routes()):
print(f" Route {i}: {route.clients}")
else:
print("No solution found")
#include <iostream>
#include <plugins/PluginBundle.hpp>
#include <plugins/attributes/ComposableCorePlugin/Problem.hpp>
#include <plugins/solvers/GASolverPlugin/GASolver.hpp>
int main() {
// Register and initialize plugins
routing::plugins::registerAllPlugins(routing::PluginRegistry::instance());
routing::PluginRegistry::instance().initializeAll();
// Create problem
routing::Problem problem;
// Enable CVRPTW attributes
problem.enableAttributes<
routing::attributes::GeoNode,
routing::attributes::Consumer,
routing::attributes::Stock,
routing::attributes::Rendezvous,
routing::attributes::ServiceQuery>();
// Add depot
auto* depot = problem.addDepot(0);
depot->addAttribute<routing::attributes::GeoNode>(0.0, 0.0);
depot->addAttribute<routing::attributes::Rendezvous>(0.0, 1000.0);
// Add clients
for (int i = 1; i <= 3; ++i) {
auto* client = problem.addClient(i);
client->addAttribute<routing::attributes::GeoNode>(
i == 2 ? 0.0 : 10.0,
i == 1 ? 0.0 : 10.0);
client->addAttribute<routing::attributes::Consumer>(5);
client->addAttribute<routing::attributes::Rendezvous>(0.0, 200.0);
client->addAttribute<routing::attributes::ServiceQuery>(10.0);
}
// Add vehicles
for (int k = 0; k < 2; ++k) {
auto* vehicle = problem.addVehicle(k);
vehicle->addAttribute<routing::attributes::Stock>(20);
}
// Solve
routing::GASolver solver(&problem);
solver.setDefaultConfiguration();
if (solver.solve(10.0)) {
std::cout << "Solution found!" << std::endl;
std::cout << "Total distance: " << solver.getObjectiveValue() << std::endl;
}
return 0;
}
Loading Benchmark Instances#
The library supports common VRP benchmark formats.
Solomon Format (CVRPTW)#
# Load a Solomon instance
problem = routing.load_solomon("data/CVRPTW/Solomon/100/c101.txt")
print(f"Clients: {problem.num_clients}")
TSPLIB Format (CVRP)#
# Load a TSPLIB/CVRPLIB instance
problem = routing.load_tsplib("data/CVRP/A/A-n32-k5.vrp")
Choosing a Solver#
The library offers multiple solvers for different needs:
Metaheuristics#
Best for large instances where optimal solutions aren’t required.
Solver |
Name |
Best For |
|---|---|---|
Genetic Algorithm |
|
General purpose, good balance |
Memetic Algorithm |
|
Higher quality, slower |
VNS |
|
Fast local improvement |
solver = routing.create_solver("ga", problem)
solver.set_param_int("iterMax", 10000)
solver.solve(60.0)
Exact Methods#
Best for small instances or when proven optimality is needed.
Solver |
Name |
Backend |
|---|---|---|
MIP (CPLEX) |
|
IBM CPLEX |
MIP (HiGHS) |
|
Open-source |
CP (CPLEX) |
|
IBM CP Optimizer |
CP (OR-Tools) |
|
Google OR-Tools |
CP (XCSP3) |
|
Export to XML format |
# Use HiGHS (open-source)
solver = routing.create_solver("mip/highs", problem)
solver.solve(300.0) # 5 minute time limit
XCSP3 Export#
Export your problem to XCSP3 format for use with any XCSP3-compatible solver:
solver = routing.create_solver("cp/xcsp3", problem)
solver.export_model("my_problem.xml")
Next Steps#
Concepts: Learn about the composable attribute system
Solvers: Detailed solver configuration and parameters
Attributes: Available problem attributes
Python API: Complete Python reference
C++ API: Complete C++ reference
Common Issues#
“No solution found”#
Check time limit - metaheuristics need time
Verify problem is feasible (capacity, time windows)
Try
feasibleOnly=Falsefor GA/MA to see intermediate solutions
Import Error#
ImportError: routing._routing_core not found
The C++ extension wasn’t built. Run:
cd python
pip install -e . --no-build-isolation
Solver Not Available#
>>> routing.list_solvers()
['ga', 'ma', 'vns'] # Missing mip/cplex, cp/cplex
CPLEX not found during build. Install CPLEX and rebuild:
cmake -S . -B build -DCPLEX_ROOT=/path/to/cplex
cmake --build build