SIR Model with Vaccination
An SIR vaccination simulation modeling epidemics with optional vaccination.
Level:Intermediate
Leverage Points
Discover how small, well-focused actions can produce significant, lasting improvements in complex systems.
Explore Leverage Pointssimulation.py
SIR outbreak with optional vaccination
This minimal model tracks susceptible, infected and recovered populations. Flip vaccination on or off to see how immunisation rates change the course of an outbreak.
from tys import probe, progress
Simulate an SIR outbreak with optional vaccination.
def simulate(cfg: dict):
import simpy
env = simpy.Environment()
Parameters
population = cfg["population"]
infected = cfg["initial_infected"]
beta = cfg["beta"]
gamma = cfg["gamma"]
vacc_rate = cfg.get("vaccination_rate", 0.0)
vaccinate = cfg.get("vaccinate", False)
days = cfg["sim_days"]
susceptible = population - infected
recovered = 0.0
vaccinated_total = 0.0
done = env.event()
Record the S, I and R populations over time.
def recorder():
while True:
probe("susceptible", env.now, susceptible)
probe("infected", env.now, infected)
probe("recovered", env.now, recovered)
yield env.timeout(1)
env.process(recorder())
Apply infection, recovery and vaccination each day.
def dynamics():
nonlocal susceptible, infected, recovered, vaccinated_total
for d in range(days):
new_infections = beta * susceptible * infected / population
new_recoveries = gamma * infected
if vaccinate:
new_vaccinated = vacc_rate * susceptible
else:
new_vaccinated = 0.0
susceptible = max(susceptible - new_infections - new_vaccinated, 0.0)
infected = max(infected + new_infections - new_recoveries, 0.0)
recovered = min(recovered + new_recoveries + new_vaccinated, population)
vaccinated_total += new_vaccinated
if infected < 1:
progress(int(100 * d / days), "🎉 Epidemic nearly over")
yield env.timeout(1)
progress(100)
done.succeed({
"final_infected": infected,
"vaccinated_total": vaccinated_total
})
env.process(dynamics())
env.run(until=done)
return done.value
def requirements():
return {
"builtin": ["micropip", "pyyaml"],
"external": ["simpy==4.1.1"],
}
Default.yaml
population: 1000
initial_infected: 10
beta: 0.3
gamma: 0.1
vaccination_rate: 0.01
vaccinate: true
sim_days: 160
Charts (Default)
Final Results (Default)
Metric | Value |
---|---|
final_infected | 0.00 |
vaccinated_total | 291.17 |
FAQ
- How is vaccination modeled?
- If vaccinate is true, each day susceptible individuals are reduced by vacc_rate * susceptible and moved to the recovered count.
- How does infection spread each day?
- New infections equal beta * susceptible * infected divided by the total population.
- When is progress text shown?
- If infected falls below one the simulation marks near completion with a progress message.