当前位置: 首页 > news >正文

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

功能说明

  1. 模型实现

    • SIR模型:易感者(S) → 感染者(I) → 康复者(R)

    • SEIR模型:易感者(S) → 潜伏者(E) → 感染者(I) → 康复者(R)

  2. 参数分析

    • 传染率(β):控制疾病传播速度

    • 恢复率(γ):影响感染者恢复速度(1/γ = 平均感染期)

    • 潜伏期(1/σ):SEIR模型特有参数(1/σ = 平均潜伏期)

  3. 干预措施

    • 隔离:降低传染率(通过滑动条控制强度)

    • 疫苗接种:将部分易感者直接转为康复者

    • 干预时间:指定措施开始实施的时间点

  4. 可视化

    • 动态显示各类人群比例随时间变化

    • 不同人群用颜色区分:蓝色(易感者)、红色(感染者)、绿色(康复者)、紫色(潜伏者)

使用方法

  1. 在MATLAB中运行epidemic_modeling()启动GUI

  2. 选择模型(SIR或SEIR)

  3. 设置初始人群比例和疾病参数

  4. 调整干预措施参数

  5. 点击"运行仿真"查看结果

关键技能点实现

  1. 微分方程建模

    • SIR和SEIR模型用常微分方程组表示

    • 方程包含人群转换过程

  2. ode45求解

    • 使用MATLAB内置求解器处理非刚性微分方程

    • 支持时变参数(干预措施)

  3. 参数分析

    • GUI滑块实时调整参数

    • 可比较不同参数下的传播曲线

  4. 干预措施模拟

    • 隔离:降低有效传染率 β → β(1-强度)

    • 接种:直接转移易感人群 S → R

  5. 可视化

    • 多曲线动态绘制

    • 图例和坐标标签

    • 网格辅助线

此代码提供了完整的传染病仿真框架,可通过调整参数和干预措施模拟不同场景下的疫情发展,适用于教学演示和疫情政策效果评估。

相关文章:

  • RocketMQ 学习
  • 中国高分辨率高质量地面CO数据集(2013-2023)
  • 8088 单板机 汇编 NMI 中断程序示例 (脱离 DOS 环境)
  • 爬虫入门:从基础到实战全攻略
  • 深入浅出MQTT协议:从物联网基础到实战应用全解析
  • nt!MiDispatchFault函数里面的nt!IoPageRead函数分析和nt!MiWaitForInPageComplete函数分析
  • ArcPy错误处理与调试技巧(3)
  • SRE 基础知识:在站点可靠性工程中可以期待什么
  • Mac电脑上本地安装 MySQL并配置开启自启完整流程
  • 数字创新智慧园区建设及运维方案
  • go环境配置
  • MATLAB中properties函数用法
  • 【Linux命令】scp远程拷贝
  • 考研系列—操作系统:第五章、输入输出(I/O)管理
  • 【笔记】在 MSYS2(MINGW64)中安装 python-maturin 的记录
  • 【python深度学习】Day 42 Grad-CAM与Hook函数
  • 关于langchain使用API加载model的方式
  • C++基础算法————广度优先搜索(BFS)
  • Spring AI调用Ollama+DeepSeek
  • 微调大模型:什么时候该做,什么时候不该做?
  • 中国十大搜索引擎排名最新/广西seo优化
  • 芜湖哪里有做网站的/优秀网页设计作品
  • 基于WEB的企业网站开发 开题报告/威海seo
  • 酒东莞网站建设技术支持/seo关键词排名优化制作
  • 网站需求分析报告范文/大数据营销案例
  • 丹阳网站建设开发/百度关键词首页排名