Modelos Continuos · Tema 20

Modelos epidemiológicos

Susceptibles, infectados y recuperados: contagio, pico y ataque final en una cadena cerrada.

01 · Punto de partida

Una población que se pasa la antorcha

Diez infectados entre 990 susceptibles: cada encuentro contagia con tasa β y cada infectado se recupera con tasa γ. Los susceptibles bajan, los infectados suben y bajan (joroba), los recuperados suben. La suma no se mueve: es una cadena cerrada S → I → R.

El SIR es el sistema acoplado por excelencia: tres estados, dos flujos y un número que decide todo, R₀ = β/γ.

  • ¿Cuánto contagia cada infectado (β)?
  • ¿Cuánto tarda en recuperarse (1/γ)?
  • ¿R₀ supera 1 y despega, o no?
  • ¿Cuándo es el pico y cuántos se infectan en total?

02 · Definición

¿Qué es el modelo SIR?

Tres estados, dos flujos, una conservación:

S

Susceptibles

Pueden contagiarse: solo bajan. Flujo de salida β·S·I/N hacia I.

I

Infectados

Contagian y se recuperan: suben por contagio, bajan por γ·I. La joroba.

R

Recuperados

Ya pasaron: solo suben con γ·I. Memoria del brote (ataque final).

R₀ es cuántos contagia cada infectado en población virgen: con β = 0,3 y γ = 0,1, R₀ = 3 y el brote despega.

R₀ decide el brote (N = 1000, I₀ = 10).
TasasR₀Historia
β = 0,3, γ = 0,13 (brote)Joroba alta y ataque grande.
β = 0,15, γ = 0,11,5 (lento)Joroba tardía y más baja.
β = 0,08, γ = 0,10,8 (no)I decae sin pico: se apaga.
β = 0,3, γ = 0,31 (umbral)Borde: ni despega ni muere rápido.

03 · Anatomía

R₀, pico y ataque final

Tres números cuentan el brote:

R₀ = β/γ
Umbral en 1: arriba hay joroba, abajo decaimiento. Bajar β (distancia) o subir γ (aislar) lo voltean.
Pico de I
Máximo simultáneo: demanda pico del sistema. Más R₀, pico más alto y temprano.
Ataque final R(∞)/N
Fracción que pasó por I: con R₀ = 3 supera el 90 %. La S final es lo que se salvó.
Conservación S + I + R = N
La suma de tasas es cero: nadie entra ni sale. El modelo es cadena cerrada.

R₀ > 1 (brote)

Sube, dobla y baja

I despega exponencial (S ≈ N), toca el pico cuando S cruza N/R₀ y cae por falta de susceptibles.

R₀ < 1 (no brote)

Decae sin pico

Cada infectado contagia menos de uno: I cae desde el inicio y R(∞) apenas supera I₀.

04 · SIR en el curso

La cadena que reaparece

El mismo esqueleto S → I → R viste varios trajes:

S→I (joroba)→R (ataque)
  1. 1
    Gripe.

    Brote estacional con R₀ ≈ 1,5: joroba moderada y ataque parcial.

  2. 2
    Sarampión.

    R₀ alto (≈ 12): rapidísimo y casi todos pasan por I sin vacuna.

  3. 3
    SEIR.

    Latentes E entre S e I: el pico se retrasa y se suaviza.

  4. 4
    SIS.

    Sin inmunidad: I vuelve a S. Equilibrio endémico en vez de ataque final.

  5. 5
    Vacunación.

    Mueve S a R sin pasar por I: baja el susceptible inicial y voltea R₀ efectivo.

05 · Representación en Python

Tres estados que se pasan masa

En Python, el SIR es f(estado) con contagio y recuperación, más Euler que avanza los tres juntos.

Python en tu navegador. Estos bloques se ejecutan localmente con Pyodide, sin instalar nada. Bajá beta a 0,08 y observá que I ya no tiene pico.

def tasas_sir(estado, beta=0.3, gamma=0.1, n=1000):
    s, i = estado["S"], estado["I"]
    contagio = beta * s * i / n
    return {"dS": -contagio, "dI": contagio - gamma * i, "dR": gamma * i}


print(tasas_sir({"S": 990.0, "I": 10.0, "R": 0.0}))

dS = −2,97 · dI = +1,97 · dR = +1,0: la suma es cero, la cadena cierra.

Un brote en diez líneas

Euler con los tres juntos hasta el pico y más allá:

def brote(beta=0.3, gamma=0.1, n=1000, i0=10, dias=160, dt=0.5):
    s, i, r, t = n - i0, float(i0), 0.0, 0.0
    pico = i
    while t < dias - 1e-9:
        c = beta * s * i / n
        s, i, r = s - c * dt, i + (c - gamma * i) * dt, r + gamma * i * dt
        pico = max(pico, i)
        t += dt
    return round(pico, 1), round(r, 1)


print(brote())

06 · Exploración

Laboratorio: voltear R₀

SIR con N = 1000 e I₀ = 10 hasta 160 días. S dorada que cae, I teal con joroba, R naranja que sube. Movete β y γ y observá el umbral R₀ = 1: arriba hay pico, abajo I muere sin nacer.

EXPERIMENTO 20

La joroba que decide

R₀ = β/γ · N = 1000 · 160 días

Los resultados numéricos aparecen debajo.
R₀ = β/γ3,00
Pico de I300,8
Día del pico38,5
Ataque R(∞)94,0 %

Con R₀ 3 el pico es 300,8 en el día 38,5.

El pico de I ocurre cuando S cruza N/R₀: ahí el contagio iguala a la recuperación y la joroba dobla.

Preguntas para explorar

  1. Con β = 0,08 y γ = 0,1, ¿hay joroba? ¿Cuánto da el ataque?
  2. Duplicá γ con el mismo β = 0,3. ¿El pico sube o baja? ¿Y el día?
  3. Con I(0) = 1 en vez de 10, ¿el pico cambia o solo se retrasa?
Ver respuestas sugeridas
  1. No: R₀ = 0,8, I decae y el ataque apenas supera el 2 %. Sin umbral no hay brote.
  2. Baja y se atrasa menos: R₀ cae a 1,5, la joroba se achica y se corre a la derecha.
  3. Casi igual de alto pero más tarde: la semilla adelanta el reloj, no el tamaño (en SIR simple).

07 · Comprensión

Confusiones frecuentes

«R₀ es el pico»

No: R₀ es el umbral y la fuerza. El pico y el ataque salen de integrar: con R₀ = 3 el pico ronda 300 en N = 1000.

«Más I₀, más brote final»

Más I₀ adelanta el reloj; el tamaño lo mandan R₀ y N. La semilla apura, no agranda.

«El pico es cuando se acaban los susceptibles»

Es cuando S = N/R₀: quedan susceptibles, pero ya no alcanzan para sostener el crecimiento.

«SIR predice personas exactas»

Predice fracciones promedio: 300,8 infectados es 300 u 301 con ruido. Con pocos, el entero manda.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: R₀ a mano

Con β = 0,25 y γ = 0,1, ¿hay brote? ¿Y con β = 0,09?

for beta in [0.25, 0.09]:
    r0 = beta / 0.1
    print(beta, "R0 =", r0, "→", "brote" if r0 > 1 else "se apaga")
Ver solución

2,5 → brote y 0,9 → se apaga: el 1 decide sin integrar nada.

Ejercicio 2: pico cuando S = N/R₀

Con N = 1000, β = 0,3 y γ = 0,1, ¿en qué S dobla la joroba?

print(1000 / (0.3 / 0.1))
Ver solución

En S ≈ 333: cuando los susceptibles caen a un tercio, el contagio ya no repone y la joroba cae.

Ejercicio 3: ataque final

Simulá con Euler hasta 160 días y reportá pico y R final con β = 0,3, γ = 0,1, I₀ = 10.

Ver una posible respuesta
def brote(beta=0.3, gamma=0.1, n=1000, i0=10, dias=160, dt=0.5):
    s, i, r, t, pico, dia = n - i0, float(i0), 0.0, 0.0, i0, 0.0
    while t < dias - 1e-9:
        c = beta * s * i / n
        s, i, r = s - c * dt, i + (c - gamma * i) * dt, r + gamma * i * dt
        t += dt
        if i > pico:
            pico, dia = i, t
    return round(pico, 1), round(dia, 1), round(r / n * 100, 1)


print(brote())

Pico ≈ 300,8 en día ≈ 38,5, ataque ≈ 94 %: casi todos pasan por I.

09 · Síntesis

Ideas para recordar

  • SIR: S → I → R con βSI/N y γI; S + I + R = N siempre.
  • R₀ = β/γ: arriba de 1 hay joroba, abajo decae. El pico dobla en S = N/R₀.
  • I₀ adelanta el reloj; R₀ y N deciden el tamaño y el ataque.
  • En Python: tasas_sir + Euler conjunto con S + I + R verificado.
  • Promedio homogéneo: orienta políticas, no predice personas exactas.

En el próximo tema el movimiento será físico: posición, velocidad y aceleración.