小编说:本文由博文视点一位身在武汉的作者龙中华老师,根据Ele实验室发布的“疫情传播仿真程序”视频以及其开源代码整理编辑而成*,*首发于个人博客:
https://blog.csdn.net/u013840066/article/details/104212919

前几天,“Ele实验室” Bruce Young同学在家制作了一个有关病毒传播的仿真程序(https://www.bilibili.com/video/av86478875),为我们带来了极大的视角上的震撼,对于人们认识病毒传播有很大的价值,于是这里把源代码分享出来(版权归Bruce Young同学),因为该程序实际上没有实际的商用价值(有很大的传播教育价值),所以我们只做一些简单的讲解。

视频中程序代码GitHub开源链接:

https://github.com/KikiLetGo/VirusBroadcast/tree/master/src

下面我们进入正题,运行效果图如下图所示:

该程序主要使用Swing( 一个为Java设计的GUI工具包)来绘制图形用户界面(GUI)。实现的步骤如下:

创建Point 类

该类用于定义绘制图形界面上的点,代码如下:

public class Point { private int x; private int y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}}

创建常量类

该类用于调整参数来展现不同的效果,见下方代码:

public class Constants { //初始感染数量 public static int ORIGINAL_COUNT=50; //传播率 public static float BROAD_RATE = 0.8f; //潜伏时间 public static float SHADOW_TIME = 140; //医院收治响应时间 9    public static int HOSPITAL_RECEIVE_TIME=10;//医院床位public static int BED_COUNT=1000;//流动意向平均值public static float u=-0.99f;14}

创建城市类

该类用于定义一个城市。

  public class City { private int centerX; private int centerY; public City(int centerX, int centerY) { this.centerX = centerX; this.centerY = centerY; } public int getCenterX() {return centerX;}public void setCenterX(int centerX) {this.centerX = centerX;}public int getCenterY() {return centerY;}public void setCenterY(int centerY) {this.centerY = centerY;}}

创建医院类

该类用于创建一个演示的医院类。

  public class Hospital { private int x=800; private int y=110; private int width; private int height=606; public int getWidth() { return width; } public int getHeight() {return height;}public int getX() {return x;}public int getY() {return y;}private static Hospital hospital = new Hospital();public static Hospital getInstance(){return hospital;}private Point point = new Point(800,100);private List<Bed> beds = new ArrayList<>();private Hospital() {if(Constants.BED_COUNT==0){width=0;height=0;}int column = Constants.BED_COUNT/100;width = column*6;for(int i=0;i<column;i  ){for(int j=10;j<=610;j =6){Bed bed = new Bed(point.getX() i*6,point.getY() j);beds.add(bed);}}}public Bed pickBed(){for(Bed bed:beds){if(bed.isEmpty()){return bed;}}return null;}}

创建医院的床位类

该类创建一个用于演示的医院的病床类。

  public class Bed extends Point{public Bed(int x, int y) { super(x, y); } private boolean isEmpty=true; public boolean isEmpty() { return isEmpty; }public void setEmpty(boolean empty) {isEmpty = empty;}}

创建PersonPool类

该类创建PersonPool,用于管理城市大小和人数。

  public class PersonPool { private static PersonPool personPool = new PersonPool(); public static PersonPool getInstance(){ return personPool; } List<Person> personList = new ArrayList<Person>(); public List<Person> getPersonList() {return personList;}private PersonPool() {City city = new City(400,400);for (int i = 0; i < 5000; i  ) {Random random = new Random();int x = (int) (100 * random.nextGaussian()   city.getCenterX());int y = (int) (100 * random.nextGaussian()   city.getCenterY());if(x>700){x=700;}Person person = new Person(city,x,y);personList.add(person);}}}

创建Person类

  public class Person {  private City city;  private int x;  private int y;  private MoveTarget moveTarget;  int sig=1;  double targetXU; double targetYU; double targetSig=50; public interface State{ int NORMAL = 0; int SUSPECTED = NORMAL 1; int SHADOW = SUSPECTED 1; int CONFIRMED = SHADOW 1; int FREEZE = CONFIRMED 1; int CURED = FREEZE 1; } public Person(City city, int x, int y) { this.city = city; this.x = x; this.y = y; targetXU = 100*new Random().nextGaussian() x;targetYU = 100*new Random().nextGaussian() y; } public boolean wantMove(){         double value = sig*new Random().nextGaussian() Constants.u; return value>0; } private int state=State.NORMAL; public int getState() { return state; } public void setState(int state) { this.state = state; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } int infectedTime=0; int confirmedTime=0; public boolean isInfected(){ return state>=State.SHADOW; } public void beInfected(){ state = State.SHADOW; infectedTime=MyPanel.worldTime; } public double distance(Person person){ return Math.sqrt(Math.pow(x-person.getX(),2) Math.pow(y-person.getY(),2)); } private void freezy(){ state = State.FREEZE; } private void moveTo(int x,int y){ this.x =x; this.y =y; } private void action(){ if(state==State.FREEZE){ return; } if(!wantMove()){ return; } if(moveTarget==null||moveTarget.isArrived()){ double targetX = targetSig*new Random().nextGaussian() targetXU;             double targetY = targetSig*new Random().nextGaussian() targetYU; moveTarget = new MoveTarget((int)targetX,(int)targetY); } int dX = moveTarget.getX()-x;int dY = moveTarget.getY()-y;double length=Math.sqrt(Math.pow(dX,2) Math.pow(dY,2));if(length<1){moveTarget.setArrived(true);return;}int udX = (int) (dX/length);if(udX==0&&dX!=0){if(dX>0){udX=1;}else{udX=-1;}}int udY = (int) (dY/length);if(udY==0&&udY!=0){if(dY>0){udY=1;}else{udY=-1;121            }}if(x>700){moveTarget=null;if(udX>0){udX=-udX;}}moveTo(udX,udY);//        if(wantMove()){//        }}private float SAFE_DIST = 2f;public void update(){//@TODO找时间改为状态机142        if(state>=State.FREEZE){return;}if(state==State.CONFIRMED&&MyPanel.worldTime-confirmedTime>=Constants.HOSPITAL_RECEIVE_TIME){Bed bed = Hospital.getInstance().pickBed();if(bed==null){System.out.println("隔离区没有空床位");}else{state=State.FREEZE;x=bed.getX();y=bed.getY();bed.setEmpty(false);}}if(MyPanel.worldTime-infectedTime>Constants.SHADOW_TIME&&state==State.SHADOW){state=State.CONFIRMED;confirmedTime = MyPanel.worldTime;}action();List<Person> people = PersonPool.getInstance().personList;if(state>=State.SHADOW){return;166        }for(Person person:people){if(person.getState()== State.NORMAL){continue;}float random = new Random().nextFloat();if(random<Constants.BROAD_RATE&&distance(person)<SAFE_DIST){this.beInfected();}}}}

创建MyPanel类

public class MyPanel extends JPanel implements Runnable { private int pIndex=0; public MyPanel() { this.setBackground(new Color(0x444444)); } @Overridepublic void paint(Graphics arg0) {super.paint(arg0);//draw borderarg0.setColor(new Color(0x00ff00));arg0.drawRect(Hospital.getInstance().getX(),Hospital.getInstance().getY(),Hospital.getInstance().getWidth(),Hospital.getInstance().getHeight());List<Person> people = PersonPool.getInstance().getPersonList();if(people==null){return;}people.get(pIndex).update();for(Person person:people){switch (person.getState()){case Person.State.NORMAL:{arg0.setColor(new Color(0xdddddd));}break;case Person.State.SHADOW:{arg0.setColor(new Color(0xffee00));}break;case Person.State.CONFIRMED:case Person.State.FREEZE:{arg0.setColor(new Color(0xff0000));}break;}person.update();arg0.fillOval(person.getX(), person.getY(), 3, 3);}pIndex  ;if(pIndex>=people.size()){pIndex=0;}}public static int worldTime=0;@Overridepublic void run() {while (true) {5657            this.repaint();5859            try {Thread.sleep(100);worldTime  ;} catch (InterruptedException e) {e.printStackTrace();}}}}

创建MoveTarget 类

创建MoveTarget 类用于模拟人群流动。

 public class MoveTarget { private int x; private int y; private boolean arrived=false; public MoveTarget(int x, int y) { this.x = x; this.y = y; }public int getX() {return x;}public void setX(int x) {this.x = x;17    }public int getY() {return y;}public void setY(int y) {this.y = y;}public boolean isArrived() {return arrived;}public void setArrived(boolean arrived) {this.arrived = arrived;}}

修改入口类

修改入口类,绘制图形

  import javax.swing.*; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import java.util.Random; public class Main { public static void main(String[] args) { MyPanel p = new MyPanel();Thread panelThread = new Thread(p);JFrame frame = new JFrame();frame.add(p);frame.setSize(1000, 800);frame.setLocationRelativeTo(null);frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);panelThread.start();List<Person> people = PersonPool.getInstance().getPersonList();for(int i=0;i<Constants.ORIGINAL_COUNT;i  ){int index = new Random().nextInt(people.size()-1);Person person = people.get(index);while (person.isInfected()){index = new Random().nextInt(people.size()-1);person = people.get(index);}person.beInfected();}}}

到此完成,运行程序即可。

图书推荐

《Spring Boot实战派》

龙中华 著

  • 让开发像搭积木一样简单,在实战情景中学习,学完即知怎么实战

版本点新 针对 Spring Boot 2.0 及以上版本

体例科学 用“知识点 实例”形式编写

实例丰富 58个基础实例 2个综合项目

对比选优 对比讲解多种同类技术,便于技术选型,如 Spring Security 和 Shiro、Elasticsearch 和 Solr、JPA 和 Mybatis

技术点新 讲解了时下流行的接口架构风格 RESTful 、用来实现高并发的 Redis 、以及用来实现系统间通信的中间件 RabbitMQ

关于作者

龙中华

12年来一直在某一线互联网公司担任资深系统分析师。

目前带领3个研发团队,承担系统的分析、设计、实施、演进,以及技术团队管理和培训等职责。有独到的团队建设和管理经验,对互联网多种技术特点和发展趋势有较深入的研究,对多种技术(如 Spring Boot 、Spring Cloud 和 Service Mesh )有深入的研究和实战经验。


扫码了解本书详情

Java丨Ele实验室“疫情传播仿真程序”的代码实现相关推荐

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

    前言 前一阵子看到有人制作了<疫情传播仿真程序>,是用 Java做的.里面根据多种实际情况,如居民移动意愿.医护能力.病毒传播能力,来模拟疫情的发展.看完之后,我暗暗称奇,特别是结合一些视 ...

  2. Unity3D疫情传播模拟器完整代码

    UI数据面板 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEng ...

  3. 手把手教你用C#做疫情传播仿真

    手把手教你用C#做疫情传播仿真 在上篇文章中,我介绍了用 C#做的疫情传播仿真程序的使用和配置,演示了其运行效果,但没有着重讲其中的代码. 今天我将抽丝剥茧,手把手分析程序的架构,以及妙趣横生的细节. ...

  4. JAVA巢院小区疫情管控系统计算机毕业设计Mybatis+系统+数据库+调试部署

    JAVA巢院小区疫情管控系统计算机毕业设计Mybatis+系统+数据库+调试部署 JAVA巢院小区疫情管控系统计算机毕业设计Mybatis+系统+数据库+调试部署 本源码技术栈: 项目架构:B/S架构 ...

  5. R语言模拟疫情传播-gganimate包

    本文用gganimate包展示模拟疫情数据 本文篇幅较长,分为以下几个部分: 前言 效果展示 小结 附录:代码 前言 前文<R语言模拟疫情传播-RVirusBroadcast>已经介绍了一 ...

  6. JAVA毕业设计开放式实验室预约系统计算机源码+lw文档+系统+调试部署+数据库

    JAVA毕业设计开放式实验室预约系统计算机源码+lw文档+系统+调试部署+数据库 JAVA毕业设计开放式实验室预约系统计算机源码+lw文档+系统+调试部署+数据库 本源码技术栈: 项目架构:B/S架构 ...

  7. java计算机毕业设计实验室耗材管理系统源程序+mysql+系统+lw文档+远程调试

    java计算机毕业设计实验室耗材管理系统源程序+mysql+系统+lw文档+远程调试 java计算机毕业设计实验室耗材管理系统源程序+mysql+系统+lw文档+远程调试 本源码技术栈: 项目架构:B ...

  8. JAVA计算机毕业设计实验室耗材管理系统源码+系统+mysql数据库+lw文档

    JAVA计算机毕业设计实验室耗材管理系统源码+系统+mysql数据库+lw文档 JAVA计算机毕业设计实验室耗材管理系统源码+系统+mysql数据库+lw文档 本源码技术栈: 项目架构:B/S架构 开 ...

  9. java计算机毕业设计校园疫情防控管理软件源码+数据库+系统+lw文档+部署

    java计算机毕业设计校园疫情防控管理软件源码+数据库+系统+lw文档+部署 java计算机毕业设计校园疫情防控管理软件源码+数据库+系统+lw文档+部署 本源码技术栈: 项目架构:B/S架构 开发语 ...

  10. JAVA毕业设计web实验室课表管理系统计算机源码+lw文档+系统+调试部署+数据库

    JAVA毕业设计web实验室课表管理系统计算机源码+lw文档+系统+调试部署+数据库 JAVA毕业设计web实验室课表管理系统计算机源码+lw文档+系统+调试部署+数据库 本源码技术栈: 项目架构:B ...

最新文章

  1. HDU1213How Many Tables
  2. nginx.conf 配置详解
  3. 电脑 Google浏览器 截长屏 无任何辅助软件
  4. 嵌入式开发比单片机开发难?
  5. Shell 教程 - 菜鸟教程
  6. 【活动报名】1024,一起过节,一起品网易/美团/贝壳/PingCAP/爱奇艺云原生实践干货!
  7. 基于单片机的音乐盒系统设计(#0435)
  8. quartz mysql表文件_spring boot+Quartz+数据库存储
  9. 【IoT】STM32 文件系统 fatfs 移植笔记详解
  10. 解决Minimum supported Gradle version is 4.6. Current version is
  11. 鲸探发布点评:7月7日发售陈孟昕系列绘画数字藏品
  12. godaddy mysql不存在_Godaddy免费空间问题及解决方案总结
  13. egpu+mac+bootcamp
  14. C语言数据的输入输出
  15. 关于C#操作Word时的版本问题
  16. 美颜sdk磨皮算法代码解析
  17. java tr合并单元格_java poi合并单元格问题
  18. 【GamePlay】两个ScrollView插件,Super ScrollView UIExtensions
  19. Google Cloud 技术矩阵,全栈赋能4大游戏品类
  20. html网页打开慢的解决方法,网页打开慢怎么办 影响网页打开速度因素有哪些【解决方法】...

热门文章

  1. scrapy_全站爬取
  2. solr6.5的分词
  3. 设置EntityFramework中decimal类型数据精度
  4. 在虚拟机中配置FastDFS+Nginx模块
  5. 巧用 Class Extension 隐藏属性
  6. Keyboard项目中观察者模式解析
  7. C# Linq to sql 实现 group by 统计多字段 返回多字段
  8. jabc spring
  9. NIS 报错No such map passwd.byname. Reason: Can't bind to server which serves this domain
  10. 动态规划 钢条切割问题