Hex.pm Docs

Elixir bindings for PyVRP, a state-of-the-art Vehicle Routing Problem (VRP) solver.

Uses the same C++ core as PyVRP via NIFs for high-performance solving of CVRP, VRPTW, multi-depot, heterogeneous fleet, prize-collecting, and multi-trip problems.

Installation

Add ex_vrp to your dependencies in mix.exs:

def deps do
  [
    {:ex_vrp, "~> 0.7"}
  ]
end

Precompiled NIF binaries are available for Linux (x86_64) and macOS (ARM). On other platforms, a C++20 compiler is required.

Quick Start

model =
  ExVrp.Model.new()
  |> ExVrp.Model.add_depot(x: 0, y: 0)
  |> ExVrp.Model.add_vehicle_type(num_available: 2, capacity: [100])
  |> ExVrp.Model.add_client(x: 10, y: 10, delivery: [20])
  |> ExVrp.Model.add_client(x: 20, y: 0, delivery: [30])
  |> ExVrp.Model.add_client(x: 0, y: 20, delivery: [25])

{:ok, result} = ExVrp.solve(model, max_iterations: 1000, seed: 42)

result.best.routes      #=> [[2, 1, 3]]
result.best.distance    #=> 68
result.best.is_feasible #=> true

Route entries are location indices, not client indices — locations are ordered [depots..., clients...], so with one depot client n is location n + 1.

Features

  • Parallel multi-start solving (automatic core utilization)
  • Time windows, service durations, and shift constraints
  • Multi-dimensional capacity (weight, volume, etc.)
  • Prize-collecting with optional clients
  • Multi-trip routes with depot reloads
  • Same-vehicle grouping constraints
  • Custom distance/duration matrices
  • Configurable stopping criteria
  • Progress callbacks

See the full documentation for detailed API reference and examples.

Usage rules

ExVrp ships a usage-rules.md describing the semantics that are easy to get wrong from the type specs alone — location index offsets, capacity dimensions, vehicle time windows, optional clients, and the cost model. If your project uses usage_rules, list :ex_vrp in your project config and sync:

defp usage_rules do
  [file: "CLAUDE.md", usage_rules: [:ex_vrp]]
end
mix usage_rules.sync

Development

Prerequisites

  • Elixir 1.18+
  • C++20 compiler (gcc 11+ or clang 14+)
  • Make

Setup

mix deps.get
mix compile
mix test

mix compile downloads a precompiled NIF from a GitHub release. When changing anything under c_src/, force a local build or your changes silently have no effect:

EX_VRP_FORCE_BUILD=1 mix compile

License

MIT License - see LICENSE file.

Acknowledgments

  • PyVRP - The underlying solver
  • Fine - Ergonomic C++ NIF bindings