EvolutionAdvanced~18 min

Population Genetics Simulator

Evolution as arithmetic you can run

Break Hardy–Weinberg one assumption at a time, add selection, drift, mutation, migration, and run replicate populations to watch identical starting conditions diverge.

The takeaway

Run twenty identical populations and they end up in different places. Drift is not a correction to evolution, in a small population, it is the dominant force.

Hardy–WeinbergSelection coefficientsGenetic driftHeterozygote advantageFounder effectFixation and loss
Read the theory: Cancer as Clonal Evolution
Scenarios

Break assumption 4 only: the population is finite (N = 50). No selection, no mutation, no migration.

What to watch: Identical starting conditions, wildly different outcomes. With no selection at all, allele frequencies still wander, and every replicate eventually hits 0 or 1. Drift is not weak evolution; given time, it is total.

generation 150 / 150
Baseline
0.50
150
12
Genetic drift (assumption 4)
50

Each generation draws 100 gametes from Binomial(2N, p). Sampling error scales as 1/√(2N) — halve N and drift gets noticeably stronger.

Natural selection (assumption 1)
1.00
1.00
1.00
Mutation (assumption 2)
0.000
0.000
Migration (assumption 3)
0.000
0.00
Non-random mating (assumption 5)
0.00

F redistributes genotypes without changing p: homozygotes gain Fpq, heterozygotes lose 2Fpq. Inbreeding alone does not evolve the population — it exposes recessives to selection.

Mean p across reps
0.313
Mean fitness w̄ (rep 1)
1.000
Heterozygosity 2pq
0.092
expected under drift: 0.111
Fixed / Lost / Poly
2 / 7 / 3
of 12 replicates

Hardy–Weinberg baseline

rep 1 · p = 1.000 · q = 0.000
AAp²
HW: 1.000obs: 1.000
Aa2pq
HW: 0.000obs: 0.000
aaq²
HW: 0.000obs: 0.000

1 assumption broken: finite population (drift). Hardy–Weinberg no longer holds — p is free to move, and (with F > 0) the genotype frequencies themselves depart from p², 2pq, q².

Allele frequency p over generations

12 independent replicates, identical parameters

Same starting p, same forces, different random draws. The spread between these lines is genetic drift.

p = 1: fixation (2) p = 0: loss (7)still polymorphic: 3

Genotype frequencies (replicate 1)

AA, Aa and aa, recomputed from p each generation. Heterozygosity (Aa) peaks at p = 0.5 and is the first casualty of drift and inbreeding.

The five assumptions

  • 1No selection — all genotypes survive and reproduce equally
  • 2No mutation — alleles do not change into one another
  • 3No migration — the gene pool is closed
  • 4Infinite population — no sampling error, the only assumption that is never literally true
  • 5Random mating — genotypes pair at random (F = 0)

Real populations violate all five. That is not a flaw in the model — the model exists so that the size of the deviation becomes a measurement of the evolutionary force responsible.

The recursions being run

Selection
p' = (p²·wAA + pq·wAa) / w̄
w̄ = p²·wAA + 2pq·wAa + q²·waa
Mutation & migration
p' = p(1 − µ) + (1 − p)ν
p' = (1 − m)p + m·pmig
Drift
p' = Binomial(2N, p) / 2N
Inbreeding
fAA = p² + Fpq   fAa = 2pq(1 − F)

Applied in that order each generation. The binomial draw is a real pseudo-random sample, seeded so a given run is reproducible — hit Reseed for a fresh universe with the same physics.

Graph of Hardy-Weinberg genotype frequencies as a function of allele frequency

Hardy–Weinberg equilibrium: with no selection, drift, or migration, genotype frequencies follow p² + 2pq + q² forever.

Image: Johnuniq, Wikimedia Commons (CC BY-SA 3.0)