mamut_routing_lib.solvers.pyvrp¶
PyVRP-backed solver integration for mamut-routing-lib.
Importing this module requires the [pyvrp] optional dependency:
pip install "mamut-routing-lib[pyvrp]"
Public API
to_vrplib_dict, to_pyvrp_problem -- conversion helpers MethodResult -- solver result dataclass SolveTick, SolveMonitor -- live progress / cancellation hook solve_cvrp, solve_vrptw, solve_instance -- single-instance solvers solve_and_update_bks -- solve + write BKS if improved
SolveTick
dataclass
¶
SolveMonitor
¶
A PyVRP stopping criterion that reports the incumbent and honours cancellation.
PyVRP calls the stopping criterion once per iteration with the cost of the best solution
so far, which is the only point inside a solve where a caller can learn that anything is
happening. This criterion never stops on its own -- the MaxRuntime it is paired with
still owns the time budget. It relays throttled ticks to on_tick, and stops the search
only when on_tick returns True.
Compose it before MaxRuntime in a MultipleCriteria: that class uses any(), which
short-circuits, so a monitor placed second would go silent the moment the budget expires.
Source code in MAMUT-routing-tools/MAMUT-routing-lib/src/mamut_routing_lib/solvers/pyvrp.py
MethodResult
dataclass
¶
MethodResult(method: str, problem_type: str, objective_function: str, instance_id: str, seed: int, time_limit_s: int, wall_time: float, solver_is_feasible: bool, routes: list[list[int]] = list(), solver_cost: int | float | None = None, route_count: int = 0, vehicle_penalty: int | float = 0, metadata: dict[str, Any] = dict())
metadata
class-attribute
instance-attribute
¶
hydrate_collection_instance
¶
hydrate_collection_instance(instance: AnyBenchmarkInstance, instance_path: str | Path | None = None, arc_costs: list[list[int]] | list[list[float]] | None = None) -> AnyBenchmarkInstance
An embedded-matrix view of a slim collection instance, usable with the checker.
Non-collection instances pass through unchanged. For a collection
instance the matrix is arc_costs if given, else resolved from the
instance's arc_costs_source (resolve_arc_costs, which needs
instance_path for sidecar sources). VRPTW collection instances with
non-integer service times or windows cannot hydrate into the integer
checker model and raise ValueError.
Source code in MAMUT-routing-tools/MAMUT-routing-lib/src/mamut_routing_lib/artifacts.py
to_vrplib_dict
¶
to_vrplib_dict(instance: AnyBenchmarkInstance, arc_costs: list[list[int]] | list[list[float]] | None = None) -> dict[str, Any]
Convert a benchmark instance into a VRPLIB-shaped dict consumable by PyVRP's parser.
Source code in MAMUT-routing-tools/MAMUT-routing-lib/src/mamut_routing_lib/solvers/pyvrp.py
to_pyvrp_problem
¶
to_pyvrp_problem(instance: AnyBenchmarkInstance, round_func: str | _RoundingFunc = 'none', arc_costs: list[list[int]] | list[list[float]] | None = None) -> ProblemData
Convert a benchmark instance into a PyVRP ProblemData.
Source code in MAMUT-routing-tools/MAMUT-routing-lib/src/mamut_routing_lib/solvers/pyvrp.py
solve_cvrp
¶
solve_cvrp(instance: BenchmarkInstanceCVRP | BenchmarkInstanceCVRPCollection, *, time_limit_s: int, seed: int = 42, display: bool = False, instance_path: str | Path | None = None, monitor: SolveMonitor | None = None) -> MethodResult
Solve a CVRP instance with PyVRP's ILS (mono-cost objective only).
Source code in MAMUT-routing-tools/MAMUT-routing-lib/src/mamut_routing_lib/solvers/pyvrp.py
solve_vrptw
¶
solve_vrptw(instance: BenchmarkInstance | BenchmarkInstanceVRPTWCollection, *, objective_function: ObjectiveFunction, time_limit_s: int, seed: int = 42, display: bool = False, instance_path: str | Path | None = None, monitor: SolveMonitor | None = None) -> MethodResult
Solve a VRPTW instance with PyVRP's ILS.
For ObjectiveFunction.MONO_COST, runs a single solve with the full time budget.
For ObjectiveFunction.HIERARCHICAL_VEHICLE_COST, runs a two-phase solve:
1. Fleet minimization (PyVRP's minimise_fleet) within ~30% of the budget.
2. Cost optimization on the constrained fleet for the remaining budget,
with a per-vehicle fixed cost large enough to dominate routing cost.
Phase 2 is warm-started from a feasible solution re-found on the
constrained fleet: the fixed cost dwarfs the solver's capped
infeasibility penalties, so a cold start can otherwise stabilize on
infeasible solutions that use fewer vehicles.
Source code in MAMUT-routing-tools/MAMUT-routing-lib/src/mamut_routing_lib/solvers/pyvrp.py
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 | |
solve_instance
¶
solve_instance(instance: AnyBenchmarkInstance, *, time_limit_s: int, seed: int = 42, objective_function: ObjectiveFunction | None = None, display: bool = False, instance_path: str | Path | None = None, monitor: SolveMonitor | None = None) -> MethodResult
Dispatch to solve_cvrp or solve_vrptw based on instance type.
For VRPTW instances, objective_function defaults to MONO_COST when not provided.
For CVRP instances, the objective is fixed to MONO_COST regardless of the argument.
Slim collection instances need instance_path when their arc costs live in
a distances sidecar. Pass a SolveMonitor to observe the search while it runs.
Source code in MAMUT-routing-tools/MAMUT-routing-lib/src/mamut_routing_lib/solvers/pyvrp.py
solve_and_update_bks
¶
solve_and_update_bks(instance: AnyBenchmarkInstance, *, instance_path: str | Path, time_limit_s: int, seed: int = 42, objective_function: ObjectiveFunction | None = None, authors: str = DEFAULT_BKS_AUTHORS, display: bool = False) -> tuple[MethodResult, BKSUpdateResult | None]
Solve an instance and, if the solution is feasible, write a BKS file in place.
Returns the MethodResult and a BKSUpdateResult (or None if the solver did not
return a feasible solution). The BKS file path is derived from instance_path
via mamut_routing_lib.artifacts.get_bks_path_for_instance (handled inside
save_bks_if_improved).