6

疾病传播模拟

 3 years ago
source link: https://blog.superpung.xyz/primary-practice-h61/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

疾病传播模拟

Posted on

2021-05-22 Edited on 2021-05-31

Views: 37

Symbols count in article: 2k Reading time ≈ 2 mins.

Primary Practice h61

Param

方法 含义 getImmuEffect() / setImmuEffect(double immuEffect) 疫苗免疫率,可降低传染率 getImmuRate() / setImmuRate(double immuRate) 人群中注射疫苗的人的比例,随机 getCityPopulation() / setCityPopulation(int cityPopulation) 城市人口数 getFamilySize() / setFamilySize(int familySize) 每个家庭人口数(按序) getCompanySize() / setCompanySize(int companySize) 每个公司人口数(随机) getSpreadRateFamily() / setSpreadRateFamily(double spreadRateFamily) 家庭传染率(晚上) getSpreadRateCompany(double spreadRateCompany) 公司传染率(白天) getLatentPeriod() / setLatentPeriod(int latentPeriod) 潜伏期,此时病人具有传染性,但仍正常上班生活,度过潜伏期后排队治疗 getHealingRateHome() / setHealingRateHome(double healingRateHome) 在家每天自愈概率 getDeathRateHome() / setDeathRateHome(double deathRateHome) 在家每天死亡概率 getHealingRateHospital() / setHealingRateHospital(double healingRateHospital) 在医院每天治愈概率 getDeathRateHospital() / setDeathRateHospital(double deathRateHospital) 在医院每天死亡概率 getHospitalSize() / setHospitalSize(int hospitalSize) 医院床位数 getInitPatients() / setInitPatients(List<Integer> initPatients) 初始病人编号

SimResult

方法 含义 getLatents() / setLatents(int latents) 潜伏期状态人数 getDeaths() / setDeaths(int deaths) 死亡人数 getCured() / setCured(int cured) 自愈+痊愈人数 getPatients() / setPatients(int patients) 患病人数

h53 问题类似,确保你已经理解 h53。

本文尚未完成,但 h62 已经完成

考虑一个人的状态,有:健康->潜伏期->患病->自愈、治愈/死亡。

开始的思路是新建一个 Citizen 类,保存一个人的状态和活动。但模拟的时候需要另外定义许多组合,比如家庭、公司、医院等,代码复杂而且算法效率低。运行一次需要 70 多秒,结果还不对。考虑到可能是公司成员设置问题,影响效率、疫苗注射给谁,随机问题不能每次循环十万次、可不可以只保存不健康的人,每天不再循环健康者……改进后仍无果,遂改用老师的思路。

发现我改进后和老师的思路类似,只不过缺少抽象。为了减少模拟过程中的计算,应将家庭和公司抽象为地点类、医院抽象为医院类。

由于许多地方用到概率,直接在工具类中定义,提高可读性、简洁度。

家庭和公司包含成员“市民”,同时市民也包含属性“属于哪个家庭/公司”。

定义 boolean 变量时,应使用过去分词或形容词,调用它的方法名为 is...

潜伏期默认为 -1 更好。

市民不用写多个“spendOneDay”,写一个分多情况就可以。

判断一个人是否得病,可以抽象为一个方法,属于一个市民。

潜伏期在家或在公司都会传染其他人,而且过了潜伏期,如果在家等待床位,也会传染其他人。所以判断家庭和公司内是否有传染源,需要不同的判断方式。

抽象的好处,住院的病人和等待住院的病人都可以放在 Hospital 类中。

疫苗注射人数可以不准确,直接对一个人按概率注射。

果然设置公司用到了 shuffle

之前模拟一天的市民感染需要住院、患者治愈或自愈需要出院移动到 Hospital 中。

以前从个体考虑,很复杂;现在从整体考虑,并加以抽象,更简单。

传染给公司其他人,不再从传染源考虑,而是从公司考虑,每天查看公司里面是否有传染源,家庭同理;之前每个人判断他的同事,现在公司抽象为一个带有 id 的类。一个人每天如果健康则判断周围环境有无传染源、如果处于潜伏期则潜伏期增长一天并判断是否超过一定天数患病(患病则直接在家等待)、如果在家或在医院等待则判断是否自愈/治愈或死亡。

上层类调用下层类的实例,可以将自身传参过去,这样下层类就可以访问上层类了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK