模拟传染病的传播与控制
人群分为四类:
模型假设和动态特征:
SEIAS模型将人群分为易感者(S)、暴露者(E)、感染者(I)和无症状感染者(A)。易感者通过与感染者和无症状感染者接触被感染,转化为暴露者;暴露者随后以一定概率转化为感染者或无症状感染者。感染者和无症状感染者在结束传染状态后,重新转为易感者,模型体现了短期免疫或未获得长期免疫的特性,可能导致循环传播。感染者和无症状感染者具有不同的传播能力,且无症状感染者对疫情传播的隐蔽性影响显著。
表 1 SEIAS 模型参数
参数 | 含义 |
---|---|
S | 易感者人数 |
E | 暴露者人数(已感染但尚未传染他人) |
I | 感染者人数(有症状且具有传染性) |
A | 无症状感染者人数(无症状但具有传染性) |
N | 总人口数 N = S + E + I + A |
β | 传播率,表示每单位时间内的感染概率 |
γᵢ | 感染者的康复率 |
γₐ | 无症状感染者的康复率 |
ω | 暴露者转化为感染者或无症状感染者的速率 |
p | 暴露者转化为感染者的概率 |
t | 时间 |
以下是SEIAS模型的流程图,展示了易感者、感染者和恢复者之间的转化过程:
图 1 SEIAS模型流程图
SEIAS 模型由以下四组微分方程描述:
$$
\begin{cases}
\frac{d\mathit{S}}{dt} &= - \beta \cdot \frac{\mathit{S} \cdot (\mathit{I} + \mathit{A})}{\mathit{N}} + \gamma_I \cdot \mathit{I} + \gamma_A \cdot \mathit{A}, \\
\frac{d\mathit{E}}{dt} &= \beta \cdot \frac{\mathit{S} \cdot (\mathit{I} + \mathit{A})}{\mathit{N}} - \omega \cdot \mathit{E}, \\
\frac{d\mathit{I}}{dt} &= p \cdot \omega \cdot \mathit{E} - \gamma_I \cdot \mathit{I}, \\
\frac{d\mathit{A}}{dt} &= (1 - p) \cdot \omega \cdot \mathit{E} - \gamma_A \cdot \mathit{A}.
\end{cases}
$$
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
# 设置中文字体
plt.rcParams['font.family'] = ['SimHei'] # 或者 'Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# SEIAS模型微分方程
def seias_ode(t, y, N, beta, gamma_I, gamma_A, omega, p):
S, E, I, A = y # 易感者、暴露者、感染者和无症状感染者数量
dS = -beta * S * (I + A) / N + gamma_I * I + gamma_A * A # 易感者的变化
dE = beta * S * (I + A) / N - omega * E # 暴露者的变化
dI = p * omega * E - gamma_I * I # 感染者的变化
dA = (1 - p) * omega * E - gamma_A * A # 无症状感染者的变化
return [dS, dE, dI, dA]
# 参数设置
N = 21858000 # 人口
beta = 1.1 # 传播率
gamma_I = 0.25 # 感染者康复率
gamma_A = 0.2 # 无症状康复率
omega = 0.2 # 暴露转感染速率
p = 0.5 # 发病概率
I0 = 170 # 初始感染人数
A0 = 0 # 初始无症状感染人数
# 计算初始的易感者和暴露者数量
S0 = N - I0 - A0
E0 = 0
y0 = [S0, E0, I0, A0]
# 时间点设置
t_start = 0 # 模拟开始天数
t_end = 160 # 模拟结束天数
num_points = 160 # 时间点数量
t_eval = np.linspace(t_start, t_end, num_points)
# 求解微分方程
solution = solve_ivp(
seias_ode,
[t_start, t_end],
y0,
args=(N, beta, gamma_I, gamma_A, omega, p),
t_eval=t_eval
)
# 检查求解是否成功
if solution.success:
S, E, I, A = solution.y
else:
raise RuntimeError("微分方程求解失败!")
# 绘制图形
plt.figure(figsize=(12, 6))
plt.plot(solution.t, S, label='易感者 S', color='blue')
plt.plot(solution.t, E, label='暴露者 E', color='orange')
plt.plot(solution.t, I, label='感染者 I', color='red')
plt.plot(solution.t, A, label='无症状感染者 A', color='purple')
plt.title(f'SEIAS 模型模拟结果 (β={beta}, γ_I={gamma_I}, γ_A={gamma_A}, ω={omega}, p={p}, N={N}, I0={I0}, A0={A0})')
plt.xlabel('天数')
plt.ylabel('人数')
plt.legend()
plt.grid(True)
plt.show()
运行以上代码后,可以观察到以下趋势:
在曲线基本平行于坐标轴的部分,表示对应人群数量变化极其缓慢,疫情进入稳定期或衰退期,此时新感染者的出现基本停止,或感染者数量趋近于零。
以下是模拟结果的可视化图表展示:
通过在模拟过程中降低传播率 β,可以模拟隔离措施的效果。例如:
可以在微分方程中引入时间依赖的传播率 β(t),例如:
$$
\beta(t) = \begin{cases}
1.1, & t < 30 \
0.7, & t \geq 30
\end{cases}
$$
发病概率 p 可以随着时间变化。例如:
发病概率 p(t) 可以用时间相关的函数表示,例如:
$$
p(t) = \begin{cases}
0.5, & t < 50 \
0.3, & t \geq 50
\end{cases}
$$
在疫情开始后的第 30 天,通过降低传播率 β 模拟实施隔离或封锁的措施。
通过直接减少易感者人数 S,并增加恢复者人数 R,模拟大规模疫苗接种的效果。例如,假设在第 50 天时易感者中接种疫苗的人数覆盖了 40% 的总人口,则:
$$ S = S - 0.4 \cdot N, \quad R = R + 0.4 \cdot N $$
在某些传染病中(如流感),传播率 β 可能具有季节性波动。例如:
$$ \beta(t) = 1.0 + 0.5 \cdot \sin\left(\frac{2\pi t}{365} + \phi\right) $$
其中:
这种形式可以模拟因气候变化或人群行为模式变化(如节假日聚集)导致的传播速率波动,同时允许通过初相位 φ 调整传播率波动的具体时间特性。