Real-time Vehicle Routing Problem solver for field service operations. Dispatches technicians to work orders using road-accurate travel times, skill matching, and workload balancing — powered by NVIDIA cuOpt on GPU.
- Assigns technicians to work orders optimally, minimising total travel time
- Respects time windows, shift hours, lunch breaks, and daily order limits
- Optional skill matching — only qualified technicians get assigned
- Optional workload balancing — caps total service time per technician so work is spread evenly
- Real road travel times via OSRM (not straight-line estimates)
- Interactive map with colour-coded routes and priority legends
- Demo data generator — enter a city name, choose order/technician counts, and the backend auto-generates realistic scenarios using real OSM locations (via Overpass → Nominatim → random fallback chain)
- Named scenario persistence — save, load, and delete named scenarios; stored as JSON files on the backend and survive container restarts
Browser (Svelte + Leaflet)
│ HTTP (same-origin in Docker, localhost:8000 in dev)
▼
nginx ← serves UI, proxies /vrp/* to API
│
├── FastAPI (Python) ← REST API, problem validation, result formatting
│ │
│ ├── cuOpt ← NVIDIA GPU solver (DataModel → Solve)
│ └── OSRM client ← travel time matrix via HTTP
│
└── OSRM server ← road routing engine (Docker container)
Prerequisites: Docker Desktop with NVIDIA GPU runtime, CUDA-capable GPU.
git clone https://github.com/grepjava/VRP.git
cd VRP
./setup.shOpen http://localhost in your browser.
To use a different map region:
./setup.sh --map-url https://download.geofabrik.de/europe/germany-latest.osm.pbfSee SETUP.md for full installation and configuration options.
See SETUP.md — Development workflow.
The UI exposes four cuOpt settings via the ⚙ Settings panel:
| Setting | cuOpt API | Effect |
|---|---|---|
| Enforce skill matching | add_order_vehicle_match |
Hard constraint — only assigns qualified technicians |
| Minimize fleet size | set_vehicle_fixed_costs |
Penalises deploying extra vehicles |
| Balance workload | add_capacity_dimension |
Caps total service time per technician — prevents overloading without pushing routes to late in the day |
| Custom time limit | SolverSettings.set_time_limit |
More time = better solution quality |
| Drop return to base | set_drop_return_trips |
Omit the final leg back to the depot (global toggle) |
POST /vrp/optimize Run the solver
GET /health Service health check
GET /status Solver and GPU status
GET /docs Interactive API docs (Swagger)
POST /vrp/generate-demo Generate a realistic scenario for a given city
GET /vrp/scenarios List saved scenarios (name, slug, counts, created_at)
POST /vrp/scenarios Save a named scenario (technicians + work orders as JSON)
GET /vrp/scenarios/{slug} Load a saved scenario
DELETE /vrp/scenarios/{slug} Delete a saved scenario
Example request body: see SETUP.md — API usage.
| Layer | Technology |
|---|---|
| Solver | NVIDIA cuOpt (GPU-accelerated VRP) |
| Routing | OSRM (Open Source Routing Machine) |
| API | FastAPI + Uvicorn |
| GPU memory | RAPIDS RMM |
| Data | cuDF (GPU DataFrames) |
| Frontend | Svelte 4 + Leaflet |
| Container | Docker Compose + nginx |