Python实现病毒仿真器的方法示例(附demo)

最近新冠在神州大陆横行,全国上下一心抗击疫情。作为一枚程序员,我也希望可以为抗击疫情做出自己的贡献,钟院士一直劝说大家不要出门,减少人口间的流动。对此,我特意做了一个病毒仿真器,探询冠状病毒传播。

1. 仿真效果

仿真开始,一开始只有5个发病者,传播率为0.8,潜伏期为14天

由于人口的流动,以及医院床位的隔离,一开始病毒扩撒不是很速度

随着医院床位满了,隔离失败,加上人口的流动,病患数开始几何式的增加

2. 什么是仿真器

仿真器(emulator)以某一系统复现另一系统的功能。与计算机模拟系统(Computer Simulation)的区别在于,仿真器致力于模仿系统的外在表现、行为,而不是模拟系统的抽象模型。

3. python如何实现仿真器

现在来谈谈仿真器实现的原理。仿真器使用Python和PyQt5实现。PyQt5是封装了Qt library的跨平台GUI开发库,基于Python语言。

这里主要涉及到仿真器效果绘制,以及如何模拟多个参数。先来说一下绘制市民的状态。绘制的工作通过drawing.py文件的Drawing类来完成。该类是QWidget的子类,这也就意味着Drawing类本身是PyQt5的一个组件。与按钮、标签类似。只是并不需要往Drawing上放置任何子组件。只要在Drawing上绘制各种图形即可。

在PyQt5中,任何一个QWidget的子类,都可以实现一个paintEvent方法,当组件每次刷新时,就会调用paintEvent方法重新绘制组件的内容。Drawing类中paintEvent方法的代码如下:

 # 每次Drawing刷新,都会调用该方法
  def paintEvent(self,event):
    qp = QPainter()
    qp.begin(self)
    self.drawing(qp) # 绘制城市的各种状态的市民
    qp.end()

在绘制图像前,需要创建QPainter对象,然后调用QPainter对象的begin方法,结束绘制后,需要调用QPainter对象的end方法。上面代码中的drawing方法用于完成具体的绘制工作。

仿真器设置一个人员池,来进行人员的流动性

class Persons(metaclass=Singleton):
  def __init__(self):
    self.persons = []          # 保存所有的人员
    self.latency_persons = []      # 保存处于潜伏期的人员

    city = City(Params.city_center_x,Params.city_center_y)

    for value in range(0, Params.city_person_count):
      x = Params.person_position_scale * next_gaussian() + city.center_x
      y = Params.person_position_scale * next_gaussian() + city.center_y
      if x > Params.city_width:
        x = Params.city_width
      if y > Params.city_height:
        y = Params.city_height
      self.persons.append(Person(city,x,y))
  # 获取特定人群的数量
  def get_person_size(self,state):
    if state == -1:
      return len(self.persons)
    count = 0
    for person in self.persons:
      if person.state == state:
        count += 1
    return count

仿真代码

from PyQt5.QtWidgets import *
from socket import *

class Transmission:
  def __init__(self,ui):
    self.ui = ui
    self.host = 'localhost'
    self.port = 5678
    self.addr = (self.host,self.port)

  def send_command(self,command,value=None):
    tcp_client_socket = socket(AF_INET,SOCK_STREAM)
    tcp_client_socket.connect(self.addr)

    if value == None:
      value = 0

    data = command + ':' + str(value)
    tcp_client_socket.send(('%s\r\n' % data).encode(encoding='utf-8'))
    data = tcp_client_socket.recv(1024)
    result = data.decode('utf-8').strip()
    tcp_client_socket.close()
    return result
  def setup(self):
    self.ui.horizontalSliderBedCount.valueChanged.connect(self.bed_count_value_change)
    self.ui.pushButtonUpdateBedCount.clicked.connect(self.update_bed_count)

    self.ui.horizontalSliderFlowIntention.valueChanged.connect(self.flow_intention_value_change)
    self.ui.pushButtonFlowIntention.clicked.connect(self.update_flow_intention)

    self.ui.horizontalSliderBroadRate.valueChanged.connect(self.broad_rate_value_change)
    self.ui.pushButtonBroadRate.clicked.connect(self.update_broad_rate)

    self.ui.horizontalSliderLatency.valueChanged.connect(self.latency_value_change)
    self.ui.pushButtonLatency.clicked.connect(self.update_latency)

    self.ui.pushButtonClose.clicked.connect(self.close_virus_simulation)

  def bed_count_value_change(self):
    self.ui.labelBedIncrement.setText(
      f'<html><head/><body><p><span style=\" font-size:24pt; color:#0000ff;\">{self.ui.horizontalSliderBedCount.value()}</span></p></body></html>')

  def update_bed_count(self):
    print(self.ui.horizontalSliderBedCount.value())
    result = self.send_command('add_bed_count', self.ui.horizontalSliderBedCount.value())
    if result == 'ok':
      QMessageBox.information(self.ui.centralwidget, '消息', f'成功添加了{self.ui.horizontalSliderBedCount.value()}张床位',
                  QMessageBox.Ok)

  def flow_intention_value_change(self):
    self.ui.labelFlowIntention.setText(
      f'<html><head/><body><p><span style=\" font-size:24pt; color:#fc02ff;\">{self.ui.horizontalSliderFlowIntention.value() / 100}</span></p></body></html>')

  def update_flow_intention(self):
    result = self.send_command('set_flow_intention', self.ui.horizontalSliderFlowIntention.value())
    if result == 'ok':
      QMessageBox.information(self.ui.centralwidget, '消息',
                  f'成功设置流动意向为{self.ui.horizontalSliderFlowIntention.value() / 100}', QMessageBox.Ok)

  def broad_rate_value_change(self):
    self.ui.labelBroadRate.setText(
      f'<html><head/><body><p><span style=\" font-size:24pt; color:#fc0107;\">{self.ui.horizontalSliderBroadRate.value() / 100}</span></p></body></html>')

  def update_broad_rate(self):
    result = self.send_command('set_broad_rate', self.ui.horizontalSliderBroadRate.value())
    if result == 'ok':
      QMessageBox.information(self.ui.centralwidget, '消息',
                  f'成功设置传播率为{self.ui.horizontalSliderBroadRate.value() / 100}', QMessageBox.Ok)

  def latency_value_change(self):
    self.ui.labelLatency.setText(
      f'<html><head/><body><p><span style=\" font-size:24pt; color:#ffff0a;\">{self.ui.horizontalSliderLatency.value()}</span></p></body></html>')

  def update_latency(self):
    result = self.send_command('set_latency', self.ui.horizontalSliderLatency.value())
    if result == 'ok':
      QMessageBox.information(self.ui.centralwidget, '消息', f'成功设置传播率为{self.ui.horizontalSliderLatency.value()}',
                  QMessageBox.Ok)

  def close_virus_simulation(self):
    reply = QMessageBox.information(self.ui.centralwidget, "请问", "是否真的要关闭病毒扩散仿真器?",
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
    if reply == QMessageBox.Yes:
      result = self.send_command('close')
      if result == 'ok':
        QMessageBox.information(self.ui.centralwidget, '消息', '已经成功关闭病毒扩散仿真器', QMessageBox.Ok)

设置变量

class Params:
  success = False

  # 初始感染人数
  original_infected_count = 50

  # 病毒传播率
  broad_rate = 0.8

  # 病毒潜伏期,14天
  virus_latency = 140

  # 医院收治响应时间
  hospital_receive_time = 10

  # 医院床位
  hospital_bed_count = 100

  # 安全距离
  safe_distance = 2

  # 平均流动意向[-3,3]  值越大,流动意向越强
  average_flow_intention = 3

  # 城市总人口数量
  city_person_count = 5000

  # 病死率
  fatality_rate = 0.02

  # 死亡时间
  dead_time = 30
  # 死亡时间方差
  dead_variance = 30

  # 城市宽度
  city_width = 1100

  # 城市高度
  city_height = 800

  # 医院宽度(需要计算获得)
  hospial_width = 0

  # 城市中心x坐标
  city_center_x = 550

  # 城市中心y坐标
  city_center_y = 400

  # 用于计算城市中每个人随机位置的scale(用于正态分布)
  person_position_scale = 200

  current_time = 1 # 当前时间

我们可以根据这些修改仿真页面

完整代码

以上就是Python实现病毒仿真器的方法示例的详细内容,更多关于请关注我们其它相关文章!

(0)

相关推荐

  • Python爬取新型冠状病毒“谣言”新闻进行数据分析

    一.爬取数据 话不多说了,直接上代码( copy即可用 ) import requests import pandas as pd class SpiderRumor(object): def __init__(self): self.url = "https://vp.fact.qq.com/loadmore?artnum=0&page=%s" self.header = { "User-Agent": "Mozilla/5.0 (iPhone;

  • Python写出新冠状病毒确诊人数地图的方法

    最近肺炎的发展速度属实有点恐怖.刚知道python的pyecharts这个库,想到pyecharts可视化的特点,正好可以扒一下肺炎实时播报的官网也做个地图. 第一步扒取数据:发现一个大问题,各省的确诊人数网页源代码里竟然没有.百度才知道这是js渲染生产的,又是一顿查.找到一种方法.用selenium执行一遍网页渲染的过程就可以了,首先安装selenium. pip install selenium 在引用库的时候还需要webdriver这个启动浏览器的东西,我用的是google,所以要下载ch

  • 十行代码使用Python写一个USB病毒

    大家好,我又回来了. 昨天在上厕所的时候突发奇想,当你把usb插进去的时候,能不能自动执行usb上的程序.查了一下,发现只有windows上可以,具体的大家也可以搜索(搜索关键词usb autorun)到.但是,如果我想,比如,当一个usb插入时,在后台自动把usb里的重要文件神不知鬼不觉地拷贝到本地或者上传到某个服务器,就需要特殊的软件辅助. 于是我心想,能不能用python写一个程序,让它在后台运行.每当有u盘插入的时候,就自动拷贝其中重要文件. 如何判断U盘的插入与否? 首先我们打开电脑终

  • python实现集中式的病毒扫描功能详解

    本文实例讲述了python实现集中式的病毒扫描功能.分享给大家供大家参考,具体如下: 一 点睛 本次实践实现了一个集中式的病毒扫描管理,可以针对不同业务环境定制扫描策略,比如扫描对象.描述模式.扫描路径.调度频率等.案例实现的架构图如下,首先业务服务器开启clamd服务(监听3310端口),管理服务器启用多线程对指定的服务集群进行扫描,扫描模式.扫描路径会传递到clamd,最后返回扫描结果给管理服务器端. 本次实战通过ClamdNetworkSocket()方法实现与业务服务器建立扫描socke

  • python模拟预测一下新型冠状病毒肺炎的数据

    大家还好吗? 背景就不用多说了吧?本来我是初四上班的,现在延长到2月10日了.这是我工作以来时间最长的一个假期了.可惜哪也去不了.待在家里,没啥事,就用python模拟预测一下新冠病毒肺炎的数据吧.要声明的是本文纯属个人自娱自乐,不代表真实情况. 采用SIR模型,S代表易感者,I表示感染者,R表示恢复者.染病人群为传染源,通过一定几率把传染病传给易感人群,ta自己也有一定的几率被治愈并免疫,或死亡.易感人群一旦感染即成为新的传染源. 模型假设: ①不考虑人口出生.死亡.流动等情况,即人口数量保持

  • 使用Python进行防病毒免杀解析

    很多渗透工具都提供了权限维持的能力,如Metasploit.Empire和Cobalt Strike,但是都会被防病毒软件检测到这种恶意行为.在探讨一个权限维持技巧的时候,似乎越来越多的人关注的是,这个方式会不会被被杀软杀掉? 打造免杀的payload成了一个很重要的话题,在这里,本文将介绍如何使用Pyhton轻松绕过防病毒软件. 0x01 环境准备 1.软件安装 Python 2.7.16 x86:https://www.python.org/ftp/python/2.7.16/python-

  • 使用Python制作新型冠状病毒实时疫情图

    最近一周每天早上起来第一件事,就是打开新闻软件看疫情相关的新闻.了解下自己和亲友所在城市的确诊人数,但纯数字还是缺乏一个直观的概念.那我们来做一个吧. 至于数据,从各大网站的实时疫情页面就可以拿到.以某网站为例,用requests拿到html后,发现并没有数据.不要慌,那证明是个javascript渲染的页面,即使是javascript也是需要从后台取数据的.打开Chrome开发者工具,点开network,刷新页面,点击各个请求,肯定有一个是取json的. 注意这里的返回数据是包含在一个js变量

  • Python实现实时数据采集新型冠状病毒数据实例

    Python实时数据采集-新型冠状病毒 源代码 来源:https://github.com/Programming-With-Love/2019-nCoV 疫情数据时间为:2020.2.1 项目相关截图: 全国数据展示 国内数据展示 国外数据展示 查看指定区域详细数据 源代码,注意安装所需模块(例如 pip install 模块名) import requests import re from bs4 import BeautifulSoup from time import sleep imp

  • Python 写了个新型冠状病毒疫情传播模拟程序

    病毒扩散仿真程序,用 python 也可以. 概述 事情是这样的,B 站 UP 主 @ele 实验室,写了一个简单的疫情传播仿真程序,告诉大家在家待着的重要性,视频相信大家都看过了,并且 UP 主也放出了源码. 因为是 Java 开发的,所以开始我并没有多加关注.后来看到有人解析代码,发现我也能看懂,然后就琢磨用 Python 应该怎么实现. Java 版程序浅析 一个人就是 1 个(x, y)坐标点,并且每个人有一个状态. public class Person extends Point {

  • Python3.7黑帽编程之病毒篇(基础篇)

    引子 Hacker(黑客),往往被人们理解为只会用非法手段来破坏网络安全的计算机高手.但是,黑客其实不是这样的,真正的"网络破坏者"是和黑客名称和读音相似的骇客. 骇客,是用黑客手段进行非法操作并为己取得利益的人.黑客,是用黑客手段为国家或单位做事的人. 那么,既然黑客不是一个很坏的职业,我们就可以去试着学习. 黑客本身的初衷 --黑客其实一直是善良的. 骇客其实他的前身就是黑客. 骇客与黑客分家,有这么一个故事: 原本,只有黑客一族.而不久后,有些黑客想用黑客手段来获取利益,不断被其

  • Python3实现监控新型冠状病毒肺炎疫情的示例代码

    代码如下所示: import requests import json from pyecharts.charts import Map, Geo from pyecharts import options as opts from pyecharts.globals import GeoType, RenderType url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5' datas = json.loads(reque

随机推荐