MATLAB实战:传染病模型仿真实现
以下是一个使用MATLAB实现传染病模型(SIR和SEIR)仿真的完整解决方案,包含参数分析和干预措施模拟:
%% 传染病模型仿真工具箱
% 包含SIR、SEIR模型,支持参数调整和干预措施模拟
% 使用ode45求解微分方程
function epidemic_modeling()
% 主控制界面
fig = uifigure('Name', '传染病模型仿真', 'Position', [100 100 800 600]);
% 模型选择
model_dropdown = uidropdown(fig, ...
'Position', [50 550 100 30], ...
'Items', {'SIR模型', 'SEIR模型'});
% 参数设置面板
param_panel = uipanel(fig, 'Title', '参数设置', ...
'Position', [50 300 300 200]);
% 初始人群设置
uilabel(param_panel, 'Text', '易感者比例:', 'Position', [20 150 80 20]);
s0_edit = uieditfield(param_panel, 'numeric', ...
'Position', [120 150 60 20], 'Value', 0.99);
uilabel(param_panel, 'Text', '感染者比例:', 'Position', [20 120 80 20]);
i0_edit = uieditfield(param_panel, 'numeric', ...
'Position', [120 120 60 20], 'Value', 0.01);
% SIR参数
uilabel(param_panel, 'Text', '传染率(β):', 'Position', [20 90 80 20]);
beta_edit = uieditfield(param_panel, 'numeric', ...
'Position', [120 90 60 20], 'Value', 0.3);
uilabel(param_panel, 'Text', '恢复率(γ):', 'Position', [20 60 80 20]);
gamma_edit = uieditfield(param_panel, 'numeric', ...
'Position', [120 60 60 20], 'Value', 0.1);
% SEIR额外参数 (默认隐藏)
uilabel(param_panel, 'Text', '潜伏期(1/σ):', 'Position', [20 30 80 20], 'Visible', 'off');
sigma_edit = uieditfield(param_panel, 'numeric', ...
'Position', [120 30 60 20], 'Value', 0.2, 'Visible', 'off');
% 干预措施面板
intervention_panel = uipanel(fig, 'Title', '干预措施', ...
'Position', [400 300 300 200]);
uilabel(intervention_panel, 'Text', '隔离强度:', 'Position', [20 150 80 20]);
isolation_slider = uislider(intervention_panel, ...
'Position', [20 130 200 3], 'Limits', [0 1], 'Value', 0);
uilabel(intervention_panel, 'Text', '接种比例:', 'Position', [20 90 80 20]);
vaccination_slider = uislider(intervention_panel, ...
'Position', [20 70 200 3], 'Limits', [0 1], 'Value', 0);
uilabel(intervention_panel, 'Text', '干预时间:', 'Position', [20 30 80 20]);
intervention_time = uieditfield(intervention_panel, 'numeric', ...
'Position', [120 30 60 20], 'Value', 30);
% 按钮
run_btn = uibutton(fig, 'push', ...
'Text', '运行仿真', ...
'Position', [50 250 100 30], ...
'ButtonPushedFcn', @(btn,event) runSimulation());
% 绘图区域
ax = uiaxes(fig, 'Position', [100 50 600 200]);
% 模型切换回调
model_dropdown.ValueChangedFcn = @(src,event) toggleModel();
%% 模型切换函数
function toggleModel()
if strcmp(model_dropdown.Value, 'SEIR模型')
sigma_edit.Visible = 'on';
sigma_edit.Parent.Children(1).Visible = 'on'; % 显示标签
else
sigma_edit.Visible = 'off';
sigma_edit.Parent.Children(1).Visible = 'off'; % 隐藏标签
end
end
%% 主仿真函数
function runSimulation()
% 获取参数
S0 = s0_edit.Value;
I0 = i0_edit.Value;
beta = beta_edit.Value;
gamma = gamma_edit.Value;
sigma = sigma_edit.Value;
iso_strength = isolation_slider.Value;
vacc_ratio = vaccination_slider.Value;
t_intervention = intervention_time.Value;
% 总人口归一化
total_pop = S0 + I0;
R0 = 0; % 初始康复者
E0 = 0; % 初始潜伏者
% 时间范围 (天)
tspan = [0 200];
% 根据模型选择设置初始条件和方程
if strcmp(model_dropdown.Value, 'SIR模型')
y0 = [S0, I0, R0];
[t, y] = ode45(@(t,y) sir_ode(t, y, beta, gamma, iso_strength, vacc_ratio, t_intervention), tspan, y0);
plotResults(ax, t, y, 'SIR模型');
else
y0 = [S0, E0, I0, R0];
[t, y] = ode45(@(t,y) seir_ode(t, y, beta, gamma, sigma, iso_strength, vacc_ratio, t_intervention), tspan, y0);
plotResults(ax, t, y, 'SEIR模型');
end
end
%% SIR模型微分方程
function dydt = sir_ode(t, y, beta, gamma, iso_strength, vacc_ratio, t_interv)
S = y(1);
I = y(2);
R = y(3);
% 应用干预措施
current_beta = beta;
if t >= t_interv
% 实施隔离:降低传染率
current_beta = beta * (1 - iso_strength);
% 实施接种:部分易感者直接转为康复者
if vacc_ratio > 0
conversion = min(vacc_ratio * S, S);
S = S - conversion;
R = R + conversion;
end
end
% SIR方程
dSdt = -current_beta * S * I;
dIdt = current_beta * S * I - gamma * I;
dRdt = gamma * I;
dydt = [dSdt; dIdt; dRdt];
end
%% SEIR模型微分方程
function dydt = seir_ode(t, y, beta, gamma, sigma, iso_strength, vacc_ratio, t_interv)
S = y(1);
E = y(2);
I = y(3);
R = y(4);
% 应用干预措施
current_beta = beta;
if t >= t_interv
current_beta = beta * (1 - iso_strength);
if vacc_ratio > 0
conversion = min(vacc_ratio * S, S);
S = S - conversion;
R = R + conversion;
end
end
% SEIR方程
dSdt = -current_beta * S * I;
dEdt = current_beta * S * I - sigma * E;
dIdt = sigma * E - gamma * I;
dRdt = gamma * I;
dydt = [dSdt; dEdt; dIdt; dRdt];
end
%% 结果可视化
function plotResults(ax, t, y, model_name)
cla(ax);
hold(ax, 'on');
if contains(model_name, 'SIR')
plot(ax, t, y(:,1), 'b', 'LineWidth', 2, 'DisplayName', '易感者(S)');
plot(ax, t, y(:,2), 'r', 'LineWidth', 2, 'DisplayName', '感染者(I)');
plot(ax, t, y(:,3), 'g', 'LineWidth', 2, 'DisplayName', '康复者(R)');
else
plot(ax, t, y(:,1), 'b', 'LineWidth', 2, 'DisplayName', '易感者(S)');
plot(ax, t, y(:,2), 'm', 'LineWidth', 2, 'DisplayName', '潜伏者(E)');
plot(ax, t, y(:,3), 'r', 'LineWidth', 2, 'DisplayName', '感染者(I)');
plot(ax, t, y(:,4), 'g', 'LineWidth', 2, 'DisplayName', '康复者(R)');
end
title(ax, [model_name ' - 疫情传播模拟']);
xlabel(ax, '时间 (天)');
ylabel(ax, '人群比例');
legend(ax, 'Location', 'best');
grid(ax, 'on');
hold(ax, 'off');
end
end
功能说明
-
模型实现:
-
SIR模型:易感者(S) → 感染者(I) → 康复者(R)
-
SEIR模型:易感者(S) → 潜伏者(E) → 感染者(I) → 康复者(R)
-
-
参数分析:
-
传染率(β):控制疾病传播速度
-
恢复率(γ):影响感染者恢复速度(1/γ = 平均感染期)
-
潜伏期(1/σ):SEIR模型特有参数(1/σ = 平均潜伏期)
-
-
干预措施:
-
隔离:降低传染率(通过滑动条控制强度)
-
疫苗接种:将部分易感者直接转为康复者
-
干预时间:指定措施开始实施的时间点
-
-
可视化:
-
动态显示各类人群比例随时间变化
-
不同人群用颜色区分:蓝色(易感者)、红色(感染者)、绿色(康复者)、紫色(潜伏者)
-
使用方法
-
在MATLAB中运行
epidemic_modeling()
启动GUI -
选择模型(SIR或SEIR)
-
设置初始人群比例和疾病参数
-
调整干预措施参数
-
点击"运行仿真"查看结果
关键技能点实现
-
微分方程建模:
-
SIR和SEIR模型用常微分方程组表示
-
方程包含人群转换过程
-
-
ode45求解:
-
使用MATLAB内置求解器处理非刚性微分方程
-
支持时变参数(干预措施)
-
-
参数分析:
-
GUI滑块实时调整参数
-
可比较不同参数下的传播曲线
-
-
干预措施模拟:
-
隔离:降低有效传染率 β → β(1-强度)
-
接种:直接转移易感人群 S → R
-
-
可视化:
-
多曲线动态绘制
-
图例和坐标标签
-
网格辅助线
-
此代码提供了完整的传染病仿真框架,可通过调整参数和干预措施模拟不同场景下的疫情发展,适用于教学演示和疫情政策效果评估。