C# 版本 疫情传播仿真程序

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 版本 疫情传播仿真程序相关的知识,希望对你有一定的参考价值。

前言

前一阵子看到有人制作了《疫情传播仿真程序》,是用 Java做的。里面根据多种实际情况,如居民移动意愿、医护能力、病毒传播能力,来模拟疫情的发展。看完之后,我暗暗称奇,特别是结合一些视频和照片,确实做得非常好。

既然有需要, 26那天晚上我决定说干就干,经过两个晚上的思考与编码,已经有了初步效果……运行效果如下:

这个效果可以这样解读,如果不加以任何控制,疫情会很快蔓延到整个城市,只有 8:1000床位的城市,将很快失去控制,一年后运行效果如下(非常惨烈):

C# 版本 疫情传播仿真程序

参数与使用

代码中实际有很多参数可以操作:

 
   
   
 
  1. static double MoveWilling = 0.90f; // 移动意愿,0-1

  2. static bool WearMask = false; // 是否戴口罩

  3. static int HospitalBeds = 40; // 床位数


  4. const float InffectRate = 0.8f; // 靠得够近时,被携带者感染的机率

  5. const float SecondsPerDay = 0.3f; // 模拟器的秒数,对应真实一天

  6. const float MovingDistancePerDay = 10.0f; // 每天移动距离

  7. const int InitialInfectorCount = 5; // 最初感染者数

  8. const double DeathRate = 0.021; // 死亡率


  9. // 要靠多近,才会触发感染验证

  10. static float SafeDistance() => WearMask ? 1.5f : 3.5f;


  11. // 住院治愈时间,最短5天,最长12.75天,平均约7天

  12. static float GenerateCureDays() => random.NextFloat(5, 12.75f);

  13. // 潜伏期,1-14天

  14. static float GenerateShadowDays() => random.Next(1, 14);

  15. // 发病后,就医时间,0-3天

  16. static float GenerateToHospitalDays() => random.Next(0, 3);

由于参数太多,很难在运行时全部都做调整,我选取了是否戴口罩、移动意愿、医院床数作为参数,代码如下:

 
   
   
 
  1. protected override void OnKeyPress(KeyPressEventArgs e)

  2. {

  3. switch (e.KeyChar)

  4. {

  5. case '1': MoveWilling = 0.10f; break;

  6. case '2': MoveWilling = 0.50f; break;

  7. case '3': MoveWilling = 0.90f; break;

  8. case 'M': WearMask = !WearMask; break;

  9. case 'A': HospitalBeds += 40; break;

  10. case 'D': HospitalBeds -= 40; break;

  11. case 'R':

  12. {

  13. if (MessageBox.Show("要重来吗?", "确认", MessageBoxButtons.YesNo) == DialogResult.Yes)

  14. {

  15. City = City.Create();

  16. }

  17. break;

  18. }

  19. }

  20. }

其中,按数字键 1、 2、 3可以指定不同的移动意愿,其中 1表示居民最不愿意出门, 3表示最愿意,按 M可以控制居民是否能戴上口罩,按 A可以添加医院可接纳病人数。

一些演示

超多床位

这里我将床位调成 240个(比例为 481000):

 
   
   
 
  1. static int HospitalBeds = 240; // 床位数

也可以运行时增加床位,按键盘 A即可(不用改代码),运行效果如下: 

C# 版本 疫情传播仿真程序

可见床位变多后,死亡率会降低,治愈人数大大提高,但仍然无法控制住疫情的发展。

“理想”情况1·没有潜伏期

可以这样配置:

 
   
   
 
  1. // 0潜伏期

  2. static float GenerateShadowDays() => 0;

运行效果如下: 

C# 版本 疫情传播仿真程序

可见就算潜伏期为 0,由于没有及时就医,疫情仍会失去控制。

“理想”情况2·没有潜伏期、且立刻隔离就医

像那个 Java版中,会先介绍一个“理想”情况,即感染即发病,发病即就就医。此种模型的参数,可以这样配置:

 
   
   
 
  1. // 0潜伏期

  2. static float GenerateShadowDays() => 0;

  3. // 发病后,立即就医。

  4. static float GenerateToHospitalDays() => 0;

在这种情况下,运行效果如下: 

C# 版本 疫情传播仿真程序

可见,由最初的 5人,最终只感染了 6人,理想情况下局势很快就被控制。当然这种情况是不存在的。

戴口罩出门

假如居民都戴口罩出门,可以用如下配置(也可以运行时按下 M键):

 
   
   
 
  1. static bool WearMask = true; // 一定戴口罩

运行效果如下: 

C# 版本 疫情传播仿真程序

坚持了 107天,疫情发展速度大大降低,但由于医疗资源的匮乏,死亡率仍然居高不下,最终仍会失去控制。

居民呆在家中不出门,且戴口罩

配置如下:

 
   
   
 
  1. static bool WearMask = true; // 一定戴口罩

  2. static double MoveWilling = 0.10f; // 每天只有10%的人愿意出门

运行效果如下: 

C# 版本 疫情传播仿真程序

病毒在最初的 5人身上,只感染了 2人。效率可谓惊人。

模拟现实模型

我想贴近现实,模拟一些现实情况,然后看看效果如何,我的脚本如下:

  1. 前 20天,不作任何控制

  2. 第 20天,全民戴口罩,移动意愿降低至 50%,床位增加 40个(模拟进入重大突发公共卫生事件Ⅰ级响应)

  3. 第 25天,移动愿意降低至 10%,床位增加 80个(模拟火神山医院)

  4. 第 30天,床位再增加 80个,共 240个(模拟雷神山医院)

为了尽可能短地截取 gif,我将时间缩短了,真实时间可能会和这个比例为 1:2(也就是相当于前 40天不作任何控制),脚本如下:

 
   
   
 
  1. void StepDay()

  2. {

  3. if (day < 20)

  4. {

  5. WearMask = false;

  6. MoveWilling = 0.9;

  7. HospitalBeds = 40;

  8. }

  9. if (day >= 20)

  10. {

  11. WearMask = true;

  12. MoveWilling = 0.5;

  13. HospitalBeds = 80;

  14. }

  15. if (day >= 25)

  16. {

  17. MoveWilling = 0.1;

  18. HospitalBeds = 160;

  19. }

  20. if (day >= 30)

  21. {

  22. HospitalBeds = 240;

  23. }


  24. // 其它代码

  25. }

运行效果如下: 

C# 版本 疫情传播仿真程序

可见这真是与病毒的一部史诗级斗争。

前 20天,没有任何控制,病毒疯狂肆虐,前期只花了 9天,就把医院给挤满了;

第 20之后,居民带上口罩,传播进度迅速下降,但由于潜伏期较长,发病人数仍然持续上升;

第 30天之后,由于 5天前床位(医护资源)的跟进,发病人数增速降低;

第 35天后,发病人数开始下降;

第 68天后,除了医院中的病人,城市中已经没有病人;

第 78天,已经没有被病毒感染的人了。

总结

所有这些代码,我都上传到了我的博客数据网站,各们可以下载代码,通过 LINQPad6直接模拟运行,或者拷到 VisualStudio中亦可。各位也可以或者提出您的想法, Github链接如下:https://github.com/sdcb/blog-data/tree/master/2020/20200207-2019-ncov-simulate

写完这个东西,给我最大的感受就是震撼,模拟起来就是一些数据而已,但背后是千千万万有血有肉的病人和医务工作者,向那些伟大的“逆行者”们致敬!

从上面的数据也可以看出,任何单项指标做好,都是不能完全阻止疫情的。我们要相互信任,做好自己。我们能做的有:尽可能呆在家,别出门,就真是对国家最好的贡献;出门一定要戴口罩,这样可以明显降低感染率。

最后,在新的一年里,祝大家阖家欢乐,鼠年大吉!

以上是关于C# 版本 疫情传播仿真程序的主要内容,如果未能解决你的问题,请参考以下文章

毕设题目:Matlab元胞自动机病毒仿真

编程资讯 | 计算机仿真程序告诉你,为什么现在还不能出门!

面向新冠疫情的数据可视化分析与模拟预测

C#程序员经常用到的10个实用代码片段 - 操作系统

C#程序员经常用到的10个实用代码片段

控疫手段不可松懈,北大面向新冠疫情的数据可视化分析与模拟预测