疾病传播模拟
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。
考虑一个人的状态,有:健康->潜伏期->患病->自愈、治愈/死亡。
开始的思路是新建一个 Citizen
类,保存一个人的状态和活动。但模拟的时候需要另外定义许多组合,比如家庭、公司、医院等,代码复杂而且算法效率低。运行一次需要 70 多秒,结果还不对。考虑到可能是公司成员设置问题,影响效率、疫苗注射给谁,随机问题不能每次循环十万次、可不可以只保存不健康的人,每天不再循环健康者……改进后仍无果,遂改用老师的思路。
发现我改进后和老师的思路类似,只不过缺少抽象。为了减少模拟过程中的计算,应将家庭和公司抽象为地点类、医院抽象为医院类。
由于许多地方用到概率,直接在工具类中定义,提高可读性、简洁度。
家庭和公司包含成员“市民”,同时市民也包含属性“属于哪个家庭/公司”。
定义 boolean
变量时,应使用过去分词或形容词,调用它的方法名为 is...
。
潜伏期默认为 -1 更好。
市民不用写多个“spendOneDay”,写一个分多情况就可以。
判断一个人是否得病,可以抽象为一个方法,属于一个市民。
潜伏期在家或在公司都会传染其他人,而且过了潜伏期,如果在家等待床位,也会传染其他人。所以判断家庭和公司内是否有传染源,需要不同的判断方式。
抽象的好处,住院的病人和等待住院的病人都可以放在 Hospital
类中。
疫苗注射人数可以不准确,直接对一个人按概率注射。
果然设置公司用到了 shuffle
。
之前模拟一天的市民感染需要住院、患者治愈或自愈需要出院移动到 Hospital
中。
以前从个体考虑,很复杂;现在从整体考虑,并加以抽象,更简单。
传染给公司其他人,不再从传染源考虑,而是从公司考虑,每天查看公司里面是否有传染源,家庭同理;之前每个人判断他的同事,现在公司抽象为一个带有 id 的类。一个人每天如果健康则判断周围环境有无传染源、如果处于潜伏期则潜伏期增长一天并判断是否超过一定天数患病(患病则直接在家等待)、如果在家或在医院等待则判断是否自愈/治愈或死亡。
上层类调用下层类的实例,可以将自身传参过去,这样下层类就可以访问上层类了。