| Title: | Vehicle Routing Problem Solver Built on 'PyVRP' |
| Version: | 0.1.0 |
| Description: | A 'tidyverse'-style interface to high-performance vehicle routing problem (VRP) solving. Vendors the C++ core of the 'PyVRP' solver (https://github.com/PyVRP/PyVRP) and rewires it through 'cpp11', with no 'Python' runtime dependency. Supports the capacitated VRP, time windows, multiple depots, heterogeneous fleets, prize-collecting and multi-trip variants, driven by an iterated local search metaheuristic. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/StrategicProjects/vrpr, https://strategicprojects.github.io/vrpr/ |
| BugReports: | https://github.com/StrategicProjects/vrpr/issues |
| Encoding: | UTF-8 |
| Depends: | R (≥ 4.3) |
| Imports: | cli, rlang, stats, tibble, vctrs |
| LinkingTo: | cpp11 |
| Suggests: | ggplot2, knitr, reticulate, rmarkdown, testthat (≥ 3.0.0), withr |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| SystemRequirements: | C++20, GNU make |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | yes |
| Packaged: | 2026-06-28 13:14:25 UTC; leite |
| Author: | Andre Leite [aut, cre], Marcos Wasilew [aut], Hugo Vasconcelos [aut], Carlos Amorin [aut], Diogo Bezerra [aut], Niels Wouda [ctb, cph] (author of the vendored PyVRP C++ core), Thibaut Vidal [cph] (HGS-CVRP, parts of the vendored C++ core), ORTEC [cph] (HGS-DIMACS, parts of the vendored C++ core) |
| Maintainer: | Andre Leite <leite@castlab.org> |
| Repository: | CRAN |
| Date/Publication: | 2026-07-04 07:10:02 UTC |
vrpr: Vehicle Routing Problem Solver Built on 'PyVRP'
Description
A 'tidyverse'-style interface to high-performance vehicle routing problem (VRP) solving. Vendors the C++ core of the 'PyVRP' solver (https://github.com/PyVRP/PyVRP) and rewires it through 'cpp11', with no 'Python' runtime dependency. Supports the capacitated VRP, time windows, multiple depots, heterogeneous fleets, prize-collecting and multi-trip variants, driven by an iterated local search metaheuristic.
Author(s)
Maintainer: Andre Leite leite@castlab.org
Authors:
Andre Leite leite@castlab.org
Marcos Wasilew marcos.wasilew@gmail.com
Hugo Vasconcelos hugo.vasconcelos@ufpe.br
Carlos Amorin carlos.agaf@ufpe.br
Diogo Bezerra diogo.bezerra@ufpe.br
Other contributors:
Niels Wouda (author of the vendored PyVRP C++ core) [contributor, copyright holder]
Thibaut Vidal (HGS-CVRP, parts of the vendored C++ core) [copyright holder]
ORTEC (HGS-DIMACS, parts of the vendored C++ core) [copyright holder]
See Also
Useful links:
Report bugs at https://github.com/StrategicProjects/vrpr/issues
Add a mutually exclusive group of clients
Description
Defines a group from which at most one client is visited (or exactly one if
required = TRUE). Useful for prize-collecting with exclusive alternatives
(e.g. serving one of several equivalent points). Clients in the group
automatically become optional (individual required = FALSE); use prize to
encourage a visit.
Usage
add_client_group(model, clients, required = FALSE)
Arguments
model |
A |
clients |
Vector of client numbers (1-based, in the order of
|
required |
If |
Value
The updated vrpr_model.
Add clients to the model
Description
Add clients to the model
Usage
add_clients(model, data)
Arguments
model |
A |
data |
A tibble/data.frame with at least the columns |
Value
The updated vrpr_model.
Add a depot to the model
Description
Add a depot to the model
Usage
add_depot(model, x, y, tw_early = 0, tw_late = Inf, service = 0)
Arguments
model |
A |
x, y |
Depot coordinates. |
tw_early, tw_late |
Depot time window (opening/closing). |
service |
Service time at the depot (e.g. loading), per trip. |
Value
The updated vrpr_model.
Add a vehicle type to the model
Description
Add a vehicle type to the model
Usage
add_vehicle_type(
model,
num_available,
capacity,
fixed_cost = 0,
tw_early = 0,
tw_late = Inf,
max_duration = Inf,
unit_distance_cost = 1,
unit_duration_cost = 0,
depot = 1L,
start_depot = depot,
end_depot = depot,
reload_depots = integer(0),
max_reloads = Inf
)
Arguments
model |
A |
num_available |
Number of vehicles available of this type. |
capacity |
Vehicle capacity. |
fixed_cost |
Fixed cost per vehicle used. |
tw_early, tw_late |
Vehicle shift time window (start/end). |
max_duration |
Maximum route duration. |
unit_distance_cost, unit_duration_cost |
Variable cost per unit of
distance and of duration for this type. Varying these (and |
depot |
Index (1-based) of the depot vehicles of this type start from and
return to. Shortcut to set |
start_depot, end_depot |
Indices (1-based) of the start and end depots, in
the order of |
reload_depots |
Indices (1-based) of depots where vehicles of this type may reload/empty mid-route, enabling multi-trip routes. Empty (default) = no reloading. |
max_reloads |
Maximum number of reloads per route. |
Details
Call add_vehicle_type() several times for a fleet with multiple
vehicle types (different capacities, costs, shifts or depots).
Value
The updated vrpr_model.
Cost of a result or solution
Description
Cost of a result or solution
Usage
cost(x, ...)
Arguments
x |
A |
... |
Unused. |
Value
The objective cost (a numeric scalar); Inf if no feasible solution
was found.
ILS solver parameters
Description
ILS solver parameters
Usage
ils_params(
num_neighbours = 20L,
min_perturbations = 1L,
max_perturbations = 25L,
init_load = 20,
init_tw = 6,
init_dist = 6,
history_length = 300L,
num_iters_no_improvement = 150000L,
exhaustive_on_best = TRUE
)
Arguments
num_neighbours |
Granular neighbourhood size (k neighbours per client). |
min_perturbations, max_perturbations |
Range of perturbations per iteration. |
init_load, init_tw, init_dist |
Initial penalties. |
history_length |
Length of the late-acceptance history (> 0). Default 300, as in PyVRP. |
num_iters_no_improvement |
Iterations without improvement before restarting from the best. |
exhaustive_on_best |
Refine each new best with an exhaustive search? |
Value
A list of parameters.
Plot a VRP model (depots and clients only)
Description
Plot a VRP model (depots and clients only)
Usage
## S3 method for class 'vrpr_model'
plot(x, ...)
Arguments
x |
A |
... |
Unused. |
Value
A ggplot object.
Plot the solution of a VRP result
Description
Draws depots, clients and the routes (one colour per route) over the instance coordinates. Unvisited optional clients (prize-collecting) appear as hollow circles.
Usage
## S3 method for class 'vrpr_result'
plot(x, show_clients = TRUE, ...)
Arguments
x |
A |
show_clients |
Reserved; clients are always drawn. |
... |
Unused. |
Value
A ggplot object.
Read a VRPTW instance in Solomon format
Description
Reads VRPTW instances in Solomon (and Gehring-Homberger) format, with the
VEHICLE section (number and capacity) and the CUSTOMER table (coordinates,
demand, time window and service time). Customer 0 is the depot.
Usage
read_solomon(path, num_vehicles = NULL)
Arguments
path |
Path to the file. |
num_vehicles |
Number of vehicles; if |
Value
A vrp_model() ready for vrp_solve().
Read an instance in VRPLIB / TSPLIB format
Description
Reads CVRP (and VRPTW) instances in VRPLIB/CVRPLIB format (extended TSPLIB),
such as the X set by Uchoa et al. Supports Euclidean coordinates
(EDGE_WEIGHT_TYPE : EUC_2D); time-window and service-time sections are read
when present.
Usage
read_vrplib(path, num_vehicles = NULL)
Arguments
path |
Path to the |
num_vehicles |
Number of available vehicles. If |
Value
A vrp_model() ready for vrp_solve().
Routes of a solution, in long (tidy) format
Description
Routes of a solution, in long (tidy) format
Usage
routes(x, ...)
Arguments
x |
|
... |
Unused. |
Value
A tibble with one row per visit: route_id, depot (start depot,
1-based), position, client, vehicle_type, start_service (start of
service) and wait (waiting time). The last two are only meaningful with
time windows (VRPTW); depot varies in the MDVRP.
Cost of a solution
Description
Cost of a solution
Usage
solution_cost(solution, cost_evaluator = NULL)
Arguments
solution |
|
cost_evaluator |
A |
Value
The penalised cost (a numeric scalar). For feasible solutions this
is the objective cost; the feasible attribute reports feasibility.
One-row summary of a result (tibble)
Description
One-row summary of a result (tibble)
Usage
## S3 method for class 'vrpr_result'
summary(object, ...)
Arguments
object |
A |
... |
Unused. |
Value
A one-row tibble with cost, feasibility, number of routes, iterations and runtime.
Unvisited optional clients
Description
In prize-collecting problems, clients with required = FALSE may be left out
if the prize does not offset the routing cost.
Usage
unvisited_clients(x, ...)
Arguments
x |
A |
... |
Unused. |
Value
An integer vector of the (1-based) client numbers not visited.
Cost evaluator (CostEvaluator)
Description
Creates a penalised-cost evaluator. Penalties multiply constraint violations (load, time window, maximum distance) to form the smoothed cost the solver minimises. For a feasible solution, the penalised cost equals the objective cost.
Usage
vrp_cost_evaluator(load_penalties = 1, tw_penalty = 1, dist_penalty = 1)
Arguments
load_penalties |
Penalty per unit of excess load, per load dimension. A scalar is recycled across all dimensions. |
tw_penalty |
Penalty per unit of time warp (time-window violation). |
dist_penalty |
Penalty per unit of distance above the maximum. |
Value
A vrpr_cost_evaluator object.
Build a vehicle routing (VRP) model
Description
vrp_model() creates an empty model to which depots, clients and vehicle
types are added via the pipe (|>). It is the tidy equivalent of PyVRP's
Model class – the data boundary uses tibbles, not one object at a time.
Usage
vrp_model()
Value
A vrpr_model object.
Examples
clients <- tibble::tibble(
x = c(10, 25, 40), y = c(5, 30, 12),
demand = c(10, 15, 8)
)
m <- vrp_model() |>
add_depot(x = 0, y = 0) |>
add_clients(clients) |>
add_vehicle_type(num_available = 5, capacity = 100)
m
Assemble the problem data (ProblemData) from a model
Description
Builds PyVRP's C++ ProblemData structure from a vrp_model(). Locations
follow PyVRP's convention: depots first (low indices), then clients.
Usage
vrp_problem_data(model, distance = NULL, duration = NULL)
Arguments
model |
A |
distance, duration |
Matrices ( |
Details
Integer measures (distance, duration, cost, load) travel as R numeric with
integer semantics; non-integer values are rejected at the C++ boundary. Use
Inf for "unconstrained" limits (e.g. tw_late).
Value
A vrpr_problem_data object (a wrapper around a C++ external pointer).
Generate a random solution
Description
Generate a random solution
Usage
vrp_random_solution(problem_data, seed = 42L)
Arguments
problem_data |
|
seed |
Integer seed. |
Value
A vrpr_solution object.
Build a solution from explicit routes
Description
Build a solution from explicit routes
Usage
vrp_solution(problem_data, routes)
Arguments
problem_data |
|
routes |
A list of integer vectors; each vector is a route given as client numbers (1..n_clients), in visit order. All routes use the first vehicle type. |
Value
A vrpr_solution object.
Solve a VRP model
Description
Runs the iterated local search (ILS) solver on a model, using PyVRP's vendored C++ core.
Usage
vrp_solve(model, stop, seed = 42L, params = ils_params(), display = TRUE)
Arguments
model |
A |
stop |
A stopping criterion (see vrpr_stop), e.g. |
seed |
Integer seed for reproducibility. |
params |
Solver parameters (see |
display |
Show progress via |
Value
A vrpr_result object with the best solution, cost, routes and run
statistics. Use cost(), routes() and summary() to inspect it.
Examples
clients <- tibble::tibble(
x = c(10, 25, 40, 15), y = c(5, 30, 12, 22),
demand = c(10, 15, 8, 12)
)
res <- vrp_model() |>
add_depot(x = 0, y = 0) |>
add_clients(clients) |>
add_vehicle_type(num_available = 3, capacity = 50) |>
vrp_solve(stop = max_iterations(200), display = FALSE)
cost(res)
routes(res)
Solver stopping criteria
Description
Control when the iterated local search loop should terminate. Each function
returns a callable object (closure) that the solver invokes every iteration,
receiving the cost of the current best solution and returning TRUE to stop.
Usage
max_runtime(seconds)
max_iterations(max_iters)
no_improvement(n)
first_feasible()
Arguments
seconds |
Maximum run time, in seconds. |
max_iters |
Maximum number of iterations. |
n |
Number of consecutive iterations without improvement before stopping. |
Details
These are the R equivalent of PyVRP's pyvrp.stop module.
Value
An object of class vrpr_stop: a function
function(best_cost, feasible) returning TRUE/FALSE.