Update or submit a BKS¶
A best-known solution is a solution file the checker has validated, stored next to its instance as
<base>.bks.<ObjectiveFunction>.json. Two rules make BKS maintenance safe:
- the stored cost is the checker's cost, whatever the solver reported;
- a BKS is replaced only by a strictly better, freshly validated solution; the stored file is itself re-validated before comparison, so a corrupted BKS is caught rather than silently kept.
Static families (CVRP, VRPTW)¶
From the CLI, solve and let the library decide:
uv run mamut-routing --benchmarks-dir benchmarks solve \
--problem-type CVRP --benchmark-name Mamut2026 --instance-name mamut-lyon-n1000-k91-poi \
--time-limit-s 600 --seed 7 --save-bks
From Python, with your own solution (any solver):
from mamut_routing_lib import BenchmarkSolution, save_solution_as_bks_if_improved
from mamut_routing_lib.enums import ObjectiveFunction
candidate = BenchmarkSolution(instance_name="mamut-lyon-n1000-k91-poi", routes=routes) # cost: the checker's
result = save_solution_as_bks_if_improved(
instance_path, ObjectiveFunction.MONO_COST, candidate,
authors="Your Name (handle)",
metadata={"method": "my-solver-v2", "seed": 7, "time_limit_s": 600, "solver_version": "2.1", "machine": "..."},
)
print(result.action, result.path, result.candidate_cost) # created | replaced | kept_existing
Under the hood: the instance is loaded and, for slim collection instances (Poryos2026, Mamut2026), hydrated from
its sidecars (hydrate_collection_instance); create_bks_from_solution builds the BenchmarkBKS (validation,
checker cost, metadata); save_bks_if_improved(instance, bks, instance_path) does the compare-and-replace.
One writer per instance
The store is an unlocked read/compare/write. Two processes storing candidates for the same instance at the same time can end with the worse one on disk. Serialize the stores (see Run a BKS campaign).
create_bks_from_solution raises on an invalid solution, requires a non-empty authors, and fills
validated_cost, validated_num_routes and date in the metadata. is_better_solution implements the objective's
order (HierarchicalVehicleCost compares route count first). With PyVRP, solve_and_update_bks in
mamut_routing_lib.solvers.pyvrp does the solve and the store in one call.
Time-dependent families (TDVRP, TDVRPTW)¶
The static checker refuses TD instances; use the TD store, which prices with check_td_solution (exact doubles,
no epsilon):
from mamut_routing_lib.td.bks import save_td_solution_as_bks_if_improved, annotate_td_bks_optimality
from mamut_routing_lib.enums import ObjectiveFunction
result = save_td_solution_as_bks_if_improved(instance_path, candidate, authors="...",
objective_function=ObjectiveFunction.DURATION)
Each objective has its own store file (.bks.Duration.json, .bks.FleetCostDuration.json). With the tools,
mamut-tools solve --solver kayros solves the Duration objective; its --update-bks is wired for PyVRP only, so
TD results go through the library call above.
Optimality proofs¶
A proven optimum is metadata, validated like everything else (OptimalityMetadata: proven: true, prover,
certificate, date, optional proven_optimum, dual_bound, wall_time_s, time_limit_s, checker,
campaign, note). For TD stores:
annotate_td_bks_optimality(instance_path, {"proven": True, "prover": "kayros 1.1.2", "certificate": "...",
"date": "2026-09-14"}, ObjectiveFunction.DURATION)
The stored BKS is re-validated before the stamp is written, and a declared proven_optimum must equal the stored
cost (a dust-level difference needs an explanatory note).
After the file changed¶
- Route geometry. The website draws BKS routes on the road network from a cache keyed by the BKS sha256. A
replaced BKS of a road-network family (Poryos2026, Mamut2026
shortest/fastest) needs its geometry rebuilt: Do it locally, not on the site VM (a large city graph can exceed 15 GiB); the deploy reuses the cache by content. - Changelog of the family (satellite or in-repo), with the source of the improvement.
- Publish. The history ledger counts the BKS as
improved; regressions are impossible by construction but a removed file shows up asremoved.
Contributions from outside¶
Point contributors to the FAQ's contribution section: a pull request on the satellite (or an issue with the solution file) is enough. Run the checker on their file yourself before merging; never trust a reported cost.