疫情模拟
背景
2020开年不顺,我们每个人都亲身经历了一场瘟疫:新冠病毒(COVID-19)。我们大家来尝试用编程的方法去建模,既学习编程和交互设计,也借此了解传染病方面的知识。
主题
“新冠病毒 ”主题的群体行为建模。
技术方案
seir感染模型和unity状态机系统
设计思想
关键技术:
SEIR传染病模型:
该模型一般把传染病流行范围内的人群分成如下几类:
1、S 类,易感者 (Susceptible),指未得病者,但缺乏免疫能力,与感染者接触后容易受到感染;
2、E 类,暴露者(潜伏者) (Exposed),指接触过感染者,但暂无能力传染给其他人的人,对潜伏期长的传染病适用;
3、I 类,感染者 (Infectious),指染上传染病的人,可以传播给 S 类成员,将其变为 E 类或 I 类成员;
4、R 类,康复者 (Recovered),指被隔离或因病愈而具有免疫力的人。
可调节参数说明:
时间流速:控制模型时间的快慢,默认20帧为一天,即现实中20/60秒为模型中的一天。
人数:模型中参与SEIR模拟的人数。
传播源:即初始的病毒携带者数量,具有感染能力。
传播率:病毒每天都会在人群中传播一次,感染者接触易感者时,易感者得病的几率。
潜伏期:易感者得病后不会立即发作,而是变为没有传播能力但是携带病毒的暴露者,当暴露者度过隔离期,会变为感染者;单位为天
流动性:人群活动的量化参数,是一个百分数,默认为100%,即表示所有模拟人群均会出门,且外出的活动范围为最大值的100%。
感染距离:感染者与易感者之间的距离不大于感染距离,易感者才有几率被感染。
隔离容量:指治疗机构能够同时收治的感染者最大值。
痊愈时间:指感染者被治疗机构隔离后,变为康复者所需时间(天)。
隔离响应:指治疗机构收治一名感染者所需的时间(天)。
Unity 枚举机制
使用枚举可以较好地管理人群的状态,并且可以通过枚举状态的改变,同步改变其表现颜色以及统计数据。
代码结构:
Game
Virus类:感染模型输入数据的定义类,向其他类提供用户输入的感染数据。
Space类:为city和hospital的父类,定义疫情模拟空间的一些基本参数
City类:为所有模拟人群生活的主要空间,提供数据初始化以及创建人群的方法。
Hospital类:为感染者被收治后的隔离空间,提供感染者收治以及痊愈的相关方法。
Person类:较关键的类,定义人群的状态,以及状态改变的相关处理。还实现模拟人群的移动功能。
MouseControl类:负责鼠标交互功能
UI
SetPanel类:负责将用户在UI上的输入传给Virus类。
InfoPanel类:负责显示感染模型相关数据(即左侧的实时信息)。
TipsPanel类:负责开始模拟的提示显示。
部分代码
public class City : Space
{
///
/// 城市类
///
//旋转中心
public GameObject cent;
public static City instance;
public static int days=0;
public static bool isBegin = false;
//人数
public List
//医院
public Hospital hospital;
private int nowInfectionNum = 0;
void Awake()
{
instance = this;
//预设的星球范围
centerPoint =cent.transform.position;
Rlength = 120;
}
//创建人数
public void CreatPerson(int num)
{
StartCoroutine(BeginCreat(num));
}
//创建与清除人数的协程(防止卡顿)
public IEnumerator BeginCreat(int num)
{
isBegin = false;
TipsPanel.instance.ShowInfo("数据加载中...");
//初始化床位
days = 0;
hospital.BeginNum(Virus.BED_NUM);
yield return 0;
nowInfectionNum = 0;
//清除人数
for (int i = 0; i < persons.Count; i++)
{
Destroy(persons[i].gameObject);
if (i % 200 == 0)
yield return 0;
}
persons.Clear();
//创建人的预设体
for (int i = 0; i < num; i++)
{
GameObject obj = Instantiate(Resources.Load
obj.transform.parent = this.transform;
obj.transform.localScale = Vector3.one;
obj.transform.localPosition = Vector3.zero;
Person p = obj.GetComponent
persons.Add(p);
//人群初始状态
p.ChangeType(E_Person_Type.Susceptible);
p.ChangeSpace(this);
if (nowInfectionNum < Virus.INFECTION_NUM) {
nowInfectionNum++;
p.ChangeType(E_Person_Type.Infective);
}
if (i % 200 == 0)
yield return 0;
}
TipsPanel.instance.ShowInfo("模拟倒计时:3");
yield return new WaitForSeconds(1f);
TipsPanel.instance.ShowInfo("模拟倒计时:2");
yield return new WaitForSeconds(1f);
TipsPanel.instance.ShowInfo("模拟倒计时:1");
yield return new WaitForSeconds(1f);
TipsPanel.instance.ShowInfo("开始");
//初始化显示
InfoPanel.instance.InitPanel(num);
yield return new WaitForSeconds(1f);
TipsPanel.instance.HideInfo();
isBegin = true;
}
```
模拟不同国家对疫情的应对策略
现在假设每个国家初始的疫情状态都是相同的,即为初始状态。未出现病例14天后假设疫情全部消除
1. 中国
中国在刚开始的时候并未真正了解该疫情,所以假设在疫情开始后的4天左右有所行动,人人有了防范意识即传播率(降低为40)有所下降。第七天左右政府采取更加严厉的措施,此时传播率进一步下降(降为30)流动性大幅下降(封城等措施 ,降为20)同时医疗物资和医护人员赶往疫情爆发地,建立大量的放舱医院,感染距离有所下降(降为30),医院容量大幅提高(提高为80).后期有了经验(治愈时间降为10).
可以看出中国完全控制住疫情大概花了200天的时间
2. 英国
英国奉行群体免疫,由于是发达国家现假设治愈时间从一开始就变为9,隔离容量为100,英国人口流动性没有中国那么大设置为50,,现在来看看英国的表现。
英国完成抗议任务需要600天,期间还包含大量的民众和医护人员的死亡。
3.美国
美国的抗击疫情政策一直比较迷,政府官方和民众好像对此不大上心。甚至还有些许冲突,这里 我们前60天不动,60天后医院床位增加到120,但是人员流动性就美国的时常抗议活动来说设成90吧,美国应对的相应时间自然不如我们这么高设置为8,来看看美国表现。
美国控制住疫情需要更长时间。
由此看出,中国的防疫政策是相当不错的,为 中国的防疫措施和医护人员点赞。