routik_solver/lib.rs
1//! # routik-solver
2//!
3//! Pure VRP core (no I/O) for the capacitated VRP with time windows (CVRPTW).
4//! It holds the data model, the [`CostMatrix`] abstraction, the Clarke-Wright
5//! savings construction, the local-search neighbourhoods, and a simulated-
6//! annealing metaheuristic ([`solve`]).
7//!
8//! The solver depends on the [`CostMatrix`] trait **only** — distances and
9//! times come from behind it, never from a baked-in map engine. Implementations
10//! are [`HaversineMatrix`] (straight-line + a configurable speed) and
11//! [`EuclideanMatrix`] (planar, unit speed — the Solomon-benchmark convention).
12//!
13//! Hard constraints (capacity, time windows) are always respected;
14//! [`solve`] never returns a worse solution than the construction baseline
15//! under the configured [`Objective`], and is deterministic for a given seed.
16//!
17//! ```
18//! use routik_solver::{solve, Coord, HaversineMatrix, Problem, SolverConfig, Stop, StopId, Vehicle, VehicleId};
19//!
20//! let problem = Problem {
21//! depot: Coord::new(48.8566, 2.3522),
22//! stops: vec![Stop {
23//! id: StopId(1),
24//! coord: Coord::new(48.8606, 2.3376),
25//! demand: 10,
26//! time_window: None,
27//! service_time: 0.1,
28//! }],
29//! vehicles: vec![Vehicle { id: VehicleId(1), capacity: 50 }],
30//! depot_window: None,
31//! };
32//! let matrix = HaversineMatrix::from_problem(&problem, 50.0);
33//! let solution = solve(&problem, &matrix, &SolverConfig::default()).expect("feasible");
34//! assert!(solution.feasible);
35//! ```
36
37pub mod anneal;
38pub mod clarke_wright;
39mod feasibility;
40pub mod matrix;
41pub mod model;
42pub mod objective;
43mod search;
44
45/// Property-test / fuzz support: an independent invariant oracle and an
46/// `arbitrary`-driven instance builder. Compiled for the crate's own tests and,
47/// behind the `fuzzing` feature, for the external cargo-fuzz crate.
48#[cfg(any(test, feature = "fuzzing"))]
49pub mod testkit;
50
51#[cfg(test)]
52mod proptest_suite;
53
54pub use anneal::{Budget, SolveStats, SolverConfig, solve, solve_with_stats};
55pub use clarke_wright::{SolveError, clarke_wright};
56pub use matrix::{CostMatrix, EuclideanMatrix, HaversineMatrix, MatrixError, ProvidedMatrix};
57pub use model::{
58 Coord, LocationId, Problem, Route, Solution, Stop, StopId, TimeWindow, Unassigned,
59 UnassignedCode, Vehicle, VehicleId,
60};
61pub use objective::Objective;