OS-032 · Networks

Epidemic on a network

People infect the people they are actually in contact with, not a random member of the population. This lab runs a stochastic SIR epidemic along the edges of a network and compares the outcome with what homogeneous mixing predicts for the same average number of contacts.

Interactive model

OS-032 · network-epidemic · seeded
susceptibleinfectedrecovered
SIRfinal size, mixingfinal size, degree-based
Parameters
Ring lattice = small world with rewiring 0
Rounded down to an even number for small world and preferential attachment
Small world only: share of ring edges moved to random nodes
Chance an infected node infects a susceptible neighbor in one step
Mean infectious period is 1/γ steps
The run ends early when nobody is infected
Same seed, same run — here, in simulation.js and in simulation.py.
Ever infected (simulated)
61.7%
Peak infected
28
Peak step
29
Last infection cleared at step
212
Final size, degree-based theory
85.4%
Final size, homogeneous mixing
81.5%
Transmissibility T
0.345
R₀, degree-based
1.74
R₀, mixing ⟨k⟩T
2.07
Mean degree (actual)
6.00
Largest degree
8
Clustering coefficient
0.503

Example run: default parameters, seed 42.

Same disease, different contacts

The SIR model assumes homogeneous mixing: every infected person is equally likely to meet every susceptible one. On a network, infection can only travel along edges, so who is connected to whom changes how fast, how far and how predictably an outbreak spreads. Keep the transmission and recovery probabilities fixed and switch the network type to see it.

  • Ring lattice and small world. With rewiring 0 every node is linked to its nearest neighbors on a circle. Infection creeps around the ring in slow fronts, much of it wasted on neighbors that are already infected, and outbreaks stay far below the mixing prediction. A few rewired shortcuts (small β) let infection jump across the circle and seed new fronts; the default run shows this halfway regime.
  • Random graph. With no clustering and a narrow (Poisson) degree distribution, the Erdős–Rényi network behaves most like homogeneous mixing; large outbreaks land close to both predictions.
  • Preferential attachment. A few hubs have many contacts. Hubs are reached early and pass infection to many others, which raises the degree-based R₀, yet the predicted final size is smaller than under mixing because many low-degree nodes are never reached.

Every run is one random outbreak. Change the seed: sometimes the initial cases recover before passing infection on, and the epidemic fizzles even when R₀ is above 1.

The model

Each node is susceptible (S), infected (I) or recovered (R). Time moves in discrete steps. In each step:

  1. Every infected node tries once to infect each susceptible neighbor, succeeding with probability τ, independently per contact.
  2. Every node that was infected at the start of the step recovers with probability γ, and stays immune.
  3. Newly infected nodes become infectious from the next step. The run stops when no node is infected.

The infectious period is geometric with mean 1/γ steps, and an infected node tries every edge at least once. The probability that infection eventually crosses a given edge before the infected end recovers is the transmissibility

T = τ / (1 − (1 − τ)(1 − γ))

The three networks are built from the seed. Erdős–Rényi: every pair is linked with probability ⟨k⟩/(n − 1). Watts–Strogatz: a ring where each node links to ⟨k⟩/2 neighbors on each side, after which each edge is rewired to a random node with probability β. Barabási–Albert: nodes arrive one at a time and link to ⟨k⟩/2 existing nodes chosen with probability proportional to degree. The drawing's layout is only for display and plays no part in the model.

Homogeneous mixing versus network structure

If each infected node instead met ⟨k⟩ random nodes, each contact transmitting with probability T, the basic reproduction number would be R₀ = ⟨k⟩T and the fraction ever infected z would solve the classic final-size equation z = 1 − e−R₀z. That is the homogeneous-mixing line on the chart.

On a network, a node reached by infection arrived along one of its edges, so it has one fewer susceptible neighbor to pass it on to — and nodes are reached in proportion to their degree. Treating the network as random apart from its degrees (a configuration model), Newman showed that an epidemic is possible only when T exceeds ⟨k⟩/(⟨k²⟩ − ⟨k⟩), which amounts to R₀ > 1 with

R₀ = T · (⟨k²⟩ − ⟨k⟩) / ⟨k⟩

He also showed that the final size follows from the generating functions of the degree distribution pk, G0(x) = Σ pkxk and G1(x) = G0′(x)/⟨k⟩: solve u = G1(1 − T + Tu), then the expected outbreak size is 1 − G0(1 − T + Tu). The lab computes both from the degrees of the network it actually built. Heterogeneous degrees raise ⟨k²⟩ and with it R₀; for scale-free networks whose degree variance grows without bound, the epidemic threshold vanishes as the network grows (Pastor-Satorras and Vespignani).

The degree-based theory ignores clustering — the chance that two neighbors of a node are also neighbors of each other — and assumes a large network. The ring lattice is highly clustered, so an infected node's contacts overlap and local susceptibles run out; that is why small-world outbreaks fall short of the theory while random-graph outbreaks match it. Watts and Strogatz pointed out in 1998 that a small fraction of shortcuts is enough to make spreading on such networks much faster.

Example result

With the defaults — a 300-node small world, mean degree 6, rewiring 0.05, τ = 0.05, γ = 0.1 and seed 42 — the transmissibility is 0.345, so homogeneous mixing gives R₀ = 2.07 and a final size of 81.5%; degree-based theory predicts 85.4%. The simulated outbreak infected 61.7% of the nodes, peaking at 28 infected at step 29 and ending at step 212. The network's clustering coefficient is 0.503, which the degree-based theory does not account for.

Output of network-epidemic with network=ws nodes=300 mean_degree=6 rewiring=0.05 tau=0.05 gamma=0.1 initial_infected=3 steps=400 seed=42
Ever infected (simulated)61.7%
Peak infected28
Peak step29
Last infection cleared at step212
Final size, degree-based theory85.4%
Final size, homogeneous mixing81.5%
Transmissibility T0.345
R₀, degree-based1.74
R₀, mixing ⟨k⟩T2.07
Mean degree (actual)6.00
Largest degree8
Clustering coefficient0.503

Implementation

The page runs simulation.js from the package below; the Python file is a line-by-line port with the same random-number generator, so a given seed produces the same result in both languages. The excerpts show the core of each.

JavaScript — simulation.js
// One step of discrete-time SIR on a network. Every infected node tries once to
// infect each susceptible neighbor (probability τ per contact), then recovers with
// probability γ. New infections become infectious from the next step.
export function stepEpidemic(net, ep, tau, gamma, rng) {
  const { state } = ep, { n, adj } = net;
  for (let v = 0; v < n; v++) {
    if (state[v] !== I) continue;
    for (const u of adj[v]) if (state[u] === S && rng.uniform() < tau) state[u] = NEW;
  }
  for (let v = 0; v < n; v++) if (state[v] === I && rng.uniform() < gamma) { state[v] = R; ep.i--; ep.r++; }
  for (let v = 0; v < n; v++) if (state[v] === NEW) { state[v] = I; ep.s--; ep.i++; }
  ep.step++;
}
Python — simulation.py
def step_epidemic(adj, state, tau, gamma, rng):
    """Discrete-time SIR on a network: each infected node tries once per step to infect
    each susceptible neighbor (probability tau), then recovers with probability gamma.
    New infections become infectious from the next step."""
    n = len(adj)
    for v in range(n):
        if state[v] != I:
            continue
        for u in adj[v]:
            if state[u] == S and rng.uniform() < tau:
                state[u] = NEW
    for v in range(n):
        if state[v] == I and rng.uniform() < gamma:
            state[v] = R
    for v in range(n):
        if state[v] == NEW:
            state[v] = I

Run the full model from a terminal:

Shell
node simulation.js --network ws --nodes 300 --seed 42
python simulation.py --network ws --nodes 300 --seed 42

Download the model

network-epidemic.zip6 files · 14.0 KBDownload .zip
Files in network-epidemic.zip
FileContentsSize
README.mdHow to run it, parameters, example result3.2 KB
model.jsonParameters with ranges and defaults, outputs, the seed-42 example4.2 KB
simulation.jsThe model used on this page plus a command-line runner (Node 18+)13.2 KB
simulation.pyPython 3.9+ port, standard library only10.9 KB
example.csvResult table from the example run2.8 KB
LICENSE.txtMIT License1.0 KB

Assumptions & limitations

  • Static network. Contacts never change during the outbreak; real contact patterns change daily and respond to illness and interventions.
  • Every edge is the same. One transmission probability for all contacts; no household versus casual contacts, no contact duration or weights.
  • Discrete, synchronous steps. Infection and recovery happen once per step, and infectious periods are geometric. Continuous-time or fixed-duration versions give somewhat different numbers.
  • Theory lines are large-network approximations. Both predictions describe a major outbreak in an infinite population; small networks, early extinction and clustering all move the simulated result away from them.
  • Stylized networks. Random, small-world and preferential-attachment graphs isolate one structural feature each; none is a measured human contact network, and the model is not a forecast for any disease.

References

  1. Newman, M. E. J. (2002). Spread of epidemic disease on networks. Physical Review E, 66, 016128. doi.org/10.1103/PhysRevE.66.016128
  2. Watts, D. J. & Strogatz, S. H. (1998). Collective dynamics of 'small-world' networks. Nature, 393, 440–442. doi.org/10.1038/30918
  3. Pastor-Satorras, R. & Vespignani, A. (2001). Epidemic spreading in scale-free networks. Physical Review Letters, 86, 3200–3203. doi.org/10.1103/PhysRevLett.86.3200
  4. Barabási, A.-L. & Albert, R. (1999). Emergence of scaling in random networks. Science, 286(5439), 509–512. doi.org/10.1126/science.286.5439.509