Optimise · Scheduling
Schedule optimiser (BZ)
The Bienstock–Zuckerberg-lineage scheduler solves the NPV-maximising schedule's LP relaxation to a provable upper bound, then repairs it into a real, mineable integer plan — and tells you how close to optimal it is.
See it
What it does
Provable bound + gap
Solves the precedence-constrained scheduling LP to an upper bound and reports the optimality gap on the integer schedule.
Real constraints
Per-period mining, ore and waste capacities (max and min), fleet truck-hour budgets, time-expanded precedence and fractional bench release.
Stockpiling inside the LP
Grade-bin stockpile flow is carried in the relaxation, with a post-pass that banks marginal ore back into value.
Fractional bench completion
A successor bench opens once its parent is, say, 80% mined — not only at 100%.
Integer repair stack
Precedence-frontier and LP-timing placement, local search, compaction and min-fill for lower bounds.
Live convergence
Streams LP-bound-versus-incumbent to the run page so you watch it converge.
How it works — the engineeringTechnical detail
Two LP paths: an exact full relaxation solved sparsely with HiGHS up to ~1M nodes; above that, Dantzig–Wolfe column generation over closures with Wentges dual smoothing and a Lagrangian bound. The optimality gap is reported on every run. Pure NumPy/SciPy/NetworkX — no commercial solver licence required.
- In
- mining units (value-by-period, tonnes, ore/waste, predecessors), period capacities, optional stockpile model.
- Out
- relaxed objective + bound, fractional and integer schedules, ore/waste/mining by period, stockpile flows, gap.
flowopt/services/bz_scheduler_clean.py