Soft evolution

every point on the ring is a perfect answer — the question is how many of them a strategy keeps AI copy back to site
evaluations0
greedy0 / 12
soft culling0 / 12
resource sharing0 / 12
pools0 / 0 / 0

Population size over time

Score distribution & survival curve

What you are looking at

All three panels optimize the same function: 1 āˆ’ (x² + y² āˆ’ 1)². It scores a perfect 1 anywhere on the unit circle, so this problem has infinitely many right answers arranged in a ring. The dashed circle is that ring; the twelve wedges are the sectors used to measure how much of it each population holds.

All three find an answer within a second, and all three start as the same knot at the centre — the worst possible point, scoring zero. The interesting question is what happens over the next thirty thousand evaluations.

What one step does

  1. Ask. Pick a parent by Boltzmann selection over score, then mutate it 60% of the time, cross it with a second pick 30%, or replay it unchanged 10%. There are no random restarts: every genome here descends from the seed knot.
  2. Score. Evaluate the child and drop it straight into the pool. Nothing is rejected at birth.
  3. Cull, every step. Each member dies with probability (size/target)^cullPressure / target Ɨ (badness/meanBadness)^selectivity. Because badness is measured against the pool average, an average member dies at exactly 1/target — one expected death per birth, so the population holds at capacity.

death = (size / target) ^ cullPressure / target Ɨ (badness / meanBadness) ^ selectivity

The two strategies on the right differ only in what feeds badness. Soft culling blends fitness with novelty — distance to nearest neighbours, sampled by proximity weight so the measure fluctuates and rare lineages keep a chance. Resource sharing has no novelty term at all: it divides fitness by local crowding, so a clump splits one niche's resource more ways and stops growing.

Worth knowing

  • Pressure is the population, not a setting. Crowding pushes the exponent above one, which drives every probability down — hardest on the low scorers. A thinned pool pushes it below one and nearly everything survives. The right panel's population chart is that feedback loop stabilizing itself.
  • Novelty can be turned up too far. Push the weight well past 0.5 and coverage gets worse, because novelty alone keeps genuinely useless points — the ones far off the ring — alive at the expense of the ones on it.
  • Selectivity is the knob to play with. At 0 the cull is indiscriminate and the population drifts as a blob. At 1 death is proportional to badness. Push it past 2 and it hunts the weak: convergence gets faster and the ring empties out.
  • The novelty recompute is the expensive part — the only O(n²) step — so it is amortized across culls rather than run on every one. A new member's own novelty is measured once, against the pool it arrives into.
  • The greedy panel is not broken. It is a generational GA keeping the top half — a completely standard algorithm, doing exactly what it was asked to. It just was not asked to remember that the problem had more than one answer.

Measured

Over six seeds and 30,000 evaluations each, all three seeded as the same knot at the origin with no random restarts: greedy 3.3 of 12 sectors, soft culling 10.8, resource sharing 11.7. The greedy population crawls out to the ring once and stays on that arc.

This is a port of evors::strategies::SoftStochastic, the Rust crate the idea comes from: same ask split, same Boltzmann selection, same proximity-weighted kNN novelty, same cull-only-when-over-capacity rule.

Written up in more detail in Evolution that refuses to be greedy.