疫情病毒模拟仿真程序的实现

2024-04-13 10:08

本文主要是介绍疫情病毒模拟仿真程序的实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实现的步骤简单介绍:(具体后面贴代码)
1.通过JFrame设计出展示的窗口;
2.添加一个JPanel面板到窗口中
2.1单独创建了MainPanel类通过继承JPanel,重写JPanel中paint(Graphics g)方法,操作绘图
2.2通过实现Rannable接口开启一个线程用于定时重复的绘图(定义一个产生随机数的数学工具类)
3.人群的创建
3.1人移动实际是坐标的移动,此时创建一个点的对象,定义坐标属性;
3.2 创建人的对象,添加点对象,用于锁定人的位置;
3.3多个人群的实现我们要创建一个List集合用来存储
4.给人的属性添加健康状态,定义常量表示(由于要模拟被感染的情况,所以我们要计算两个人之间的距离,此时在数学工具类添加计算距离的方法。。。直接上代码看注释吧)
创建的全部的类

1.Main主要是窗口的展示和人的初始化

package com.ty;import javax.swing.*;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;public class Main {public static void main(String[] args) {personInit();frameInit();}/*** 创建人群的方法*/private static void personInit(){List<Person> persons =PersonPool.getPersonPool().getPersonList();for (int i =1;i<=Paramer.TOTAL_SIZE;i++){Person p = new Person(MathUtil.getGaussian(60)+250,MathUtil.getGaussian(60)+250);p.setType(Person.HEALTH100);//设置人为健康状态p.setHealth(new Random().nextInt(20)+80);//设置人的健康值为80-100persons.add(p);}//随机添加一个病原体Random r = new Random();Person person = persons.get(r.nextInt(Paramer.TOTAL_SIZE));person.setType(Person.HEALTH25);person.setVirsu(Virsu.getVirsu());//将病原对象放到病原集合中PersonPool.getPersonPool().getVirusList().add(person);//初始化社区人员,保存10个,使用set集合防止挑选的人重复Set<Person> tempSet = new HashSet<>();//先执行后判断雇用do-while循环do{int p = r.nextInt(Paramer.TOTAL_SIZE);//所有人员中随机抽选Person person1 = persons.get(p);//集合中挑出person1.setObserver(true);//设置为社区人员tempSet.add(person1);//去重校验}while (tempSet.size()<10);//加入社区人池集合中PersonPool.getPersonPool().getObserverList().addAll(tempSet);}/*** 初始展示窗口的方法*/private static void frameInit() {JFrame frame = new JFrame();//设置窗体大小frame.setSize(Paramer.WIN_WIDTH,Paramer.WIN_HIGHT);//设置标题frame.setTitle("疫情仿真程序");//添加面板用于绘图MainPanel panel = new MainPanel();frame.add(panel);//设置窗口可见frame.setVisible(true);//设置窗口退出方式frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//启动一个线程用于定时重复绘图Thread t = new Thread(panel);t.start();}
}

2.MainPanel主要执行面板上绘图的操作

package com.ty;import javax.swing.*;
import java.awt.*;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;public class MainPanel extends JPanel implements Runnable {//调用人群集合显示在面板private  List<Person> persons = PersonPool.getPersonPool().getPersonList();private  List<Person> observers = PersonPool.getPersonPool().getObserverList();//重写画图方法@Overridepublic void paint(Graphics g) {super.paint(g);//设置背景色this.setBackground(new Color(0x444444));Color[] colors = {Color.white,Color.green,Color.yellow,Color.red,null,Color.black};for(Person person:persons) {//判断如果是隔离状态的人不在移动if(person.getType()==Person.ISOLATION){continue;}//调用人移动的方法person.move();//调用健康结算的方法person.doHealth();//画出人在的位置
//            程序优化,通过数组来代替
//            if(person.getType()==Person.HEALTH100){
//                g.setColor(Color.white);
//            }else if(person.getType()==Person.HEALTH25){
//                g.setColor(Color.red);
//            }g.setColor(colors[person.getType()]);g.fillOval(person.getPoint().getX(), person.getPoint().getY(), 3, 3);}//打印信息g.setColor(Color.white);g.drawString("总人数:"+Paramer.TOTAL_SIZE,Paramer.MSG_BASE_X,Paramer.MSG_BASE_Y);g.setColor(Color.white);g.drawString("健康人数:"+(Paramer.TOTAL_SIZE-1-Paramer.HEALTH50_COUNT-Paramer.HEALTH90_COUNT),Paramer.MSG_BASE_X,Paramer.MSG_BASE_Y+20);g.setColor(Color.green);g.drawString("疑似人数:"+(Paramer.HEALTH50_COUNT+Paramer.HEALTH90_COUNT-Paramer.dealth_Count),Paramer.MSG_BASE_X,Paramer.MSG_BASE_Y+40);g.setColor(Color.red);g.drawString("发病人数:"+1,Paramer.MSG_BASE_X,Paramer.MSG_BASE_Y+60);g.setColor(Color.red);g.drawString("死亡人数:"+Paramer.dealth_Count,Paramer.MSG_BASE_X,Paramer.MSG_BASE_Y+80);g.setColor(Color.white);g.drawString("世界时间:"+Paramer.time,Paramer.MSG_BASE_X,Paramer.MSG_BASE_Y+100);//发布通告在一定的世界时间if(Paramer.time>40) {Publish.publish(40, "通告:非常时期,大家保持警惕,继续居家隔离,减少外出活动!", g);if(Paramer.time==60){Paramer.move_Wish=0.6f;}}//发布疫情通告在世界时间60if(Paramer.time>60) {Publish.publish2(60, "通告:火神山医院建成并投入使用!", g);}//调用画医院方法if(Paramer.time>70) {Hospital.getHospital().paintHospital(g);}//画出社区人员的监测范围if(Paramer.time>80) {g.setColor(new Color(0x79AEAC9D, true));for (Person p : observers) {//如果社区人员被隔离,不在执行画图if(p.getType()==Person.ISOLATION){continue;}int x = p.getPoint().getX() - 25;int y = p.getPoint().getY() - 25;g.fillOval(x, y, 50, 50);}}}//定义一个执行任务的内部类class MyTask extends TimerTask{@Overridepublic void run() {//绘图操作repaint();//显示的世界世界++Paramer.time++;}};@Overridepublic void run() {//此线程用于定时绘图Timer timer = new Timer();timer.schedule(new MyTask(),0,100);}
}

3.人相关的类

3.1定义人的位置Point类封装坐标属性

package com.ty;public class Point {private int x;private int 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 Point(int x, int y) {this.x = x;this.y = y;}public Point() {}
}

3.2Person包括人的行为等等的封装

package com.ty;import java.util.Random;public class Person {//定义常量代表人健康的状态public static final int HEALTH100=0;   //健康public static final int HEALTH90=1;    //接触未感染,疑似public static final int HEALTH50=2;    //接触感染,疑似public static final int HEALTH25=3;    //病源public static final int ISOLATION=4;    //被隔离public static final int DEATH=5;       //死亡//人的状态属性private int type;//人的健康值100作为上限private int health;public int getHealth() {return health;}public void setHealth(int health) {this.health = health;}public int getType() {return type;}public void setType(int type) {this.type = type;}//人的坐标点private Point point;//病毒对象private Virsu virsu;//社区人员标记private boolean observer;public boolean isObserver() {return observer;}public void setObserver(boolean observer) {this.observer = observer;}public Virsu getVirsu() {return virsu;}public void setVirsu(Virsu virsu) {this.virsu = virsu;}public Point getPoint() {return point;}public void setPoint(Point point) {this.point = point;}public Person(int x,int y) {this.point = new Point(x,y);}public Person() {}//定义人移动行为public void move(){//社区人员的巡检操作if(this.isObserver()&&Paramer.time>80){//检验辖区范围内每一个人for(Person p : PersonPool.getPersonPool().getPersonList()){//判断距离int x = this.getPoint().getX();int y = this.getPoint().getY();int x1 = p.getPoint().getX();int y1 = p.getPoint().getY();if(Math.abs(x-x1)<25&&Math.abs(y-y1)<25){//判断状态if(p.getType()==Person.HEALTH50||p.getType()==Person.HEALTH90){//送医院就诊Hospital.getHospital().receieve(p,this);return;//发现对象,停止监测}}}}//判断如果死亡的人不在移动if(this.getType()==Person.DEATH){return;}//移动前根据意愿判断行为//社区人员不受移动意愿的控制if(Math.random()>Paramer.move_Wish && !this.isObserver()){return;}//如果是社区人员,移动范围扩大if(this.isObserver()){int x =  this.getPoint().getX() + MathUtil.getGaussian(4);int y = this.getPoint().getY() + MathUtil.getGaussian(4);}int x =  this.getPoint().getX() + MathUtil.getGaussian(2);int y = this.getPoint().getY() + MathUtil.getGaussian(2);//控制人活动的范围x=x>Paramer.AREA_WIDTH?Paramer.AREA_WIDTH:x;x=x<0?0:x;y=y>Paramer.AREA_HIGHT?Paramer.AREA_HIGHT:y;y=y<0?0:y;this.getPoint().setX(x);this.getPoint().setY(y);//2.1如果距离在传染范围则被传染,停止比对并加入病原集合//0.排除已经被感染人群的比对if(getType()>1){return;}//1.使用每一个人与带病的人进行比对for(Person p :PersonPool.getPersonPool().getVirusList()){//2.计算两者之间的距离double distance = MathUtil.getDistance(this,p);if(distance>5){//放行检测下一个continue;}//添加概率判断暂且定位40%的命中率if(Math.random()<0.4f){//接触未感染,再次被检测感染时要从源数据减去if(this.getType()==Person.HEALTH90){Paramer.HEALTH90_COUNT--;}//2.1范围内被感染修改状态this.setType(Person.HEALTH50);//病毒加载到病人身上this.setVirsu(Virsu.getVirsu());//2.2加入病原人群PersonPool.getPersonPool().getVirusList().add(this);//2.3计算传染的数量Paramer.HEALTH50_COUNT++;//2.4已经传染无需再比对,终止循环break;}else{//接触,未感染,终止if(this.getType()==Person.HEALTH90){continue;}//计算接触未感染数量Paramer.HEALTH90_COUNT++;this.setType(Person.HEALTH90);}}}Random r = new Random();//健康结算public void doHealth(){//无病毒的人不结算if(this.getVirsu()==null) {return;}//已经死亡的人不结算if(this.getType()==Person.DEATH){return;}//获取健康值-病毒的伤害保存到人健康属性中this.setHealth( this.getHealth()-this.getVirsu().getDamage());//免疫力的设定this.setHealth( this.getHealth()+r.nextInt(7));//判断健康值不能超过100if (this.getHealth()>=100){this.setHealth(100);//健康值设为100this.setVirsu(null);//去掉病毒//数据统计if(this.getType()==Person.HEALTH50){Paramer.HEALTH50_COUNT--;}//状态变为健康的状态this.setType(Person.HEALTH100);//从疑似病毒集合移除PersonPool.getPersonPool().getVirusList().remove(this);}//判断如果健康值低于0需要去除病毒并修改人的状态if(this.getHealth()<=0){this.setVirsu(null);this.setType(Person.DEATH);//如果是社区人员,要从社区集合移除if(this.isObserver()){PersonPool.getPersonPool().getObserverList().remove(this);}//将死亡的人从病毒集合中移除PersonPool.getPersonPool().getVirusList().remove(this);//死亡数量要++Paramer.dealth_Count++;}}
}

3.3PersonPool

package com.ty;import java.util.ArrayList;
import java.util.List;public class PersonPool {private static PersonPool personPool = new PersonPool();private PersonPool(){}public static PersonPool getPersonPool(){return personPool;}//健康人的集合private List<Person> personList = new ArrayList<>();//病源集合private List<Person> virusList = new ArrayList<>();//社区人员的集合private List<Person> observerList = new ArrayList<>();public List<Person> getObserverList() {return observerList;}public void setObserverList(List<Person> observerList) {this.observerList = observerList;}public List<Person> getPersonList() {return personList;}public void setPersonList(List<Person> personList) {this.personList = personList;}public List<Person> getVirusList() {return virusList;}public void setVirusList(List<Person> virusList) {this.virusList = virusList;}
}

4.工具类

4.1MathUtil计算距离等封装

package com.ty;import java.util.Random;public class MathUtil {private static Random r = new Random();//通过高斯获取一个随机数public static int getGaussian(int range){return (int)(r.nextGaussian()*range);}//计算两个人距离的方法public static double getDistance(Person p1,Person p2){Point point1 = p1.getPoint();Point point2 = p2.getPoint();int x = point1.getX()-point2.getX();int y = point1.getY()-point2.getY();return Math.sqrt(x*x+y*y);}
}

4.4publish发布公告信息的类

package com.ty;import java.awt.*;public class Publish {public static void publish(int time,String msg, Graphics g){//公告栏的显示msg = "        "+msg+"        ";if((Paramer.time-time)/Paramer.MSG_SHOW_SPEED+20<msg.length()) {String showMsg = msg.substring((Paramer.time-time) / Paramer.MSG_SHOW_SPEED, (Paramer.time-time) / Paramer.MSG_SHOW_SPEED + 20);g.drawString(showMsg , Paramer.MSG_BASE_X, Paramer.MSG_BASE_Y + 120);}}public static void publish2(int time, String msg, Graphics g) {//公告栏的显示msg = "        "+msg+"        ";if((Paramer.time-time)/Paramer.MSG_SHOW_SPEED+20<msg.length()) {String showMsg = msg.substring((Paramer.time-time) / Paramer.MSG_SHOW_SPEED, (Paramer.time-time) / Paramer.MSG_SHOW_SPEED + 20);g.drawString(showMsg , Paramer.MSG_BASE_X, Paramer.MSG_BASE_Y + 140);}}
}

5.疫情主角

5.1病毒类Virsu描述新冠的威力

package com.ty;import java.util.Random;public class Virsu {private static Virsu virsu = new Virsu();private Virsu(){}public static Virsu getVirsu(){return virsu;}private int damage;Random r = new Random();//随机产生15-30的杀伤力public int getDamage() {return r.nextInt(3)+2;}public void setDamage(int damage) {this.damage = damage;}
}

5.2Bed给医院提供的床位

package com.ty;import java.awt.*;public class Bed {private int x;private int y;private Person person;private Color bedColor = Color.GREEN;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 Person getPerson() {return person;}public void setPerson(Person person) {this.person = person;if(person==null){this.bedColor = Color.green;return;}if(person.getType()==Person.DEATH){this.bedColor = Color.orange;return;}if(person!=null && person.isObserver()){this.bedColor = Color.blue;return;}this.bedColor = Color.red;}public Color getBedColor() {return bedColor;}public void setBedColor(Color bedColor) {this.bedColor = bedColor;}
}

5.3医院Hospital

package com.ty;import java.awt.*;
import java.util.Random;public class Hospital {private static Hospital hospital = new Hospital();private Hospital(){}public static Hospital getHospital(){return hospital;}//定义一个二维数组,模拟床位Bed[][] beds = new Bed[43][32];//给床设置坐标{for(int i=0;i<beds.length;i++){for(int j=0;j<beds[i].length;j++){beds[i][j] = new Bed();beds[i][j].setX(i);beds[i][j].setY(j);}}}//绘制医院的方法public void paintHospital(Graphics g) {g.setColor(Color.green);g.drawString("雷火医院",580,175);g.drawRect(520,180,160,260);for(int i=0;i<beds.length;i++){for(int j=0;j<beds[i].length;j++){/* g.drawLine(522+j*5,183+i*6,524+j*5,183+i*6);g.drawLine(522+j*5,184+i*6,524+j*5,184+i*6);*/g.setColor(beds[i][j].getBedColor());g.fillRect(522+j*5,183+i*6,3,2);}}}//接收病人的方法public void receieve(Person target,Person src){//疑似病例判断,若感染,治疗if(isHaveVirsu(target)){treat(target);}//社区人员判断,若感染,治疗if(isHaveVirsu(src)){treat(src);}else {//回去继续工作}}//治疗的方法private void treat(Person p ){//分配病床out :for(int i=0;i<beds.length;i++){for(int j=0;j<beds[i].length;j++){if(beds[i][j].getPerson()==null){beds[i][j].setPerson(p);//病人的状态修改为隔离状态p.setType(Person.ISOLATION);break out;//停止继续寻找}}}}//治疗情况的计算方法Random r = new Random();//健康结算public void doHealth(){for(int i=0;i<beds.length;i++){for(int j=0;j<beds[i].length;j++){Bed b =  beds[i][j];Person p = b.getPerson();//判断床位是否有病人,无直接下一个if(p==null){continue;}//如果死病床的也不结算if(p.getType()==Person.DEATH){continue;}//健康值的计算int health = p.getHealth();//病毒的杀伤力,判断排除掉疑似为感染病范if(p.getVirsu()!=null){health -= p.getVirsu().getDamage();}//免疫力health += r.nextInt(6);//医院的治疗health += r.nextInt(3)-30;p.setHealth(health);//判断健康值不能超过100if (p.getHealth()>=100){p.setHealth(100);//健康值设为100p.setVirsu(null);//去掉病毒//状态变为健康的状态p.setType(Person.HEALTH100);//从疑似病毒集合移除PersonPool.getPersonPool().getVirusList().remove(p);//出院的腾出床位b.setPerson(null);}//判断如果健康值低于0需要去除病毒并修改人的状态if(p.getHealth()<=0){p.setVirsu(null);p.setType(Person.DEATH);//如果是社区人员,要从社区集合移除if(p.isObserver()){PersonPool.getPersonPool().getObserverList().remove(p);}//将死亡的人从病毒集合中移除PersonPool.getPersonPool().getVirusList().remove(p);//死亡数量要++Paramer.dealth_Count++;b.setPerson(p);}}}}//判断状态是否感染的方法private boolean isHaveVirsu(Person p ){return p.getType()==Person.HEALTH50||p.getType()==Person.HEALTH25;}}

6.提取了公共数据的参数类Paramer

package com.ty;public class Paramer {//疑似不带病人的数量public static  int HEALTH90_COUNT = 0;//疑似带病人的数量public static  int HEALTH50_COUNT = 0;//已经死亡人的数量public static int dealth_Count = 0;//定义一个世界时间public static int time =0;//移动意愿的定义public static float move_Wish = 0.9f;//定义消息显示的基本坐标public static final int MSG_BASE_X=520;public static final int MSG_BASE_Y=20;//定义消息滚动速度(1最快)public static final int MSG_SHOW_SPEED=5;//设置窗口的宽和高public static final int WIN_WIDTH =700;public static final int WIN_HIGHT =500;//设置总人数public static final int TOTAL_SIZE =2000;//设置区域的宽高public static final int AREA_WIDTH=500;public static final int AREA_HIGHT=500;}

最后效果图在这里插入图片描述

这篇关于疫情病毒模拟仿真程序的实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/899847

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

Java面试八股之怎么通过Java程序判断JVM是32位还是64位

怎么通过Java程序判断JVM是32位还是64位 可以通过Java程序内部检查系统属性来判断当前运行的JVM是32位还是64位。以下是一个简单的方法: public class JvmBitCheck {public static void main(String[] args) {String arch = System.getProperty("os.arch");String dataM

通过SSH隧道实现通过远程服务器上外网

搭建隧道 autossh -M 0 -f -D 1080 -C -N user1@remotehost##验证隧道是否生效,查看1080端口是否启动netstat -tuln | grep 1080## 测试ssh 隧道是否生效curl -x socks5h://127.0.0.1:1080 -I http://www.github.com 将autossh 设置为服务,隧道开机启动

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页:

探索蓝牙协议的奥秘:用ESP32实现高质量蓝牙音频传输

蓝牙(Bluetooth)是一种短距离无线通信技术,广泛应用于各种电子设备之间的数据传输。自1994年由爱立信公司首次提出以来,蓝牙技术已经经历了多个版本的更新和改进。本文将详细介绍蓝牙协议,并通过一个具体的项目——使用ESP32实现蓝牙音频传输,来展示蓝牙协议的实际应用及其优点。 蓝牙协议概述 蓝牙协议栈 蓝牙协议栈是蓝牙技术的核心,定义了蓝牙设备之间如何进行通信。蓝牙协议

一道经典Python程序样例带你飞速掌握Python的字典和列表

Python中的列表(list)和字典(dict)是两种常用的数据结构,它们在数据组织和存储方面有很大的不同。 列表(List) 列表是Python中的一种有序集合,可以随时添加和删除其中的元素。列表中的元素可以是任何数据类型,包括数字、字符串、其他列表等。列表使用方括号[]表示,元素之间用逗号,分隔。 定义和使用 # 定义一个列表 fruits = ['apple', 'banana