DOCS Getting started

Source layout

Production Rust code lives in src/. Unit tests live in tests/unit/, and public-interface integration suites live in subsystem directories under tests/. See the test guide for registration and commands. Runnable demonstrations belong in examples/.

Directory Responsibility
src/core/ Errors, options, logging, and conservative floating-point arithmetic
src/graph/ Graphs, resources, neighborhoods, and bucket construction
src/labeling/ Label storage, dominance, and directional labeling engines
src/pricing/ Stateful pricing, restrictions, cut preparation, and retained route universes
src/enumeration/ Route-domain proofs and bounded path enumeration
src/cuts/ Cut families, registration, and shared separation machinery
src/master/ LP interfaces, column generation, root solving, branching, and tree search
src/master/mp/ Shared masters with independently priced networks and imported columns
src/master/solvers/ Clp, HiGHS, and Gurobi adapters and shared MIP controls
src/extensions/ HGS, IPM, electric-vehicle routing, p-step, robust routing, and column elimination (ce)
src/inputs/ Instance parsing and graph construction
src/bin/baldes/ Executable entry point and command implementations

A module with production child files uses name/mod.rs; a leaf module uses name.rs. This keeps the parent and its implementations together. Rust module paths stay independent of these physical filenames. Private implementation modules group work by responsibility, while the parent defines shared data and exports the public interface.

pricing/mod.rs defines the solver state. Construction, configuration, cut preparation, restriction application, and lifecycle changes have separate implementations. master/mp/mod.rs defines its shared model and state; pricing.rs implements network pricing callbacks, and solve.rs implements initialization and the solve workflow.

Keep test bodies and fixtures outside src/. Attach private unit tests with feature-gated #[path] module declarations so tests do not require widening production visibility. Keep implementation-specific test adapters gated with #[cfg(test)] when they must access private fields. Extension guides belong in docs/extensions/; dependency licenses remain alongside their implementation.

Responsibility within large modules

The top-level directories follow solver responsibilities. Keep that grouping as new models and algorithms arrive. In particular, multiple pricing networks still belong to master/, while a specialized routing formulation belongs to extensions/. Low-level route enumeration belongs to enumeration/; installing its routes into a restricted master belongs to master/.

Module Internal ownership
graph/coupled/kernel/mod.rs Shared kernel/state types, state inspection, graph attachment, and child declarations
graph/coupled/kernel/preparation.rs Prepare definitions, configure objectives, and validate graph compatibility
graph/coupled/kernel/extension.rs Create directional labels, extend arcs, and replay paths
graph/coupled/kernel/joining.rs Join forward/backward states and compute the joined objective
master/mp/enumeration/mod.rs Public options/reports and snapshot enumeration entry point
master/mp/enumeration/collection.rs Collect complete or cutoff-bounded route universes under shared budgets
master/mp/enumeration/transfer.rs Install a collected universe atomically on a private master
master/mp/enumeration/pricing.rs Price the installed finite universe
master/mp/enumeration/mip.rs Solve integer copies and check original-domain encoding
master/mp/enumeration/cutoff.rs Own the improvement-domain snapshot and expose its restricted guarantees
master/cg/setup.rs Validate options and warm-start metadata before execution
master/cg/driver.rs Sequence master solves, pricing, stabilization, cuts, and handoffs

Kernel submodules with their own implementations (front, relation, dominance, and certificate) also use mod.rs. Moving a file into its module directory does not change its Rust import path.

Naming and split decisions

Use established solver vocabulary (price, extend, join, dominates, separate) when the enclosing type or module supplies the subject. Prefer a more specific verb when several subjects share the scope: collect_routes and collect_routes_with_plan distinguish route-universe construction from iterator collection. Public names such as Options, Output, and Status remain useful under a descriptive module path; import them with a module qualifier when several solvers appear in one file.

Keep implementation state near its consumer. For example, column generation's IpmAccuracy belongs beside its loop rather than among its public data types. Keep private helpers private to their owning module; sibling implementations may share them through a restricted parent visibility. Re-export public types and entry points from their existing parent so callers do not learn the internal file layout.

Split when a file contains independently explainable responsibilities. Keep extension and replay together because they share the same transition rules. Avoid extracting each short helper into its own file or creating generic utils modules. A long mathematical routine may remain cohesive; line count alone does not justify another interface.

Remaining redesign candidates

The organization review identifies these next areas for deeper work:

  • master/cg/driver.rs: the main loop still coordinates many mutable values and several restart paths. A future extraction should give iteration state a single owner and test warm starts, feasibility recovery, cut remapping, and enumeration handoffs together. Moving individual branches behind helpers with long mutable argument lists would retain that coupling.
  • graph/coupled/kernel/relation/mod.rs and graph/coupled/kernel/bounds.rs: separate preparation, directional operations, and mathematical helpers only where they can share a small internal interface. Existing specialized child implementations provide starting points; preserve numerical evaluation order when extracting code.
  • bin/baldes/routing.rs: consider separating command configuration from execution and result rendering when adding another routing command.

The canonical namespaces are baldes::master::cg for column generation, baldes::master::mp for multi-pricing, and baldes::extensions::ce for column elimination. Source and mirrored unit-test folders use those abbreviations as well. These namespace renames require Rust callers to update their imports; descriptive algorithm method names remain unchanged. Internal file splits preserve the remaining public interfaces and numerical algorithms. This is a structural pass, not an exhaustive correctness or dead-code audit of every function. Further function renames should follow call-site evidence and domain meaning rather than a global naming substitution.

BALDES · Rust tools for vehicle routing · MIT license