Jacky Gu

用NetLogo为Covid-19大流行建模 - 看看与实际相差多远?

05 Sep 2023 Share to

1. 为什么做Covid-19模型?

Covid-19似乎已经与我们远去,但过去两年半来,这场全球大流行病给我们带来了巨大的冲击,其影响将长期延续。新冠病毒的出现改变了我们的生活方式、经济格局和全球卫生安全的认识。尽管疫苗的开发和广泛接种取得了一定的进展,但全球范围内仍然存在着新冠病毒的传播和感染风险。

未来,新冠病毒是否会再次出现是一个令人关注的问题。由于病毒的变异性和传染性,无法完全排除新的变种或突发疫情的可能性。科学家、医疗专家和政府机构都在持续研究和监测新冠病毒的发展,以便及时采取措施来预防和控制潜在的疫情爆发。

三天前,我找到了NetLogo这个用于生物学,社会学,经济学等领域的建模软件,然后花了一天时间学习使用和编程。学习这个软件的目的是为了尝试通过建模方式,研究加密货币市场中的交易者行为,并试图用这种新的方法论来建立加密货币的价格模型。设计完模型架构后,发现这个模型的复杂度相当高,作为一个NetLogo新手,很难驾驭,所以试着找到一个较为简单的模型来练练手。

Covid-19是一个非常典型的多主体模型(Agent-based modeling - ABM)复杂模型,而NetLogo正是一个广泛用于建立、模拟复杂系统的工具。使用NetLogo来为Covid-19建模,可以帮助我们更好地理解病毒传播的动态过程、影响因素和应对策略。通过建立模型并进行模拟实验,我们可以探索不同的假设和策略,评估它们在控制疫情和减轻影响方面的效果。

2. 模型展示

先看几个模型的模拟图,来了解下这个模型将要解决什么问题。 上图显示在146天内,与感染者接触后感染率80%,康复期为10天,康复后免疫期为90天时的感染率模拟图,显示高峰期约在76天,无人死亡。红色小人是感染者。

上图显示在231天内,与感染者接触后感染率100%,康复期21天,康复后免疫期为50天时的感染率模拟图,显示出现两个高峰,一个高峰在第64天,另一个在166天,并有60人死亡。红色小人是感染者。

3. 建模过程

3.1. 建模参数

在这个模型中,我设了四个参数,分别是:

  • population: 即人口密度,取值范围0~5000
  • infectiousness: 感染率,即当正常人遇到一个感染者时,被感染的概率,取值范围0~100,代表0%~100%
  • recover-days: 即接受治疗后,多少天可以康复,取值范围0~100天
  • immunitydays: 在康复后,获得免疫力的天数,过了这个免疫期,如果再次遇到感染者,会第二次被感染

3.2. 输出结果

输出的结果有两个:

  • %infection: 即感染率,感染率的计算方式:
    set %infection (count turtles with [color = red] / count turtles) * 100
    

    上述代码意思是感染人群(count turtles with [color = red])数量占总人群(count turtles)的比例。

  • died: 死亡人数,计算方式:
    ask n-of (count turtles with [color = red] * 0.001) turtles with [color = red] [
      set died died + 1
      die
    ]
    

    上面代码中0.001是死亡率,在这里指0.1%。上述代码意思是指在感染人群([color = red])按死亡率随机选择n个患者,设为die,并将died加1

3.3. 程序详解

3.3.1. 全局变量,包括三个:
globals [
  %infection
  died
  max-ticks
]
3.3.2. 人的属性,有两个,用于记录感染和康复的时间。在这里,时间用ticks表示
turtles-own [
  infected-tick
  recovered-tick
]
3.3.3. 初始化
to setup
  clear-all
  reset-ticks
  ask patches [set pcolor white]  ;;设置背景
  create-turtles population [     ;;创建人,数量为population参数
    set shape "person"            ;;设置为人的形状
    set color green               ;;将健康人设为绿色
    set recovered-tick 0          ;;将康复时间设为0
    setxy random-xcor random-ycor ;;随机将人放在不同位置
  ]
  ask n-of 1 turtles [            ;;随机确定一个人为0号感染者,如果需要设置多个,将1改为相应数量
    set color red                 ;;将感染者设为红色
    set infected-tick ticks       ;;设置感染时间ticks
  ]
  set %infection (count turtles with [color = red] / count turtles) * 100	;;计算感染率
  set max-ticks 1000              ;;设置模型最多天数为1000天
end
3.3.4. 每一步执行的程序
to go
  if ticks >= max-ticks or %infection = 0 [stop]    ;;如果感染率为0,或者达到最大ticks时,停止模型
  tick                                              ;;前进一天
  
  ;;随机游走1步,相当于人与人的随机接触
  ask turtles [
    rt random 180 
    lt random 180
    fd 1
  ]

  ask turtles with [color = red] [
    ask other turtles-here with [color = green] [   ;;在同一地区,遇到健康的人
      if random 100 < %infectiousness and           ;;如果随机数小于感染率,并且没有康复过,或者康复过,但是已过康复后免疫期,则被感染
			(recovered-tick = 0 or recovered-tick + immunitydays < ticks) [
        set color red                               ;;设为感染状态-红色
        set infected-tick ticks                     ;;设置感染时间为当下ticks
        set recovered-tick 0                        ;;设置感染后康复时间为0
      ]
    ]
    
    if infected-tick + recover-days < ticks [       ;;如果感染后一段时间后,康复
      set color green                               ;;设为康复状态-绿色
      set infected-tick max-ticks                   ;;设感染时间为最大值
      set recovered-tick ticks                      ;;设置康复时间为当下ticks
    ]
  ]
  
  ;;判断是否死亡,见3.2
  ask n-of (count turtles with [color = red] * 0.001) turtles with [color = red] [
    set died died + 1
    die
  ]
  
  set %infection (count turtles with [color = red] / count turtles) * 100
end

3.4. 组件设计

见上图红色框中的组件,在这个模型中,我建了10个组件,分别是:

  • 按钮
    • setup 初始化
    • go 循环执行一步
  • 滚动条Slider
    • population
    • %infectiousness
    • recover-days
    • immunitydays
  • 监视器
    • %infection 感染率
    • died 死亡人数
  • 图表 plot
    • Infection 感染率曲线图
    • Died 死亡人数曲线

4. 不同参数模拟

下面我将不同参数下得到的模型结果列在下面,为方便起见,只显示监控器和图标。另外,每组参数都会进行三个模拟,所以会有三个图片:

人口密度 感染率 康复天数 免疫期天数 感染率曲线#1 感染率曲线#2 感染率曲线#3 死亡人数
500 80% 14 90 0/0/0
800 100% 21 60 0/0/0
1000 67% 21 90 0/0/0
2000 67% 14 90 0/0/0
2000 100% 21 60 11/0/0
5000 80% 21 90 70/71/73
5000 100% 14 60 43/45/46
2000 100% 21 30 182/196/208

5. 结论

我不是医学专家,以上只是从数学建模方式提供一些数据参考,作为学习NetLogo的一个案例。

上述模型源码下载地址