Development documentation — 0.3.0a4 / main

This is the development branch, not a published stable release. Use the source installation guide. Functional checks cover Ubuntu, Windows and macOS; interpreter, artifact and optional-feature limits still apply. Read support, release gates and known limitations before relying on results.

C++ reference and compatibility

Behavioral reference: RKO_Cpp_v2.0, revision 126e35873e50dc308795b58b8c75d37f8de4c857. Compare executable behavior, not only comments or algorithm names. Full solver equivalence is not proven.

Checked neighborhood contracts

The reference Program/src/Method.h calls strategy 1 "first improvement", but its immediate return statements are commented out. SwapLS, InvertLS and FareyLS therefore continue the sweep after accepting an improvement. All three shuffle RKorder unconditionally. Python already followed that transition policy; changing it to immediate return would diverge from this reference.

Setting Reference behavior preserved in Python
strategy 1 Sequential acceptance: next candidate starts from the best accepted vector; finish the sweep
strategy 2 Evaluate all neighbors from the fixed input; return the best improvement
supplied order Base indices are reshuffled, not treated as a fixed exploration schedule

Six deterministic cases (three operators, both strategies) were verified by compiling the unmodified C++ function bodies with minimal solution/data types, a linear decoder and controlled exploration order/Farey midpoint draws. The same outputs and full candidate counts are regression-tested in tests/components/test_cpp_operator_contracts.py. This was a kernel comparison, not a build/test of the complete C++ application or random generator. The normalized reference Method.h SHA256 is 0f202c543c424a77db3f44220986ee956b3b17c0900a2454fcb122f25339262d.

Python returns new vectors and copies the supplied index list instead of mutating caller-owned input as C++ does. Random streams and repeated-call index state are not identical; these tests compare matched deterministic transitions. The portfolio currently uses strategy 2 defaults; a run-level strategy setting is not yet exposed. Operator docstrings describe actual sweep semantics.

Deliberate corrections, not unchanged trajectories

Python now keeps selected GA fitness with its chromosome, recomputes current Q maxima after updates, handles negative/extreme rewards consistently, filters infeasible joint parameter states, covers partial IPR blocks and retains superior initial simplex vertices. Some issues were inherited from the reference. These are explicit correctness choices; do not silently revert them just to match a historical defect or claim byte-for-byte C++ search trajectories.

IPR initialization contract

The C++ driver calls CreatePoolSolutions before invoking its selected searches; standalone IPR therefore starts with an elite population. Python previously started with an empty pool and could spend its entire allocation waiting, returning only its first random candidate. This is an initialization difference, not evidence that compiling the same waiting loop would improve search quality.

Python IPR now inserts its initial evaluated candidate and tries at most one extra seed if fewer than two elites exist at startup. Both evaluations use ordinary callbacks, assigned RNGs and the existing search deadline. Prefilled pools retain their initialization draw order. Initialization is bounded even when a custom pool or capacity-one pool cannot retain a pair; existing backoff then applies.

This restores usable standalone relinking, not full-driver parity: C++ seeds its configured pool population, whereas Python only bootstraps the missing pair locally in IPR. A fixed-work diagnosis exposed clone collapse and redundant block evaluations. Stock Python pools now enforce chromosome uniqueness, retaining different tied-cost vectors; IPR skips identical effective parents. C++ update rejects objective duplicates, which is a different policy. Python's unchanged-block pruning reuses known current costs for representation-identical moves while retaining virtual path/tie decisions. This intentionally changes callback counts, not an assertion of matching C++ evaluation schedules or stochastic trajectories. Global initialization, random engines, block-path transitions and throughput still require separate matched comparisons. Random seeds are not generic feasibility repairs; no C++-matching quality claim follows from this correction.

SA adaptive and GRASP construction audit

SA now implements online actions rather than silently falling back to fixed settings. The SA control contract describes actual parameter application and migration to control=0 for the legacy path. Python uses the sampled initial Q state, credits completed levels including refinement with the shared sign-safe reward, and applies selected t0 to the next schedule. C++ leaves its initial Q source at zero and never applies later t0 selections. These are explicit corrections, not claims of identical trajectories or scientific quality. Python's legacy refinement/current-incumbent transition is retained; full SA transition parity remains unproven.

GRASP's line-candidate correction now restores the nominal reference lattice, sample quota and optional incumbent inclusion. Exact-ratio bounds and sparse sampling define safe behavior beyond the reference's float/int limits. Construction iteration/subset counts now also match the nominal reference rules. Other audited construction/refinement policies remain separate:

Contract Pinned C++ Current Python
Line candidate universe Bounded lattice around the gene, then randomized subset Same nominal lattice with exact-ratio bounds; no dense allocation
Candidate evaluation count At most ceil(log2(int(1/h)))+1 sampled lattice values Matching nominal quota, safely extended to tiny/large steps
Incumbent in subset May be omitted; construction can worsen May be omitted; global solver best remains protected
Small unfixed sets Search every remaining coordinate when the 10% subset is below two Same fallback, recomputed after each commit
Construction intensity Integer loop against a real bound (effectively ceiling) ceil(n*intensity), including one construction step for n=1
Shuffle ordering Shuffle a copy of unfixed coordinates Shuffle a copy; unfixed order survives every pass (aligned)
Improving fine-grid step Keep the current h Keep the current h; previous reset to hs removed
Initial refinement Score the initial vector before construction Score the initial vector, then insert it; no initial RVND
Alpha parameter Read/selected but unused by construction Retained adaptive state axis; no direct construction effect (policy)

The former near-only Python grid could miss available candidates while making more callback evaluations. Bounded dyadic oracle cases now cover the wider universe, ordered samples and callback budget; this is not a full compiled-C++ quality test or bitstream/rounding equivalence. The unfixed-order shuffle now also matches the reference copy semantics. Alpha is deliberately retained for reference state-graph compatibility, not interpreted as an RCL. Its indirect adaptive effects and the remaining offline RNG-draw difference are documented in the alpha policy. The ongoing paired benchmark remains unchanged; full validation is hosted to avoid local contention.

Full-driver initialization

The startup contract audit separates shared-pool seeding from private algorithm populations. C++ fills its shared pool before launching searches and makes one cost-tie perturbation pass; Python starts empty by default and treats pool_size as capacity. An explicit prefill_pool=True now enables the reference-style fill/tie pass with isolated callbacks, separate startup reports and fresh search allowances. Coordinate-unique admission and RNG engines remain different. Equal nominal capacities/durations still do not imply exact startup work, diversity or trajectory parity.

BRKGA-CS undefined correlation

Community construction now excludes constant chromosomes and chromosomes with fewer than two observations. Pearson correlation is undefined in those cases; there is no community edge, including when floating-point rounding previously fabricated a finite coefficient for a constant array. Nonconstant pairs whose normalization fails numerically (for example, covariance underflow) also add no edge. No epsilon cutoff is used: finite small-variance correlations remain valid.

Python still calls NumPy for defined coefficients. A fresh local np.errstate turns invalid/divide faults into handled FloatingPointError, not ignored warnings; the caller's floating error policy is restored. Label propagation, representative selection and their RNG draws are unchanged for the same graph. Direct regressions cover the real warning, one-gene inputs, constants, small variance, error-policy restoration and a hand-worked two-component graph. Defined graph/RNG results were also checked against the unmodified prior Python source. The diagnostic replay contract is brkga-cs-defined-correlation-v1, not a new user option.

This deliberately removes spurious constant-array edges and can change those search trajectories; it is not an exact replay or quality-improvement promise. The pinned C++ Program/src/MH/BRKGA_CS.h::PearsonCorrelation has an unchecked raw-moment denominator. Source inspection shows an ordinary zero-denominator NaN fails its graph threshold, but no compiled whole-solver equivalence follows. Python retains its existing absolute correlation and inclusive >= sigma rule; the reference uses signed pearson > sigma. This pre-existing difference is not silently changed by the numerical-warning fix. Full BRKGA-CS parity and current multi-instance quality remain unproven.

See NumPy's coefficient/rounding contract and scoped floating error handling.

Still to resolve

  • GRASP offline unused-alpha RNG draw differs; exact random-engine/trajectory parity is not claimed.
  • Full SA/GRASP transition and refinement comparisons beyond adaptive plumbing.
  • Full per-algorithm initialization, transition, restart and stopping contracts.
  • Full-driver population initialization and comparable timing/work accounting; owned search RNGs and CPU-bounded remaining-time process scheduling are implemented.
  • Mapping additional C++ run settings into actual Python functionality rather than accepting unsupported fields. Current terminal/configuration usage is in running.md.
  • Matched-work, multi-instance measurements with strong optimization baselines.

These remain release limitations. No competitive-quality or whole-solver parity claim follows from six neighborhood examples.