The replicator equation in R

evolutionary ecology
evolutionary game theory
population dynamics
R
ecology tutorial
Simulate evolutionary game dynamics in R with the replicator equation: convergence to an ESS, and the rock-paper-scissors cycles that never settle.
Author

Tidy Ecology

Published

2026-08-05

An evolutionarily stable strategy tells you where a population can rest, but not whether it ever arrives there, nor what it does if no such rest exists. For that you need dynamics. The replicator equation is the workhorse: it grows each strategy in proportion to how much its payoff exceeds the population mean, and it turns a payoff matrix into a trajectory. This post codes it in base R, confirms it converges on an ESS, and then shows the case that has no ESS at all: rock-paper-scissors.

The equation

For strategy frequencies x and a payoff matrix A, the payoff to strategy i is (A x)_i, the mean payoff is x' A x, and each frequency changes as

\[ \dot{x}_i = x_i\left[(\mathbf{A}\mathbf{x})_i - \mathbf{x}^\top\mathbf{A}\mathbf{x}\right]. \]

A strategy above the average grows, one below it shrinks, and the frequencies always sum to one. Here it is as a plain Euler integrator.

replicator <- function(A, x0, dt = 0.005, tmax = 200) {
  x <- x0; out <- matrix(0, tmax / dt, length(x0))
  for (i in seq_len(nrow(out))) {
    fit <- as.numeric(A %*% x)
    x <- x + dt * x * (fit - sum(x * fit))
    x <- x / sum(x)                      # guard against numerical drift off the simplex
    out[i, ] <- x
  }
  out
}

Rock, paper, scissors: no ESS

The lizard Uta stansburiana runs a real rock-paper-scissors among three male types, where each beats one and loses to another (Sinervo and Lively 1996). Encode the cycle as a zero-sum payoff matrix: winning pays +1, losing -1.

A <- matrix(c( 0, -1,  1,
               1,  0, -1,
              -1,  1,  0), 3, byrow = TRUE)
out <- replicator(A, c(0.5, 0.3, 0.2))
cat(sprintf("time-averaged frequencies: %.3f %.3f %.3f (interior point is 1/3 each)\n",
            mean(out[, 1]), mean(out[, 2]), mean(out[, 3])))
time-averaged frequencies: 0.333 0.336 0.331 (interior point is 1/3 each)
cat(sprintf("strategy 1 ranges over %.3f to %.3f: it never settles\n", min(out[, 1]), max(out[, 1])))
strategy 1 ranges over 0.157 to 0.550: it never settles

The interior point where all three are at 1/3 is an equilibrium, but not an ESS: it is a neutrally stable centre, not an attractor. Started off it, the population orbits forever without converging. The time-average of each strategy is 1/3, yet at no single moment is the population actually there. Reporting “the equilibrium is one-third each” would describe a state the population never occupies.

library(ggplot2)
tt <- seq_len(nrow(out)) * 0.005
d <- rbind(data.frame(t = tt, x = out[, 1], s = "rock"),
           data.frame(t = tt, x = out[, 2], s = "paper"),
           data.frame(t = tt, x = out[, 3], s = "scissors"))
ggplot(d, aes(t, x, colour = s)) +
  geom_hline(yintercept = 1/3, colour = "#93a87f", linewidth = 0.4) +
  geom_line(linewidth = 0.7) +
  scale_colour_manual(values = c(rock = "#275139", paper = "#c9b458", scissors = "#b5534e")) +
  labs(x = "Time", y = "Frequency", colour = NULL) +
  theme_minimal(base_size = 12)
Three coloured lines oscillating out of phase over time, none settling to a constant value.
Figure 1: Rock-paper-scissors replicator dynamics. The three frequencies chase each other in sustained cycles and never reach the one-third equilibrium; the mean is 1/3 but the population is never at rest.

When it does settle

Not every game cycles. A game with a genuine ESS, like hawk-dove, sends the replicator straight to its stable mix and holds it there. The difference is structural: hawk-dove has negative frequency dependence pulling toward a point, while rock-paper-scissors has a rotational flow with nothing at the centre to pull toward. The same equation produces both, so you cannot assume an equilibrium is where a population ends up. Whether an interior point attracts, repels, or merely circles is a question about the flow around it (see basins of attraction), not about the equilibrium alone.

An honest limit

The replicator equation assumes an infinite, well-mixed population reproducing in proportion to payoff, with fixed payoffs and no mutation. Each assumption bends real cases. Finite populations add drift that can push a cycling system to the boundary and lose a strategy for good; spatial structure can stabilise cycles that would otherwise wander; and the payoff matrix is, as ever, assumed rather than measured. The equation is a clear lens on which strategies win and whether they settle, not a literal population forecast. The checking post takes up finite populations and payoff sensitivity directly.

References

Hofbauer J, Sigmund K 2003. Bulletin of the American Mathematical Society 40(4):479-519 (10.1090/S0273-0979-03-00988-1)

Nowak MA, Sigmund K 2004. Science 303(5659):793-799 (10.1126/science.1093411)

Sinervo B, Lively CM 1996. Nature 380(6571):240-243 (10.1038/380240a0)

Newsletter

Get new tutorials by email

New R and QGIS tutorials for ecologists, straight to your inbox. No spam; unsubscribe anytime.

By subscribing you agree to receive these emails and confirm your address once. See the privacy policy.