tabench.models

The road-assignment model roster and the MODEL_REGISTRY, plus the CallableModel wrapper and external-engine adapters. Optional-extra models (torch, sumo, dtalite) register only when their extra is installed.

Benchmark models: white-box solvers and black-box adapters.

class tabench.models.AlgorithmBModel(**factor_overrides)[source]

Bases: _BushMachinery, TrafficAssignmentModel

Dial (2006) Algorithm B, origin-by-origin Gauss-Seidel over bushes.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.CallableModel(fn, name='callable', paradigm='learned', deterministic=False, seedable=True, trained_on=())[source]

Bases: TrafficAssignmentModel

Adapter turning fn(scenario, rng) -> link_flows into a benchmark model.

capabilities are instance-level here (unlike library solvers, which declare them on the class), because they describe the wrapped artifact: pass trained_on lineage for learned models so the fairness gate can act on it.

Parameters:
  • fn (FlowFn)

  • name (ClassVar[str])

  • paradigm (str)

  • deterministic (bool)

  • seedable (bool)

  • trained_on (tuple[str, ...])

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.DTALiteSimulationAdapter(*, iterations=16, keep_files=False)[source]

Bases: object

Emit the EDOC-1 artifact contract for one EdocScenario: P0 from the R9 route_assignment.csv construction, then iterations MSA 1/(k+2) best-response blends — each iterate replays the current plans through the pinned engine, builds the substrate frozen field + origin-wait profiles, finds each agent’s BR route with the certifier’s own composition, and moves a hash-picked 1/(k+2) fraction of the improvers onto their BR routes (departures never move — G2). The loop is ROW-LOCAL (adr-036 names no substrate MSA deliverable; hoisting waits for a second router-less engine). iterations=0 emits the R9 step-0 FW split as-is — the row’s negative-control state. The measured one-step overshoot (the pilot’s 0.394 -> 0.513) is WHY the model is the smoothed blend, not the one-step BR (R12: realized-BR is Tier-B, never scored).

X is defined by this adapter’s own pinned replay of the final P (the S2/S3 artifact contract); the certifier re-runs the identical replay for G1. Deterministic track: seedable=False — the engine consumes no seed (LCG re-seeded per time step), disclosed.

Parameters:
  • iterations (int)

  • keep_files (bool)

emit(scenario, *, wall_seconds=None)[source]

R9 assignment -> MSA loop -> pinned replay for X, all under one wall deadline. RAISES on any engine/infra failure and on an in-loop boost-census crossing (pair 12’s every-constructor-side-run clause: the model’s own field would be boost-contaminated); never returns a partial or self-reported result.

Parameters:
Return type:

EmittedBundle

class tabench.models.MatsimAdapter(*, iterations=10, keep_files=False)[source]

Bases: object

Emit the EDOC-1 artifact contract for one EdocScenario by running the pinned MATSim co-evolution loop (plans P = the final iterate’s selected plans under scenario.seed) and then THIS adapter’s own pinned zero-replanning replay of P (the experienced record X + provenance — the adr-037 clarification: X is DEFINED by the pinned replay map, never scraped from the solver’s internals). The certifier’s G1 re-runs the identical replay. iterations is the co-evolution length (lastIteration); iteration 0 executes the free-flow-routed initial plans, so iterations=0 is the AON control state.

Parameters:
  • iterations (int)

  • keep_files (bool)

emit(scenario, *, wall_seconds=None)[source]

Write inputs -> run the co-evolution -> read P -> pinned replay for X, all under one wall deadline. RAISES on any engine/infra failure (never a partial or self-reported result).

Parameters:
Return type:

EmittedBundle

class tabench.models.AllOrNothingModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Assign every trip to its free-flow shortest path.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.TrafficAssignmentModel(**factor_overrides)[source]

Bases: ABC

Base class every benchmark model or wrapper implements.

Parameters:

factor_overrides (Any)

abstractmethod solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

tabench.models.register_model(cls)[source]

Class decorator adding a model to the name registry (BO4Mob pattern).

Only self-contained models belong here: the registry is what the CLI instantiates with no arguments, so a registered class must declare its name and capabilities at class level. Adapter-style models with per-instance capabilities (e.g. CallableModel) are used by passing instances directly to run_experiment and must not be registered.

Parameters:

cls (type[TrafficAssignmentModel])

Return type:

type[TrafficAssignmentModel]

class tabench.models.BiconjugateFrankWolfeModel(**factor_overrides)[source]

Bases: ConjugateFrankWolfeModel

Bi-conjugate Frank-Wolfe (BFW, Mitradjieva & Lindberg 2013).

The search point combines the AON solution with the previous TWO search points so the new direction is H-conjugate to both previous directions (paper eqs 8-9 and Appendix A). Ramps FW -> CFW -> BFW on warm-up and after every restart, which also guarantees the stored step size is < 1.

Parameters:

factor_overrides (Any)

class tabench.models.ConjugateFrankWolfeModel(**factor_overrides)[source]

Bases: _FrankWolfeFamily

Conjugate-direction Frank-Wolfe (CFW, Mitradjieva & Lindberg 2013).

The search point is s_k = a s_{k-1} + (1-a) y_k with a chosen so the new direction is H-conjugate to the previous one, where H is the diagonal Beckmann Hessian t’(v) at the current flows (paper eqs 2-6). A step of ~1 lands on the search point and restarts the method (FW step next); a = 0 recovers plain FW, so every safeguard degrades gracefully.

Parameters:

factor_overrides (Any)

class tabench.models.CostSmoothingSUEModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Horowitz (1984) exponential cost-smoothing day-to-day dynamics for logit SUE.

p_{n+1} = (1 - w) p_n + w t(L(p_n)): travelers logit-load at their perceived link costs p and smooth those toward the experienced costs.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.CumLogDTDModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Li, Wang & Nie (2024) cumulative-logit day-to-day dynamics for Wardrop UE.

s_t = s_{t-1} + eta_t c(p_{t-1}) with p = softmax(-r s) over column-generated working route sets: boundedly-rational logit choices whose global limit is the exact deterministic Wardrop UE (finite r).

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.DialSUEModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

MSA around Dial-STOCH loading: v_{k+1} = v_k + (L(t(v_k)) - v_k)/k.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.BoundedlyRationalUEModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Mahmassani & Chang (1987) BR-UE via band-thresholded gradient projection.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.CascettaStochasticProcessModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Cascetta (1989) finite-population stochastic-process day-to-day dynamics.

v_n ~ SampledDial(p_n, N); p_{n+1} = (1 - w) p_n + w t(v_n): daily flows never converge; the emitted burnt-in time average converges (ergodic theorem) to the stationary mean, which approximates the logit SUE.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.FrieszDTDModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Friesz et al. (1994) route-based projected-dynamical-system day-to-day model.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.LinkBasedDTDModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

He, Guo & Liu (2010) link-based day-to-day projected dynamical system.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.RouteSwapDTDModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Smith (1984) proportional route-swap day-to-day dynamical system.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.RouteSwapSUEModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Smith & Watling (2016) generalized-cost route-swap dynamics for logit SUE.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.UnifyingDTDModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Cantarella & Cascetta (1995) unified cost-learning + choice-inertia dynamics.

p <- (1 - w) p + w t(v); v <- v + alpha_n (ChoiceLoad(p) - v): the choice map is all-or-nothing (deterministic scenarios -> Wardrop UE) or the pinned Dial-STOCH logit load (SUE scenarios -> logit SUE), gated on scenario.sue_theta.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.ElasticDemandFWModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Frank-Wolfe on the Gartner excess-demand augmented network.

Emits real link flows only; the augmented (dummy) arcs are internal. The self-monitored relative_gap is the real-route relative gap — the same quantity the harness scores (adr-005) — so Budget.target_relative_gap stops at a quality comparable to a fixed-demand solver’s; the looser augmented-network gap is reported separately as augmented_relative_gap.

Like the other UE solvers this requires every positive-demand OD pair to be reachable in the real network; a disconnected instance (which the elastic formulation could in principle absorb as fully unmet demand) is out of scope for v1 and raises during the shortest-path step.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.EvansCombinedModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Evans (1976) partial-linearization Frank-Wolfe for the combined distribution + assignment problem.

Requires a scenario with combined_demand set (the fixed trip-end margins and gravity dispersion β). The self-monitored relative_gap is the combined route-equilibrium gap the harness scores (adr-007); the solver early-stops on max(route-gap, distribution-gap), both nonnegative, so Budget.target_relative_gap never trips on the transiently-negative combined gap a naive stop would.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.SueProbitMsaModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

MSA around Monte Carlo probit loading: v_{k+1} = v_k + (L_R(t(v_k)) - v_k)/k.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.FrankWolfeModel(**factor_overrides)[source]

Bases: _FrankWolfeFamily

Link-based Frank-Wolfe with exact line search.

Parameters:

factor_overrides (Any)

class tabench.models.GradientProjectionModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Path-based gradient projection (Jayakrishnan et al. 1994).

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.LearnedSurrogateModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Per-link learned regression surrogate (paradigm learned).

Predicts each link’s equilibrium volume/capacity ratio from its free-flow loading and BPR shape, fitted offline on synthetic solver equilibria, then emits predicted_v/c * capacity (clipped nonnegative) as its single checkpoint. Deterministic. The harness recomputes the equilibrium gap and demand-feasibility from these flows exactly as for any solver — a per-link predictor conserves flow only approximately, so it is typically censored or carries a large certified gap even when its link-flow RMSE is small (that contrast is the point). Refused on synthetic-net scenarios by the trained_on fairness gate.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.MSAModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Method of successive averages with 1/k step sizes.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.MulticlassModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Dafermos (1972) multiclass-user UE with a linear class interaction, by diagonalization.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.OriginBasedModel(**factor_overrides)[source]

Bases: _BushMachinery, TrafficAssignmentModel

Bar-Gera (2002) Origin-Based Assignment over per-origin bushes.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.SideConstrainedModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Larsson & Patriksson (1995) side-constrained UE via augmented Lagrangian.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.SystemOptimumModel(**factor_overrides)[source]

Bases: BiconjugateFrankWolfeModel

System-optimum solver: bi-conjugate FW on the marginal-cost network.

Emitted flows are for the ORIGINAL scenario (the transformation changes costs, not the network structure). Self-reports: beckmann is the true SO objective (original-network TSTT) and relative_gap is the self-monitored SO gap; Budget.target_relative_gap therefore applies to the SO gap.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.TapasModel(**factor_overrides)[source]

Bases: _BushMachinery, TrafficAssignmentModel

Bar-Gera (2010) TAPAS: global PAS pool + proportionality adjustments.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

class tabench.models.AsymmetricVIModel(**factor_overrides)[source]

Bases: TrafficAssignmentModel

Dafermos (1980) asymmetric-VI UE with non-separable costs, by diagonalization.

Parameters:

factor_overrides (Any)

solve(scenario, budget, rng, trace)[source]

Run the model, emitting checkpoints to trace.

Implementations must respect budget and record at least one checkpoint. Self-reported metrics go into checkpoint self_report entries; they are provenance, never scores.

Parameters:
Return type:

ResultBundle

tabench.models.marginal_network(network)[source]

The network whose UE is the original network’s system optimum.

Parameters:

network (Network)

Return type:

Network