Production

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