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

来源:脚本之家  责任编辑:小易  

其实这个不难,以下代码做个参考吧。coding:utf-8-*-class Student(object):自定义Student类def_init_(self,name,score):初始化Student,参数name,scoreself.name=nameself.score=scoredef_cmp_(self,other):重写比较方法,根据Student类属性score进行比较return cmp(self.score,other.score)def show(self):return 'name:'+self.name+';score:'+str(self.score)def get_input():name=raw_input('input name>')if not name:#当姓名输入为空时,返回Nonereturn(None,None)score=raw_input('input%s\\'s score>'%name)if name and score:return(name,int(score))#为方便比较,将score强制转换为int型else:return(None,None)def main():s_list=[]while True:#一直循环输入姓名及成绩name,score=get_input()if name and score:s=Student(name,score)s_list.append(s)else:#当输入姓名或成绩为空时跳出循环breaks_list.sort()#对Student实体进行排序for i,s in enumerate(s_list):#遍历已经排序的实体列表,并进行显示print ' '.join([str(i+1),s.name,str(s.score)])if_name_='_main_':main()输入及输出结果如下,当然你也可以修改下 s_list 方便测试input name>ainput a's score>97input name>binput b's score>95input name>cinput c's score>96input name>1 b 952 c 963 a 97 注释已经比较详细了,应该能看懂www.zgxue.com防采集请勿采集本网。

病毒扩散仿真程序,用 python 也可以。

我一般都是在后面加一个输入语句, 比如:input("Prease ")

概述

事情是这样的,B 站 UP 主 @ele 实验室,写了一个简单的疫情传播仿真程序,告诉大家在家待着的重要性,视频相信大家都看过了,并且 UP 主也放出了源码。

import httplib2response, content = httplib2.Http().request( "guji.artx.cn", "GET" header={"cookie":"bdshare_", "User-Agent":"Mozilla/5.0 (Windows"} 请求头都以dict形式写在header里就行了。 返回值中,response里主要是状态码,

因为是 Java 开发的,所以开始我并没有多加关注。后来看到有人解析代码,发现我也能看懂,然后就琢磨用 Python 应该怎么实现。

你的代码呢?

Java 版程序浅析

Python程序,错误NameError:名称XX未定义不是由声明引起的,需要在文件的前两行声明代码,声明方法是: 1,在文件中写一个带有中文字符的python文件,不进行编码。 2,当程序文件中有中文字符时,如果文件未声明编码格式,则会显示错误消息:文

一个人就是 1 个(x, y)坐标点,并且每个人有一个状态。

你的文件是csv,文本格式,不是excel格式,所以用excel方式去打开文本文件就会报错。

public class Person extends Point { private int state = State.NORMAL;}

在每一轮的迭代中,遍历每个人,每个人根据自身的状态,做出一定的动作,包括: 移动 状态变化 影响他人

这些动作的具体变更,取决于定义的各种系数。

一轮迭代完成,打印这些点,不同的状态对应不同的颜色。

绘图部分直接使用的 Java 绘图类 Graphics。

Python 版思路

如果我们想用 Python 实现应该怎么做呢?

如果完全复刻 Java 版本,则每次迭代需遍历所有人,并计算和他人距离,这就是 N^2 次计算。如果是 1000 个人,就需要循环 1 百万次。这个 Python 的性能肯定捉急。

不过 Python 有 numpy ,可以快速的操作数组。结合 matplotlib 则可以画出图形。

import numpy as npimport matplotlib.pyplot as plt

如何模拟人群

为了减少函数之间互相传参和使用全局变量,我们也来定义一个类:

class People(object): def __init__(self, count=1000, first_infected_count=3): self.count = count self.first_infected_count = first_infected_count self.init()

所有人的坐标数据就是 N 行 2 列的数组,同时伴随一定的状态:

def init(self): self._people = np.random.normal(0, 100, (self.count, 2)) self.reset()

状态值和计时器也都是数组,同时每次随机选取指定数量的人感染:

def reset(self): self._round = 0 self._status = np.array([0] * self.count) self._timer = np.array([0] * self.count) self.random_people_state(self.first_infected_count, 1)

这里关键的一点是,辅助数组的大小和人数保持一致,这样就能形成一一对应的关系。

状态发生变化的人才顺带记录时间:

def random_people_state(self, num, state=1): """随机挑选人设置状态 """ assert self.count > num # TODO:极端情况下会出现无限循环 n = 0 while n < num: i = np.random.randint(0, self.count) if self._status[i] == state: continue else: self.set_state(i, state) n += 1 def set_state(self, i, state): self._status[i] = state # 记录状态改变的时间 self._timer[i] = self._round

通过状态值,就可以过滤出人群,每个人群都是 people 的切片视图。这里 numpy 的功能相当强大,只需要非常简洁的语法即可实现:

@property def healthy(self): return self._people[self._status == 0] @property def infected(self): return self._people[self._status == 1]

按照既定的思路,我们先来定义每轮迭代要做的动作:

def update(self): """每一次迭代更新""" self.change_state() self.affect() self.move() self._round += 1 self.report()

顺序和开始分析的略有差异,其实并不是十分重要,调换它们的顺序也是可以的。

如何改变状态

这一步就是更新状态数组 self._status 和 计时器数组 self._timer:

def change_state(self): dt = self._round - self._timer # 必须先更新时钟再更新状态 d = np.random.randint(3, 5) self._timer[(self._status == 1) & ((dt == d) | (dt > 14))] = self._round self._status[(self._status == 1) & ((dt == d) | (dt > 14))] += 1

仍然是通过切片过滤出要更改的目标,然后全部更新。

这里具体的实现我写的非常简单,没有引入太多的变量:

在一定周期内的 感染者(infected),状态置为 确诊(confirmed)。 我这里简单假设了确诊者就被医院收治,所以失去了继续感染他人的机会(见下面)。如果要搞复杂点,可以引入病床,治愈,死亡等状态。

如何影响他人

影响别人是整个程序的性能瓶颈,因为需要计算每个人之间的距离。

这里继续做了简化,只处理感染者:

def infect_possible(self, x=0., safe_distance=3.0): """按概率感染接近的健康人 x 的取值参考正态分布概率表,x=0 时感染概率是 50% """ for inf in self.infected: dm = (self._people - inf) ** 2 d = dm.sum(axis=1) ** 0.5 sorted_index = d.argsort() for i in sorted_index: if d[i] >= safe_distance: break # 超出范围,不用管了 if self._status[i] > 0: continue if np.random.normal() > x: continue self._status[i] = 1 # 记录状态改变的时间 self._timer[i] = self._round

可以看到,距离的计算仍然是通过 numpy 的矩阵操作。但是需要对每一个感染者单独计算,所以如果感染者较多,python 的处理效率感人。

如何移动

_people 是一个坐标矩阵,只要生成移动距离矩阵 dt,然后它相加即可。我们可以设置一个可移动的范围 width,把移动距离控制在一定范围内。

def move(self, width=1, x=.0): movement = self.random_movement(width=width) # 限定特定状态的人员移动 switch = self.random_switch(x=x) movement[switch == 0] = 0 self._people = self._people + movement

这里还需要增加一个控制移动意向的选项,仍然是利用了正态分布概率。考虑到这种场景有可能会重用,所以特地把这个方法提取了出来,生成一个只包含 0 1 的数组充当开关。

def random_switch(self, x=0.): """随机生成开关,0 - 关,1 - 开 x 大致取值范围 -1.99 - 1.99; 对应正态分布的概率, 取值 0 的时候对应概率是 50% :param x: 控制开关比例 :return: """ normal = np.random.normal(0, 1, self.count) switch = np.where(normal < x, 1, 0) return switch

输出结果

有了一切数据和变化之后,接下来最重要的事情自然就是图形化显示结果了。直接使用 matplotlib 的散点图就可以了:

   

def report(self): plt.cla() # plt.grid(False) p1 = plt.scatter(self.healthy[:, 0], self.healthy[:, 1], s=1) p2 = plt.scatter(self.infected[:, 0], self.infected[:, 1], s=1, c='pink') p3 = plt.scatter(self.confirmed[:, 0], self.confirmed[:, 1], s=1, c='red') plt.legend([p1, p2, p3], ['healthy', 'infected', 'confirmed'], loc='upper right', scatterpoints=1) t = "Round: %s, Healthy: %s, Infected: %s, Confirmed: %s" % \ (self._round, len(self.healthy), len(self.infected), len(self.confirmed)) plt.text(-200, 400, t, ha='left', wrap=True)

实际效果

启动。

if __name__ == '__main__': np.random.seed(0) plt.figure(figsize=(16, 16), dpi=100) plt.ion() p = People(5000, 3) for i in range(100): p.update() p.report() plt.pause(.1) plt.pause(3)

因为这个小 demo 主要是个人用来练手,目前一些参数没有完全抽出来。有需要的只能直接改源码。

后记

从多次实验的结果,通过调整人员的流动意愿,流动距离等因素,是可以得到直观的结论的。

本人也是初次使用 numpy 和 matplotlib,现学现卖,若有使用不当之处请指正。其中的概率参数设置 基本没有科学依据,仅供 Python 爱好者参考。

总得来说,用 numpy 来模拟病毒感染情况应该是能行得通的。但是其中的影响因子还需要仔细设计。性能也是需要考量的问题。

源码地址

总结

以上所述是小编给大家介绍的Python 写了个新型冠状病毒疫情传播模拟程序,希望对大家有所帮助,也非常感谢大家对真格学网网站的支持!

该醒醒了,工人本来就是工厂的产能工具,利益才是他们最关心的,换谁都一样,工厂无非就是要填写调查确定下,然后照样要你按时开工内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • python实现新型冠状病毒传播模型及预测代码实例
  • 使用python制作新型冠状病毒实时疫情图
  • 十行代码使用python写一个usb病毒
  • python selenium cookie 绕过验证码实现登录示例代码
  • python2.7读取文件夹下所有文件名称及内容的方法
  • python执行时间的计算方法小结
  • 解决pytorch 训练与测试时爆显存(out of memory)的问题
  • python 迭代器和iter()函数详解及实例
  • python pandas批量读取csv文件到dataframe的方法
  • python将一个csv文件里的数据追加到另一个csv文件的方法
  • python获取本地计算机名字的方法
  • python读取本地文件并解析网页元素的方法
  • python实现点阵字体读取与转换的方法
  • 新型冠状病毒疫情漫延,工厂明天开工,至今没有收...
  • 用python写一个程序
  • 编写一个Python程序, 模拟抛硬币一百万次,显示出现...
  • 我想使用python写一个小程序作为练习,使用的是pyt...
  • 用Python写的程序,保存为.py,添加什么命令才能使...
  • 用python写一个程序模拟登陆,不知怎么写,请大神指点
  • 想用python写一个模拟知乎发文章的功能,模拟到dra...
  • 我写了一个python程序,报错NameError: name XX is...
  • 在Windows环境下用Python写了一个小程序,出现下面...
  • 编写一个python程序,输出如下图形效果? 编写一个...
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全vbsdos/bathtahtcpythonperl游戏相关vba远程脚本coldfusionruby专题autoitseraphzonepowershelllinux shellluagolangerlang其它首页pythonpython实现新型冠状病毒传播模型及预测代码实例使用python制作新型冠状病毒实时疫情图十行代码使用python写一个usb病毒python selenium cookie 绕过验证码实现登录示例代码python2.7读取文件夹下所有文件名称及内容的方法python执行时间的计算方法小结解决pytorch 训练与测试时爆显存(out of memory)的问题python 迭代器和iter()函数详解及实例python pandas批量读取csv文件到dataframe的方法python将一个csv文件里的数据追加到另一个csv文件的方法python获取本地计算机名字的方法python读取本地文件并解析网页元素的方法python实现点阵字体读取与转换的方法python入门教程 超详细1小时学会python 列表(list)操作方法详解python 元组(tuple)操作详解python 字典(dictionary)操作详解pycharm 使用心得(一)安装和首python strip()函数 介绍python 中文乱码问题深入分析python科学计算环境推荐——anacpython逐行读取文件内容的三种方python中使用xlrd、xlwt操作excepython多线程、异步+多进程爬虫实现代码python实现支付宝当面付(扫码支付)功能python使用tkinter显示网络图片的方法pycharm设置ssh远程调试的方法在python中测试访问同一数据的竞争条件的python使用tkinter模块实现推箱子游戏python实现通过shelve修改对象实例python实现linux命令xxd -i功能python实现学员管理系统python远程调用rpc模块xmlrpclib的方法
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved