飞道的博客

疫情肆虐下,程序员用代码告诉你为什么千万不要出门!

286人阅读  评论(0)

这两天,一个视频火了起来。

视频地址:

https://www.bilibili.com/video/av86478875/

这是一个使用 Java 语言编写的肺炎仿真程序,从统计学的角度来说,能够从一定程度上模拟新冠肺炎病毒扩散及被控制的趋势。

现在,作者已经将代码开源到 GitHub 上,笔者特此 download 下来与诸君分享。

GitHub 地址:

https://github.com/KikiLetGo/VirusBroadcast

在代码中,我们假定一个城市是一个 600 x 600 的正方型。在这个城市中,每一个人为一个 3*3 大小的圆形的点。在每一个城市中,人口所在位置在统计学上都有相应的规律。在这里,假定城市中有 5000 个人,这 5000 个人以城市中心按照正态分布的方式,随机地分布在城市的各个角落。

城市中人口正态分布情况

代码如下:


   
  1. Random random =  new Random();
  2. int x = ( int) ( 100 * random.nextGaussian() + city.getCenterX());
  3. int y = ( int) ( 100 * random.nextGaussian() + city.getCenterY());
  4. Person person =  new Person(city, x, y);

在新型肺炎期间,根据肺炎的信息,我们可以知道,病毒存在潜伏期,医院会对患者进行收治。本文中我们对每一个人的状态进行简化,分为以下四个状态:

  • 正常

  • 潜伏期

  • 确诊

  • 在医院治疗中

其中三个状态中,人是可以自由活动的,当然,关于人的移动,此处的处理逻辑也是简化为一个正态分布的随机移动。以下代码为人随机移动到的目的地的位置:


   
  1. // 根据流动意愿计算当前人是否需要流动
  2. public boolean wantMove() {
  3.    double value = sig *  new Random().nextGaussian() + Constants.u;
  4.     return value >  0;
  5. }
  6. // 计算人流动到的目标位置
  7. double targetX = targetSig *  new Random().nextGaussian() + targetXU;
  8. double targetY = targetSig *  new Random().nextGaussian() + targetYU;
  9. moveTarget =  new MoveTarget(( int) targetX, ( int) targetY);

除了处理分配位置和随机移动,还有一个被感染的函数。当我们在城市中移动的时候,当周围的人存在携带病毒的人,我们就有一定的概率被感染,以下代码描述了这个过程:


   
  1. float random =  new Random().nextFloat();
  2. if (random < Constants.BROAD_RATE && distance(person) < SAFE_DIST) {
  3.   this.beInfected();
  4. }

当然,医院和国家的响应,会让我们在感染数上升的同时,避免外出,所以在计算人移动的过程中,添加一个辅助变量来表示人外出移动的意愿,随着感染数的上升,人们的移动意愿就会逐渐降低,为了简化程序,笔者在此添加了一个线性变化的流动意愿修改。随着床位被占据得越来越多,人们的流动意愿就越来越低。


   
  1. public  int usedBed() {
  2.    int result =  0;
  3.    for (Bed bed : beds) {
  4.      if (!bed.isEmpty()) {
  5.       result++;
  6.     }
  7.   }
  8.    return result;
  9. }
  10. // 更新流动意向
  11. public void updateU() {
  12.    int subCount = Constants.BED_COUNT /  5;
  13.    int used = usedBed();
  14.    if (used > subCount) {
  15.     Constants.u =  -0.99f;
  16.   }
  17.   float mu =  1.98f * used / subCount;
  18.   Constants.u =  0.99f - mu;
  19. }

下列动图就是从最开始很小一部分感染群体在不断地流动中所带来的大规模扩散模拟,当政府进行管控,外出人员大幅减少之后,整个疫情得到了有效的控制的演示,我们可以明确地得出一个结论,那就是「不出门、不串门」是非常行之有效的举措。正如 UP 主在视频最后所说的那句话 —— 「对本次疫情起到主导作用的,恰恰就是我们普普通通的每一个人」。

 


转载:https://blog.csdn.net/csdnnews/article/details/104191358
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场