使用MATLAB实现SEIAR模型,模拟流行病传播过程
SEIAR 模型扩展了经典的 SIR 模型,通过增加暴露者和无症状感染者的状态,更贴近现实中传染病传播的特点。模型能有效模拟传染病潜伏期和无症状传播对疫情的影响。
表 1: 仓室及其含义
仓室 | 含义 |
---|---|
$S$ | 易感者人数 |
$E$ | 暴露者人数(已感染但尚未传染他人) |
$I$ | 感染者人数(有症状且具有传染性) |
$A$ | 无症状感染者人数(无症状但具有传染性) |
$R$ | 康复者人数 |
$N$ | 总人口数($N = S + E + I + A + R$) |
表 2: 参数及其含义
参数 | 含义 |
---|---|
$\beta$ | 传播率,表示每单位时间内感染者的传染能力 |
$ \gamma $ | 感染者的康复率 |
$ \gamma_1$ | 无症状感染者的康复率 |
$\omega $ | 暴露者转化为感染者或无症状感染者的速率 |
$p $ | 暴露者转化为无症状感染者的比例 |
$k $ | 无症状感染者的相对传播能力系数 |
以下是SEIAR模型的流程图,展示了易感者、感染者和恢复者之间的转化过程:
图 1: SEIAR 模型流程图
SEIAR 模型由以下常微分方程组描述:
$$\begin{cases}
\frac{dS}{dt} = - \beta \cdot \frac{I + k \cdot A}{N} \cdot S \\
\frac{dE}{dt} = \beta \cdot \frac{I + k \cdot A}{N} \cdot S - p \cdot \omega \cdot E - (1 - p) \cdot \omega \cdot E \\
\frac{dI}{dt} = (1 - p) \cdot \omega \cdot E - \gamma \cdot I \\
\frac{dA}{dt} = p \cdot \omega \cdot E - \gamma_1 \cdot A \\
\frac{dR}{dt} = \gamma_1 \cdot A + \gamma \cdot I
\end{cases}$$
% 清除所有图像、变量和命令窗口
close all; clear; clc;
% 定义模型参数
params.tSpan = [0, 149] + 0.5; % 模拟时间范围为0.5天到149.5天,总计150天
params.k = 0.50; % 无症状患者传播能力系数,相较于有症状患者
params.omega = 0.53; % 有症状患者的潜伏期倒数 (1/潜伏期)
params.p = 0.333; % 无症状患者的比例
params.gamma = 0.33; % 有症状患者的传染期倒数 (1/传染期)
params.gamma1 = 0.25; % 无症状患者的传染期倒数 (1/传染期)
% 设置基本传播率 beta 和初始条件
beta = 0.7; % 基本传播系数 (传染率)
E0 = 0; % 初始潜伏者人数
I0 = 1; % 初始有症状感染者人数
A0 = 0; % 初始无症状感染者人数
R0 = 0; % 初始康复人数
population = 220000; % 总人口数
% 初始化易感者人数 S0
S0 = population - E0 - I0 - A0; % 易感者人数为总人口减去其他状态人群总和
params.initialStates = [S0; E0; I0; A0; R0]; % 初始状态向量 [S, E, I, A, R]
% 定义微分方程
dxdt = @(t, x) computeDerivative(beta, params, t, x); % 使用匿名函数封装微分方程
% 使用ODE45求解微分方程
[tt, xPredicted] = ode45(dxdt, params.tSpan, params.initialStates); % 调用ODE45进行数值求解
% 计算每日新增病例数
yPredicted = (1 - params.p) * params.omega * xPredicted(:, 2); % 每日新增病例数 = (1 - p) * omega * E
% 创建绘图
fig = figure; % 创建图像窗口
fig.Position = [248.2, 291.4, 1374.4, 584]; % 设置窗口大小和位置
tiledlayout(1, 2); % 创建1行2列的布局
% 绘制S, E, I, A, R状态变量随时间的变化曲线
nexttile;
plot(tt, xPredicted);
legend('S', 'E', 'I', 'A', 'R'); % 添加图例
% 绘制每日新增病例数随时间的变化曲线
nexttile;
plot(tt, yPredicted);
legend('每日新增病例数'); % 添加图例
% 导出图像为高分辨率图片
exportgraphics(fig, 'SEIAR及每日新增病例图.png', 'Resolution', 300); % 保存图片到文件
%% 微分方程函数
function dxdt = computeDerivative(beta, params, t, x)
% 提取状态变量
S = x(1); % 易感者人数
E = x(2); % 潜伏者人数
I = x(3); % 有症状感染者人数
A = x(4); % 无症状感染者人数
R = x(5); % 康复人数
% 总人口数 (用于归一化传播率)
N = S + E + I + A + R;
% 计算交互传播项
interactionTerm = beta * (I + params.k * A) / N; % 考虑有症状和无症状患者的传播能力
% 计算各状态变量的微分
dSdt = -interactionTerm * S; % 易感者人数的变化速率
dEdt = interactionTerm * S - params.p * params.omega * E - (1 - params.p) * params.omega * E; % 潜伏者人数的变化速率
dIdt = (1 - params.p) * params.omega * E - params.gamma * I; % 有症状感染者人数的变化速率
dAdt = params.p * params.omega * E - params.gamma1 * A; % 无症状感染者人数的变化速率
dRdt = params.gamma1 * A + params.gamma * I; % 康复者人数的变化速率
% 返回状态变量的变化速率
dxdt = [dSdt; dEdt; dIdt; dAdt; dRdt];
end
运行以上代码后,可以观察到以下趋势:
以下是模拟结果的可视化图表展示:
图 2: SEIAR及每日新增病例图
---通过在模拟过程中降低传播率 ($ \beta$ ),可以模拟隔离措施的效果。例如:
模型中的体现:
可以在微分方程中引入时间依赖的传播率 ( $\beta(t) $),例如:
$$\beta(t) =
\begin{cases}
0.7, & t < 50 \\
0.5, & t \geq 50
\end{cases}$$
通过直接减少易感者人数 ( S ),并增加恢复者人数 ( R ),模拟大规模疫苗接种的效果。例如,假设在第 60 天接种疫苗覆盖了 40% 的总人口,则:
$$S = S - 0.4 \cdot N, \quad R = R + 0.4 \cdot N$$