Selection and Mutation–Selection Balance

Natural selection is the deterministic counterpart to genetic drift: instead of allele frequencies wandering by chance, they are pushed in a direction by differences in survival and reproduction. This page shows how to turn genotype fitnesses into an allele-frequency recursion, when that recursion drives an allele to fixation versus maintains a polymorphism, and how recurrent mutation balances selection at a low equilibrium frequency.

Fitness and the selection recursion

Consider a single biallelic locus with alleles AA and aa at frequencies pp and q=1pq = 1 - p. Assign each genotype a relative fitness — its expected reproductive contribution — writing wAAw_{AA}, wAaw_{Aa}, waaw_{aa}. Starting from Hardy–Weinberg genotype frequencies p2,2pq,q2p^2, 2pq, q^2 before selection, the mean fitness of the population is the weighted average wˉ=p2wAA+2pqwAa+q2waa.\bar w = p^2 w_{AA} + 2pq\, w_{Aa} + q^2 w_{aa}. Selection reweights each genotype by its fitness, and the frequency of AA in the next generation is the frequency of AA-carrying gametes after this reweighting: p=p2wAA+pqwAawˉ.p' = \frac{p^2 w_{AA} + pq\, w_{Aa}}{\bar w}. The change in one generation is Δp=pp=pq[p(wAAwAa)+q(wAawaa)]wˉ.\Delta p = p' - p = \frac{pq\,\bigl[\,p(w_{AA}-w_{Aa}) + q(w_{Aa}-w_{aa})\,\bigr]}{\bar w}. The sign of Δp\Delta p depends only on the bracketed term, and the factor pqpq vanishes at the boundaries p=0p=0 and p=1p=1, which are always fixed points.

Directional selection

Suppose one homozygote is fittest and the heterozygote is intermediate, for example wAA=1w_{AA} = 1, wAa=1hsw_{Aa} = 1 - hs, waa=1sw_{aa} = 1 - s with selection coefficient s>0s > 0 and dominance coefficient 0h10 \le h \le 1. Then AA is favoured, Δp>0\Delta p > 0 for all 0<p<10 < p < 1, and the allele marches monotonically toward fixation at p=1p = 1. A recessive deleterious allele (h=0h = 0) is removed slowly once rare, because selection acts only on the vanishingly few aaaa homozygotes.

Overdominance and stable polymorphism

When the heterozygote is fittest — heterozygote advantage, or overdominance — selection maintains both alleles. Write wAA=1s1w_{AA} = 1 - s_1, wAa=1w_{Aa} = 1, waa=1s2w_{aa} = 1 - s_2 with s1,s2>0s_1, s_2 > 0. Setting Δp=0\Delta p = 0 with 0<p<10 < p < 1 requires the bracket to vanish, giving the interior equilibrium p^=s2s1+s2,q^=s1s1+s2.\hat p = \frac{s_2}{s_1 + s_2}, \qquad \hat q = \frac{s_1}{s_1 + s_2}. This equilibrium is stable: if pp drifts above p^\hat p the fitter allele becomes the rarer one and selection pushes it back. The textbook case is the sickle-cell allele, where the heterozygote resists malaria while both homozygotes suffer. Frequency-dependent versions of this balancing dynamic are studied in evolutionary game theory.

Mutation–selection balance

A deleterious allele is never fully eliminated because mutation keeps regenerating it. Let mutation from AA to aa occur at rate μ\mu per generation while selection removes aa. The equilibrium frequency of aa is where mutational input equals selective removal.

For a fully recessive deleterious allele (h=0h = 0, fitness 1s1 - s for aaaa), removal near equilibrium is sq^2\approx s\hat q^2 and input is μ\approx \mu, so μsq^2q^μ/s.\mu \approx s\,\hat q^{\,2} \quad\Longrightarrow\quad \hat q \approx \sqrt{\mu/s}. For a dominant (or additive) deleterious allele, selection acts on the common heterozygotes, removal is sq^\approx s\hat q, and q^μ/s.\hat q \approx \mu/s. The recessive case sits at a much higher frequency for the same μ\mu and ss, because deleterious recessives are shielded from selection inside heterozygotes.

Worked example

One generation of directional selection

Take wAA=1.0w_{AA} = 1.0, wAa=0.9w_{Aa} = 0.9, waa=0.8w_{aa} = 0.8 and a starting frequency p=0.3p = 0.3, so q=0.7q = 0.7. The mean fitness is wˉ=0.32(1.0)+2(0.3)(0.7)(0.9)+0.72(0.8)=0.09+0.378+0.392=0.86.\bar w = 0.3^2(1.0) + 2(0.3)(0.7)(0.9) + 0.7^2(0.8) = 0.09 + 0.378 + 0.392 = 0.86. The updated frequency is p=0.32(1.0)+(0.3)(0.7)(0.9)0.86=0.09+0.1890.86=0.2790.860.3244.p' = \frac{0.3^2(1.0) + (0.3)(0.7)(0.9)}{0.86} = \frac{0.09 + 0.189}{0.86} = \frac{0.279}{0.86} \approx 0.3244. So Δp+0.0244\Delta p \approx +0.0244: the favoured allele AA increases, and iterating this map carries it to fixation.

A mutation–selection balance

Let a recessive lethal-ish allele have s=0.1s = 0.1 with mutation rate μ=105\mu = 10^{-5}. Then q^μ/s=105/0.1=104=0.01.\hat q \approx \sqrt{\mu/s} = \sqrt{10^{-5}/0.1} = \sqrt{10^{-4}} = 0.01. If instead the allele were dominant with the same ss and μ\mu, its equilibrium would be q^μ/s=104\hat q \approx \mu/s = 10^{-4} — a hundredfold lower.

Simulation

Iterate the selection recursion from a starting frequency and watch it approach fixation (directional) or an interior equilibrium (overdominance).

R

selection_step <- function(p, wAA, wAa, waa) {
  q <- 1 - p
  wbar <- p^2 * wAA + 2 * p * q * wAa + q^2 * waa
  (p^2 * wAA + p * q * wAa) / wbar
}

iterate <- function(p0, wAA, wAa, waa, gens = 200) {
  p <- p0
  for (i in seq_len(gens)) p <- selection_step(p, wAA, wAa, waa)
  p
}

# Directional: A fixes
iterate(0.3, 1.0, 0.9, 0.8)          # ~ 1.0 (fixation of A)

# Overdominance: stable polymorphism, phat = s2/(s1+s2)
s1 <- 0.2; s2 <- 0.3
iterate(0.05, 1 - s1, 1, 1 - s2)     # ~ 0.6 = 0.3/0.5

Python

import numpy as np

def selection_step(p, wAA, wAa, waa):
    q = 1 - p
    wbar = p**2 * wAA + 2 * p * q * wAa + q**2 * waa
    return (p**2 * wAA + p * q * wAa) / wbar

def iterate(p0, wAA, wAa, waa, gens=200):
    p = p0
    for _ in range(gens):
        p = selection_step(p, wAA, wAa, waa)
    return p

# Directional: A fixes
print(iterate(0.3, 1.0, 0.9, 0.8))       # ~ 1.0

# Overdominance: stable polymorphism at s2/(s1+s2)
s1, s2 = 0.2, 0.3
print(iterate(0.05, 1 - s1, 1, 1 - s2))  # ~ 0.6
0.9999999985559945
0.5999999999998405

Julia

function selection_step(p, wAA, wAa, waa)
    q = 1 - p
    wbar = p^2*wAA + 2p*q*wAa + q^2*waa
    (p^2*wAA + p*q*wAa) / wbar
end

function iterate_sel(p0, wAA, wAa, waa; gens=200)
    p = p0
    for _ in 1:gens
        p = selection_step(p, wAA, wAa, waa)
    end
    p
end

iterate_sel(0.3, 1.0, 0.9, 0.8)            # ~ 1.0 (fixation)

s1, s2 = 0.2, 0.3
iterate_sel(0.05, 1 - s1, 1, 1 - s2)       # ~ 0.6

Why it matters

Selection is the engine of adaptation, and this simple recursion is the workhorse that turns genotype fitnesses into predictions about how populations change. It explains why some alleles sweep to fixation while others persist as protected polymorphisms, and mutation–selection balance sets the baseline burden of deleterious variation that every population carries — the quantity behind genetic load, the maintenance of disease alleles, and the evolution of dominance.