">
Dawkins' famous illustration that cumulative selection is nothing like blind chance. A population of random strings mutates and reproduces toward a target sentence. The twist this coursework asks: does crossover actually help, and how does a hill-climber compare to a genetic algorithm? Watch it converge, Race the three methods, then run the Lab experiments yourself.
The population is shown live; matched characters glow green. A fitness evaluation is one comparison of a candidate against the target: the true currency of evolutionary search, since it's the expensive bit in any real problem. Notice how few generations it takes once selection gets a grip.
All three search the same target from their own random start. The bar shows best fitness so far; the counter shows fitness evaluations spent. First to a perfect match wins. The weasel's characters are independent (each is its own little building block), so crossover gives a steady edge but nothing dramatic, while a population of hill-climbers burns evaluations. The decisive case for recombination is higher-order structure: hold that thought for the HIFF demo.
This reproduces the coursework experiment: fitness evaluations to solve (lower is better) versus population size, averaged over many runs, for each method. It's the browser version of the matplotlib figure from the original Python, but you can drag the sliders and watch the curves move.
Race them and crossover wins, but only by roughly half, not the landslide you might expect. The weasel target is separable: every character is its own tiny building block, so there's little structure for recombination to exploit.
In the Lab its curve rockets upward with population size. A population of hill-climbers re-tests every member each generation, so its fitness-evaluation bill balloons while the GAs stay lean.
Push the mutation slider far either way and convergence stalls. Too little and errors take forever to fix; too much and selection can't hold onto a correct character: the error catastrophe.