干货 | 手把手教你用AnyLogic实现武汉疫情的高级模型
文案代码 向柯玮
”
审核校对 邓发珩
前言
经过上次AnyLogic的简单介绍,大家都反应还不够,想看更高级
的。
向来宠各位伙伴的小玮当然会满足大家的要求,这次给大家带来上次武汉疫情的加强版本
。
经过本篇推文,你就可以做出上面的模型~
那么废话不多说,我们进入今天的主要内容。
本次参数
本次模型的参数较多,在这里直接给出,数据并不严谨。
- 总人口:9000000人
- 规避系数:0.1
- 隔离率:0.1
- 接触人数:50人
- 患者接触感染率:0.01
- 潜伏者接触感染率:0.05
- 就诊率:0.5
- 潜伏期:10天
- 患病周期:5天
- 院内治愈率:0.95
- 院外治愈率:0.8
- 患者接触人数:接触人数*(1-规避系数)
- 初始感染者:2000
- 易感染者:总人口-2000
- 病毒携带者:1000
- 暴露人群:500
- 家庭隔离者:500
- 入院患者,院内治愈者,院内死亡者,院外治愈者,院外死亡者。
正式步骤
好了,参数部分我们已经先明确了,下面我们开始今天的正式步骤。
主要分为三个部分:运行状态图,初始化图和再美化。
运动状态图
首先,打开我们的AnyLogic,新建一个模型,选择工具栏中的系统动力学。
拖动一个存量出来,然后按住Ctrl,用鼠标左键拖动存量,生成9个存量,并命名。
存量的作用类似于一个容器,把水存在里面,接下来,我们会用到叫做流量的工具,它就类似于水管的作用。
它可以使不同存量之间建立起联系。现在我们拖动流量,让存量连接起来。然后对每个流量进行命名。
在这里我们暂时不要让暴露人群和院外治愈,院外死亡联系起来,因为不美观
!在后面我们介绍一种方法,让连线更美观。
然后,我们就需要添加我们的参数了。同样是在系统动力学中,我们把参数拖出来,命名并且赋值。
命名和赋值已经在之前介绍过了,这里就不多加介绍了。
下一步就是给我们的每个存量赋值,让他们与参数进行联系起来。但是在此之前,我们要用到一个叫做动态变量的东西。
这个是什么意思呢?就是我们之前的参数是不是就是赋值一个固定的初始值?而动态变量就是一个变化的值,它是由我们的参数和一定的系数构成。
本题中,我们的动态变量是患者接触人数,且为接触人数*(1-规避系数)。
接下来,我们就是对我们的存量下手了,赋值并与参数建立联系。记住要使不同的存量之间建立起联系,我们要对流量进行赋值。其中的规则本模型设置如下:
- 感染=易感染者*(病毒携带者潜伏者接触感染率接触人数+暴露人群患者接触感染率患者接触人数)/总人口
- 隔离=病毒携带者*隔离率
- 不隔离=病毒携带者*(1-隔离率)
- 去医院=家庭隔离者*就诊率/潜伏期
- 住院=暴露人群*就诊率/潜伏期
- 院外死亡=家庭隔离者*(1-院外治愈率)/患病周期
- 院外治愈=家庭隔离者*院外治愈率/患病周期
- 院内死亡=入院患者*(1-院内治愈率)/患病周期
- 院内治愈=入院患者*(院内治愈率/患病周期
到现在这个位置,我们就可以来解决最开始遗留的问题,暴露人群中可能有院外治愈,和院外死亡啊,那怎么办呢?
在这里AnyLogic给我们提供了一种叫做影子
的东西,我们对影子的各种操作和对本身的操作是一样的
。
右键点击存量就可以选择影子了,拖到合适的地方,然后再拖动流量建立联系即可。
但是我们会看到,在屏幕下方会爆出两个错误。
不用着急,这是因为我们还需要进行一个步骤。我们可以点开这个错误
,然后双击,就会自动移动到错误的位置
。
定位到这个位置以后,我们点击红色的X
就可以看到,是因为我们没有建立链接,单击建立链接就可以了。
最终我们的运动状态图其实已经建立好了,如下。
点击运行,就可以看到效果图了。
当然啦,这还不够酷
,分析图呢?分析图去哪儿啦?找到左侧工具栏的分析区,把我们想要的样表拖出来,把值附上就ok了。
现在给出我们的效果图~
初始化图
好了,第一个部分我们已经圆满完成了,接下来,我们想一想,我们是不是每次想用不同的参数值来运行,都需要重新在Main函数中再一个接一个赋值?我们可不可以每次在程序run了以后的界面更改参数?
你的意思是说,像下面这样?
答案是,当然可以!
回到工程栏,选择当前模型栏中的Simulation:Main,点进去。
在进行接下来的操作之前,我们需要先了解一个小小的概念。
我们这样设置了这个界面,其实就是设置了变量,我们通过更改变量,从而更改相应的参数。那么本次我们的主要内容肯定是围绕变量展开的。
进入Simulation的界面之后,我们先进入智能体中拖出一个变量,然后进入演示中拖出一个文本,最后进入控件中拖出一个编辑框。
我们在这里举一个例子,大家就知道之后的其他参数应该怎么进行操作了。
将文本和变量的名称进行修改,比如改成接触人数。(不修改也可以,修改了便于识别。)
点击链接按钮,选择我们刚刚拖出的变量。之后,点击空白处,看到我们的主属性区的参数。
在接触人数后面,改成我们当前拖出来这个变量的名称,比如说我刚刚把变量名称改成了接触人数,在这里我就应该填上接触人数。
如果我们成功地设置了,前面的参数名称会变成深色。
当然在这里如果我们想设置一个默认初始值,以便于我们不用每次进入程序都把所有参数都重新输入一次,也是可以的。
在相应变量的初始值处设置一个就可以了。好了,我们可以点击一下运行,看看成功了没有。如果出现了下面的界面就说明成功了。
如果我们想要设置随机值的话,我们可以在初始值这个位置填上uniform(x,y),即随机在x-y之间生成一个随机数。
这样设置的话,只是在我们第一次运行这个程序的时候生成一个随机数,而不是每次运行都可以生成一个随机数,后面运行时的初始值都是第一次的随机数,除非我们关闭整个软件。
这里面是为什么,我就不在这里多解释啦,有兴趣的伙伴可以去查一下随机数种子这个概念。
那么我们怎么让程序每次运行都有一个新的随机数呢?
其实很简单,我们来到simulation的界面。
在随机性一栏中选择随机种子,在之后我们每一次运行程序就可以有不同的随机数了。
现在我们就可以依次把所有的参数都按照上面的方式进行操作。(为了美观,我们可以把变量拖到其他地方)
总结一下,就是拖出三个原件,改名,链接,就可以了。
再美化
看到现在我们做的模型,总感觉有些地方做的不够好
。比如说
- 初始化的位置背景不好看
- 在运动状态图的时候,我们总是需要往下面拉,才可以看到分析图
不用着急,接下来,我们对程序进行进一步美化。在演示框中,拖出图像。
我们就可以选择一张图片了,设置适合的大小以后,我们会很失望--因为他覆盖了原来的东西。
不用着急,右键单击图片,选择次序中的置于底层就可以完美解决这个问题了。
那如果我们想给当前界面加一个标题呢?我们需要的工具的位置依然是在演示中,选择矩形。
在我们的界面上方画一个矩形,然后再右侧栏选择填充颜色。
就可以设置好这一个矩形了,然后依然是演示栏,选择文本。
拖到矩形上,输入字,就可以做一个很酷的标题了。如果想要实现这种,应该怎么办呢?
诶,对!就是再拖一个矩形出来,然后右键单击选择次序就可以了。
我们现在解决了第一个问题,那么接下来就是处理第二个问题的时候了。现在我们需要用到的是演示栏中的视图区域工具。
然后利用这个工具,将我们的界面进行区域化。
但是我们还是没有实现跳转的目的,别急。接下来,我们还是拖动一个矩形出来,然后用文本输入两个界面的名称。
然后再在文本的高级选项中的点击时
填上view+视图区域的名称.navigateTo();
。
最后,把这一栏复制到另外一个界面就可以了。
点击运行就可以看到效果了。