Features 31-40¶
Items in this decade from the roadmap overview. Status and surfaces live on that table. Empty slots stay empty until an item is numbered into this range.
31. Affine scaling and Lamarckian writeback¶
What. Keijzer linear scaling next to tune_ephemerals.
Given aligned predicted and target (and the same valid=
mask case_errors already uses), fit \(a + b\,f(x)\) in the
least-squares sense.
- Darwinian: use the scaled series only to write fitness / case errors. The tree is unchanged.
- Lamarckian: write \(a\) and \(b\) back as ephemerals or as a wrapping Slim delta, then invalidate fitness and the compile cache for that expression.
Today. affine_scale(predicted, target, *, valid=) fits
Keijzer \(a + b\,f(x)\) in the least-squares sense on the same
valid= mask case_errors uses. Darwinian callers apply
\(a + b\,f(x)\) only when writing fitness or case errors; the
tree is unchanged. write_affine_scale(ind, a, b, prim_set)
writes \(a\) and \(b\) back as ephemeral leaves wrapping a
PrimitiveTree, or as wrapping Slim deltas
(\(a + b\cdot\mathrm{head}\), and \(b\) on each existing delta),
then invalidates fitness and the compile-cache entries for the
old expression. No Autograd. No domain fitness.
tune_ephemerals is unchanged.
Benefit. Structure plus \(a + b\,f(x)\) is the usual difference between a shape that still fights intercept and slope and a law the numeric engine can finish. Both halves already exist; they do not meet.
Scope. One scaling helper and an optional writeback onto leaves / Slim deltas. No Autograd. No domain fitness.
Related: item 6, item 24, Push GP P17.
32. Population tape CSE¶
What. Hash-cons postfix suffixes across a generation, evaluate
each unique sub-tape once against the packed matrix, and stitch
the results. Same Python oracle, same nan warmup, same
interpret_tapes return shape \((n_{\mathrm{ind}}, n_{\mathrm{rows}})\).
Today. interpret_tapes hash-conses postfix subexpressions
across a batch, evaluates each unique sub-tape once against the
packed matrix, and stitches the results. The Python oracle,
warmup nan contract, and (n_ind, n_rows) return shape are
unchanged. Incremental ts_rank stays deferred.
Benefit. The next columnar speedup after items 3, 4, and 9 that does not need a C rewrite. A generation of related trees shares most of its suffixes. Same programs, less work.
Scope. Common-subexpression elimination inside the batch
interpreter. Incremental ts_rank stays a kernel tweak in
Under consideration. No new language.
33. Evaluation budget and eval cache¶
What. Two plumbing pieces on the shared algorithm loop:
n_evals=(or an equivalent stop) onea_simple,ea_mu_plus_lambda,ea_mu_comma_lambda, andea_map_elites.ea_generate_update_restartsalready stops on evaluations. Generations remain the default.EvalCache— wrapevaluate/evaluate_batchwith a key of expression text (or a caller key) plus matrix identity / row count.promote_subtreeandtune_ephemeralsalready invalidate compile-cache entries; the fitness cache must drop those keys too.
Today. n_evals= is an optional stop on ea_simple,
ea_mu_plus_lambda, ea_mu_comma_lambda, and ea_map_elites.
The generation that meets or exceeds the budget is finished,
then the loop returns. Generations remain the default.
ea_generate_update_restarts already stops on evaluations.
EvalCache wraps evaluate / evaluate_batch with a key of
expression text (or a caller key) plus matrix identity and
row count. A hit does not call the wrapped callable;
n_evals / nevals still count the fitness assignment.
clear_compile_cache clears every live EvalCache;
invalidate_compiled drops matching expression keys. That is
the same path promote_subtree and tune_ephemerals already
use for the compile LRU.
Benefit. GP papers report evaluation budgets. A cache is the
other half of the compile LRU: the same tree on the same matrix
should not pay evaluate twice.
Scope. A stop condition and a cache with explicit invalidation. Not adaptive operator rates, not racing, not a new algorithm.
Related: item 9, item 13, item 24, Push GP P15.
34. Parallel RNG streams¶
What. Independent, seedable streams for spawned workers that
still reproduce a run. Process-wide rng stays the default and
stays checkpointable. A worker map (or a documented
spawn_rng(seed, worker_id) helper) draws from a stream that
does not collide with the parent and does not depend on
scheduling order.
Today. Process-wide tools.rng is still the default NumPy
Generator, and Checkpoint still persists it.
spawn_rng(seed, worker_id) derives an independent child
stream from the run seed and a stable task id without
advancing the parent. map_spawned binds that stream for
each item and returns results in input order, so a pool's
completion order cannot change the run.
Benefit. The last reproducibility hole that is still open on
DEAP (user-provided streams for parallel runs). Golden
tests and papers that use evaluate_batch in a pool need a
stream contract, not “hope the OS schedules the same way.”
Scope. Stream derivation and a worker entry point. Not a second RNG library. Not switching the parent stream off NumPy.
Related: item 4, Multiprocessing, Push GP P18.
35. Island topologies¶
What. mig_fully_connected / mig_random next to
mig_ring, plus a helper that computes eval_keys from the
current exam.
Today. mig_fully_connected visits every directed deme pair;
mig_random picks one destination per source. Both reuse
mig_ring placement rules. island_eval_keys hashes each
deme's CaseExam and optional matrix identity for
step_islands(..., eval_keys=). Custom graphs stay
mig_ring(..., mig_indices=). Archives still do not
auto-merge.
Benefit. Heterogeneous islands shipped in item 25; the
missing half is more than a ring. A named topology plus an
exam-derived key stops every island recipe from reinventing
mig_indices and a hash of the case set.
Scope. Two migrate callables and an eval_keys helper.
Archives still do not auto-merge. Custom graphs stay
mig_ring(..., mig_indices=).
Related: item 25, Operators, Multiprocessing.
36. Persistent hall of fame¶
What. A first-class hof slot on Checkpoint, or
HallOfFame.to_json matching Logbook
(persistency of the hall of fame).
Today. HallOfFame.to_json / from_json round-trip
maxsize and members as genes plus fitness values.
Checkpoint(..., hof_ind_cls=) stores hof as JSON instead
of dill and rebuilds it on load. Logbook already round-trips
JSON the same way.
Benefit. A resumed run should restore the archive without relying on dill for the one object papers want to inspect. Matches the logbook JSON path and the still-open DEAP request.
Scope. A convenience API, not a new record type. Not a
per-generation snapshot mode beyond what fronts= already
logs.
Related: Using checkpoints, Logging statistics.
37. Interval analysis on tapes¶
What. Given column bounds (or empirical min/max), propagate
intervals through the opcode kit. Flag programs that are
identically nan, constant, or that use vwhere to hide
warmup — before a full interpret_tapes / evaluate pass.
Today. bounds_from_matrix derives per-column bounds from a
packed matrix. tape_interval and tape_flags walk the builtin
opcode kit and certificate identically-nan, constant, or
warmup-hiding vwhere programs before interpret_tapes.
evaluate_columnar(..., static_filter=True) skips those tapes
and writes the existing empty sentinel instead. The runtime
warmup nan contract is unchanged; tape_lookback and
suffix_rescore stay the oracle path for legal suffixes.
Benefit. Columnar populations waste evaluations on programs
that cannot be a law. A cheap certificate lets
evaluate_invalid and evaluate_columnar skip them, or write
a sentinel the caller already uses for empty overlap.
Scope. Interval propagation over the builtin opcode kit and
a flag / helper next to tape_lookback. Not a domain fitness.
Not a substitute for the runtime nan contract.
Related: item 30, item 32, Columnar programs.
38. Structural meta-case regularization¶
What. Extra cheap cases — size, depth, unique opcodes, promote-library hits, time-in-output / non-finite fraction — appended to the case matrix so lexicase regularizes bloat and “always on” programs without a second fitness weight.
Today. structural_meta_case_columns returns size, depth,
unique opcodes, promote-library hits, and non-finite fraction for
a packed population. structural_meta_case_weights supplies
default lexicase signs. Append with numpy.hstack to
fitness_case_matrix, pass trust_matrix=True, and extend
fit_weights when the matrix is wider than fitness.values.
The caller still owns evaluate and may omit columns via
columns=.
Benefit. Machine-checkable pressure on the same path as
case exams. A constant or giant tree fails an extra case
instead of requiring a magic penalty in evaluate.
Scope. A helper that returns extra columns for a packed
population. The caller still owns evaluate and may omit
any column. Not human-in-the-loop. Not a second objective
on Fitness.weights unless the caller concatenates them
there.
Related: item 5, item 27, item 28, item 41.
39. Homologous and semantic crossover¶
What. Align similar subtrees (homologous) or prefer nodes
whose interpret_tape vectors are close (semantic_nearest
on subtrees). Type-matched one-point stays the default.
Today. gp.cx_homologous swaps subtrees at the same
root-to-node path when return types match, otherwise falling
back to type-matched one-point. gp.cx_one_point_semantic
picks the type-matched partner whose interpret_tape row is
nearest to the anchor subtree via semantic_nearest on
batched interpret_tapes rows. gp.cx_one_point remains
the default mate. SlimGP still moves in output space through
cx_semantic / cx_slim_donor.
Benefit. Long, expensive tapes survive variation more often. Random typed swaps on unrelated subtrees are the usual way a good law dies in one generation.
Scope. Optional crossover(s) next to cx_one_point.
Default stays type-matched one-point. Not a second genome.
Related: item 7, item 22, item 31, item 32.
40. Noisy fitness resample¶
What. resample(ind, evaluate, n) and a racing stop
(F-Race-shaped) for noisy cases. Repeats go through
EvalCache when the key is unchanged; a noisy evaluate
must use a key that includes the draw.
Today. resample(ind, evaluate, n) averages n independent
draws and optionally writes fitness.values. Repeats route
through EvalCache when cache= is set; noisy_draw_key
pairs a caller key with the draw index so identical draws hit
the cache. race_stop adds one resample per survivor per
round and drops challengers whose first objective is
significantly worse than the leader (F-Race-shaped elimination).
race_eval_charge counts evaluate units for n_evals=
budgeting. evaluate stays on the caller.
Benefit. Time-series and case-structured search treat a single history pass as an estimate. Racing spends the budget on individuals whose rank is still unstable.
Scope. A resample helper and an optional race stop.
evaluate stays on the caller. Not a domain metric. Not a
new algorithm loop.