Engine flow¶
Every sezgi run — whether it uses a built-in preset, a Python Algorithm
subclass, or a hand-written spec — executes through the same Rust loop:
Engine::run (crates/core/src/engine.rs). This page walks that loop
exactly as written, not as an idealized textbook version of it.
The run, start to finish¶
Engine::run (engine.rs:83-248):
- Builds an
Evaluatorwrapping the problem and the run'sbudget, and a freshBlackboard(component-shared state). - Derives per-role RNG streams from
(master_seed, run_id)— one for initialization, one for boundary repair, one generator/replacer pair per stage, one per adapter, one for restarts (see Determinism and the RNG model for the exact derivation). - Runs the configured
Initializeronce to build the starting population, then evaluates it (chargingpop_sizeevaluations against the budget). - Enters the outer loop, which repeats until a
targetfitness is reached or the budget is exhausted: - For each configured stage (most presets have one;
tlbois the only preset with two —gen/tlbo-teacherthengen/tlbo-learner,presets.rs:600-620.abchas one stage with anAdapterattached — its extra per-cycle evaluation cost comes from that adapter's own internal evaluations, not from a second engine stage,presets.rs:695-708):Generator::generate(pop, ctx)produces offspring.- Boundary repair (
boundary/clampin every documented preset) repairs each offspring against the search space. Evaluator::evaluate(offspring)charges the budget; a budget shortfall here ends the run cleanly (break 'outer), keeping whateverbest_f/best_xhad already been observed.Replacer::replace(pop, offspring, fitness, ctx)decides the next population.- The stage's optional
Adapter::adapt(pop, ctx)runs, if configured (e.g. SHADE's success-history update, CMA-ES's covariance update). - If
targetis now reached, the run stops immediately — even mid-stage, before any later stage in the same generation runs.
- After all stages, an optional
Restartcomponent may re-initialize the population (preserving only the restart component's own declared blackboard state across the reset) — used by, e.g., CMA-ES-IPOP's stagnation restarts. - Returns a
RunResult { best_f, best_x, evals_used, iterations }.best_f/best_xare read directly from theEvaluator's own best-tracking — the minimum over every charged evaluation of the run, including ones anAdapterorGeneratorissued internally via its ownctx.eval.evaluate(..)call, not only the ones this loop's own per-stageeval.evaluate(&offspring)call re-observes.
Two details worth being explicit about, because they are easy to get
wrong in a simplified diagram: the budget check happens inside
eval.evaluate(...), not as a separate "is there budget left?" test before
each stage — a stage that cannot afford its own offspring batch ends the
run there, mid-generation; and a target hit is checked once per stage,
immediately after that stage's own adapter call, so it can short-circuit
before any later stage in the same generation ever runs.
The loop, as a diagram¶
flowchart TD
START(["Engine::run(problem, cfg)"]) --> DERIVE["Derive per-role RngStreams\nfrom (master_seed, run_id)"]
DERIVE --> INIT["Initializer.initialize(pop_size, ctx)"]
INIT --> EVALINIT["Evaluator.evaluate(individuals)\n(charges pop_size evals)"]
EVALINIT --> LOOP{"target reached\nOR budget exhausted?"}
LOOP -->|no| STAGES
subgraph STAGES["For each configured stage (1 for most presets, incl. abc's single\nstage+adapter; 2 only for tlbo: teacher then learner)"]
direction TB
GEN["Generator.generate(pop, ctx)\n-- e.g. gen/de-shade, gen/pso, gen/step,\n or a Python Algorithm.generate() callback"]
GEN --> REPAIR["BoundaryHandler.repair\n(boundary/clamp)"]
REPAIR --> EVALSTAGE["Evaluator.evaluate(offspring)\n(charges the budget;\nshortfall ends the run cleanly)"]
EVALSTAGE --> REPL["Replacer.replace(pop, offspring, fitness, ctx)"]
REPL --> ADAPT["Adapter.adapt(pop, ctx)\n(optional, per stage)"]
ADAPT --> TCHECK{"target reached\nnow?"}
TCHECK -->|yes| DONE
end
STAGES --> RESTART{"Restart configured\nand its check(pop, ctx)\nfires?"}
RESTART -->|yes| REINIT["Re-initialize population\n(blackboard cleared, restart\ncomponent's own state preserved)"]
REINIT --> LOOP
RESTART -->|no| LOOP
LOOP -->|yes| DONE(["RunResult{best_f, best_x,\nevals_used, iterations}"])
Next¶
- Class hierarchy covers what sits above this loop, on the Python side.