别光看狼吃羊了!用NetLogo 6.3.0从零搭建一个病毒传播模型(附完整代码)
用NetLogo构建病毒传播模型:从理论到实践的完整指南
在数字时代,流行病学研究正经历着一场革命性的变革。传统的数学方程和统计方法虽然精确,但往往难以捕捉人群互动中的复杂动态。这正是多主体建模工具如NetLogo大显身手的领域——它让我们能够直观地模拟个体之间的相互作用如何导致群体层面的现象。不同于简单的"狼吃羊"教学模型,构建一个真实的病毒传播模拟器需要考虑更多现实因素:人群移动模式、接触频率、免疫力持续时间等。本文将带您从零开始,用NetLogo 6.3.0创建一个完整的SIR(易感-感染-康复)模型,不仅展示基础实现,更会深入探讨如何调整参数以匹配真实世界数据,让您获得可直接用于科研或教学的实用建模技能。
1. 理解SIR模型的核心机制
SIR模型是流行病学中最基础的框架之一,它将人群分为三类:
- S (Susceptible):易感人群,可能被感染但尚未患病
- I (Infected):已感染人群,具有传染性
- R (Recovered):康复人群,获得免疫力不再易感
在NetLogo中实现这个模型时,我们需要量化几个关键参数:
| 参数名称 | 代码变量表示 | 典型取值范围 | 生物学意义 |
|---|---|---|---|
| 感染概率 | infection-rate | 0.01-0.3 | 每次接触导致传播的可能性 |
| 恢复率 | recovery-rate | 0.05-0.2 | 每天康复的概率 |
| 初始感染比例 | initial-infected | 0.01-0.05 | 模拟开始时感染者的占比 |
| 人群密度 | population-density | 10-70 | 每平方单位面积的人数 |
提示:这些参数需要根据具体疾病特性调整。例如COVID-19的初期R0值约为2-3,而麻疹可高达12-18。
2. 搭建基础模型框架
首先在NetLogo中创建新模型,设置以下全局变量:
globals [ total-infected ; 累计感染人数 total-recovered ; 累计康复人数 day-count ; 模拟天数 ] turtles-own [ status ; 可以是"susceptible", "infected"或"recovered" days-infected ; 感染持续时间 ]初始化过程(setup)应该包含:
to setup clear-all create-turtles population [ setxy random-xcor random-ycor ; 随机分布人群 set status "susceptible" set shape "person" set color blue ] ; 随机选择初始感染者 ask n-of (initial-infected * population) turtles [ set status "infected" set color red set days-infected 0 ] set day-count 0 reset-ticks end3. 实现传播动力学
核心的go过程需要处理三种状态转换:
to go ; 1. 传播过程 ask turtles with [status = "infected"] [ let nearby-turtles other turtles in-radius 1 ; 定义接触范围 ask nearby-turtles with [status = "susceptible"] [ if random-float 1 < infection-rate [ set status "infected" set color red set days-infected 0 ] ] ; 2. 康复过程 set days-infected days-infected + 1 if random-float 1 < recovery-rate [ set status "recovered" set color green ] ] ; 更新统计数据 set total-infected count turtles with [status = "infected"] set total-recovered count turtles with [status = "recovered"] set day-count day-count + 1 tick end为增强可视化效果,可以添加以下代码动态调整个体大小表示不同状态:
ask turtles [ ifelse status = "infected" [ set size 1.5 ; 放大感染者 ] [ set size 1 ; 正常大小 ] ]4. 添加高级功能与参数优化
基础模型运行后,可以考虑以下增强功能:
隔离措施模拟:添加滑块控制隔离强度,减少感染者活动范围
slider "quarantine-effectiveness" 0 1 0.1修改移动规则:
ask turtles with [status = "infected"] [ ifelse random-float 1 < quarantine-effectiveness [ ; 隔离状态下移动受限 rt random 30 - 15 fd 0.2 ] [ ; 正常移动 rt random 60 - 30 fd 0.5 ] ]疫苗接种策略:添加按钮控制疫苗接种时间和覆盖率
button "vaccinate-50%" [ vaccinate 0.5 ] to vaccinate [ coverage ] ask n-of (coverage * count turtles with [status = "susceptible"]) turtles with [status = "susceptible"] [ set status "recovered" set color green ] end动态传播率:模拟季节性或防控措施影响
; 在go过程中添加 set infection-rate infection-rate * (1 + 0.1 * sin (day-count / 30))
5. 结果分析与可视化
NetLogo内置的绘图工具可以实时显示疫情曲线:
- 创建新绘图"疫情发展曲线"
- 添加三个笔:
- 易感者:
plot count turtles with [status = "susceptible"] - 感染者:
plot count turtles with [status = "infected"] - 康复者:
plot count turtles with [status = "recovered"]
- 易感者:
为更专业分析,可以导出数据到CSV:
to export-data let filename user-new-file if filename != false [ file-open filename file-print (word "day,susceptible,infected,recovered") foreach range day-count [ let day ? file-print (word day "," susceptible-at day "," infected-at day "," recovered-at day) ] file-close ] end6. 模型验证与校准
确保模型反映现实的关键步骤:
参数敏感性分析:系统性地改变输入参数,观察输出变化
- 使用行为空间工具进行批量实验
experiment "sensitivity-analysis" ["infection-rate" 0.05 0.3 0.05] ["recovery-rate" 0.01 0.2 0.02] repeat 10 [ go ] metrics ["peak-infected"]现实数据对比:将模拟曲线与真实疫情数据叠加
- 调整参数使峰值时间和高度匹配
稳定性测试:多次运行检查结果的随机波动范围
7. 教学与科研应用建议
在实际项目中使用此模型时:
- 课堂演示:逐步展示不同R0值的影响,直观解释"群体免疫"概念
- 研究扩展:
- 添加年龄结构(不同年龄组的易感性和接触率)
- 引入空间异质性(城市vs农村)
- 模拟多种病毒株竞争
- 政策评估:测试不同干预策略的组合效果
; 示例:多病毒株实现 turtles-own [ strain ; 病毒株类型 immunity ; 对各株的免疫力 ]模型的一个常见问题是初期随机爆发可能很快熄灭。解决方法是在setup时设置至少5个初始感染集群:
; 替换原来的初始感染设置 repeat 5 [ let patient one-of turtles ask patient [ set status "infected" set color red set days-infected 0 ] ask turtles in-radius 3 [ ; 创建小规模聚集感染 if random-float 1 < 0.7 [ set status "infected" set color red set days-infected 0 ] ] ]通过这个完整的NetLogo实现,您不仅掌握了病毒传播建模的技术细节,更获得了将理论模型转化为可操作模拟器的能力。这种技能可以轻松迁移到其他复杂系统的建模中,从社交网络信息传播到生态系统能量流动,多主体建模为我们理解复杂世界提供了独特视角。
