编程模拟250永动机¶
设定, 在后期开放了所有种类的疾病的情况下, 刷新出来的病人是什么疾病是完全随机的, 在本次模拟中, 每种疾病的病人刷新 1000 个, 分别在医生技能平均等级为 1, 3, 5 级的情况下, 计算各个房间的访问量 (人次) 到底是多少, 从而推断出各种房间需要的比例是多少.
# -*- coding: utf-8 -*-
import random
from two_point_hospital.tsv_gz import make_gzip, read_compressed_tsv
tsv_filename = "disease-diagnose-and-treatment.tsv"
make_gzip(this_file=__file__, filename=tsv_filename)
df = read_compressed_tsv(this_file=__file__, filename=tsv_filename + ".gz")
columns = [
"疾病",
"全科",
"综合诊断", "心脏病科", "病房", "精神科", "体液分析", "X光", "磁共振", "DNA",
"重访全科"
]
all_rooms = columns[1:-1]
columns_percentage_type = columns[1:]
columns_secondary_diagnose = columns[2:-1]
# 将百分比字符串数据转化成小数
for c in columns_percentage_type:
df[c] = df[c].apply(lambda x: float(x[:-1]) / 100)
df.index = df["疾病"]
df = df.sort_values("全科", ascending=True) # 从
# 计算每个疾病的最二级诊所列表
ignore_x_raw = True # 由于 X光 可以不造, 因为任何病 X光 最多只是和其他房间并列最优
disease_room_candidate = dict()
for _, row in df.iterrows():
disease = row["疾病"]
l = [
(room, row[room])
for room in columns_secondary_diagnose
]
max_rate = max([rate for _, rate in l])
if ignore_x_raw:
room_candidate = [room for room, rate in l if ((rate == max_rate) and (room != "X光"))]
else:
room_candidate = [room for room, rate in l if rate == max_rate]
disease_room_candidate[disease] = room_candidate
n_disease = df.shape[0]
class Config(object):
# 全科诊断室 按照 5 级全科技能
# 磁共振 按照 1 级放射 4 级诊断
# DNA 按照 1 级 DNA, 4 级治疗
# 病房和精神病科按照 5 级别 病房管理 或 精神病学
# 综合诊断, 心脏病科, 体液分析 按照 5 级诊断
员工级别 = 1
全科药柜数量 = 0 # 全科单独拿出来, 因为可以全科堆大量药柜尽量保证一次诊断成功
诊断室药柜数量 = 0 # 对 病房, 精神病室, 综合诊断, 心脏病科 有效, 假设数量都一样
诊断室器材升级 = 0 # 最高 2, 对 综合诊断, 心脏病科, 体液分析, 磁共振, DNA 有效
每种疾病的病人人数 = 1000
治疗所需最低诊断 = 0.9
def __init__(self):
self.counts = {
room: 0
for room in all_rooms
}
@property
def 全科诊断加成(self):
医生加成 = 0.7 + self.员工级别 * 0.1 + self.员工级别 * 0.2
药柜加成 = 1 + self.全科药柜数量 * 0.01
return 医生加成 * 药柜加成
@property
def 综合和心脏病科诊断加成(self):
护士加成 = 0.7 + self.员工级别 * 0.1 + self.员工级别 * 0.1
药柜加成 = 1 + self.诊断室药柜数量 * 0.01
器材加成 = 1 + 0.25 * self.诊断室器材升级
return 护士加成 * 药柜加成 * 器材加成
@property
def 病房或精神病诊断加成(self):
"""
计算公式和全科一样, 因为都是每级20%
"""
return self.全科诊断加成
@property
def 体液分析诊断加成(self):
护士加成 = 0.7 + self.员工级别 * 0.1 + self.员工级别 * 0.1
器材加成 = 1 + 0.25 * self.诊断室器材升级
return 护士加成 * 器材加成
@property
def 磁共振诊断加成(self):
医生加成 = 0.7 + self.员工级别 * 0.1 + (self.员工级别 - 1) * 0.1
器材加成 = 1 + 0.25 * self.诊断室器材升级
return 医生加成 * 器材加成
@property
def DNA诊断加成(self):
医生加成 = 0.7 + self.员工级别 * 0.1 # 因为一般 DNA 里面的医生全加治疗, 因为治疗很难
器材加成 = 1 + 0.25 * self.诊断室器材升级
return 医生加成 * 器材加成
@property
def 一次诊断直接治疗所需全科基础诊断率(self, 送诊最低概率=0.9):
return 送诊最低概率 / self.全部加成
def simulate(self, 送诊最低概率=0.9):
"""
模拟大量随机病人进入医院, 造访所有房间的次数.
"""
multiplier_mapper = {
"全科": self.全科诊断加成,
"综合诊断": self.综合和心脏病科诊断加成,
"心脏病科": self.综合和心脏病科诊断加成,
"体液分析": self.体液分析诊断加成,
"病房": self.病房或精神病诊断加成,
"精神科": self.病房或精神病诊断加成,
"磁共振": self.磁共振诊断加成,
"DNA": self.DNA诊断加成,
}
patient_id = 0
patient_passed_room = {
i: 0
for i in range(1, 1 + self.每种疾病的病人人数 * n_disease)
}
room_visited = {
room: 0
for room in all_rooms
}
for disease, row in df.iterrows():
row = dict(row)
for _ in range(self.每种疾病的病人人数):
patient_id += 1
# 一个实际的病人样本诞生
current_diagnose_perc = 0 # 用于监视当前总诊断率
current_diagnose_perc += (row["全科"] * multiplier_mapper["全科"])
room_visited["全科"] += 1
patient_passed_room[patient_id] += 1
for _ in range(10):
if current_diagnose_perc < 送诊最低概率:
room_candidate = disease_room_candidate[disease]
room = random.choice(room_candidate)
current_diagnose_perc += (row[room] * multiplier_mapper[room]) # 访问二级诊端室
current_diagnose_perc += (row["重访全科"] * multiplier_mapper["全科"]) # 回访全科
patient_passed_room[patient_id] += 2
room_visited[room] += 1
room_visited["全科"] += 1
else:
patient_passed_room[patient_id] += 1 # 前往治疗
try:
room_visited[row["科室"]] += 1
except:
room_visited[row["科室"]] = 1
break
# break
# break
# reformat room_visited
total_visits = sum(list(room_visited.values()))
room_visited["全科初诊"] = n_disease * self.每种疾病的病人人数
room_visited["全科返诊"] = room_visited["全科"] - n_disease * self.每种疾病的病人人数
for key, value in sorted(room_visited.items(), key=lambda x: x[1], reverse=True):
perc_text = "%.2f%%" % (value * 1.0 / total_visits * 100,)
print("%s\t%s" % (key, perc_text))
Config.员工级别 = 1
Config.全科药柜数量 = 15
Config.诊断室药柜数量 = 10
Config.诊断室器材升级 = 0
Config.每种疾病的病人人数 = 1000
config = Config()
config.simulate()
员工级别 = 1, 全科药柜数量 = 15, 诊断室药柜数量 = 10, 诊断器材升级 = 0, 每种病人各来 1000 人:
全科 50.00%
全科返诊 29.76%
全科初诊 20.24%
DNA 9.43%
磁共振 7.67%
体液分析 5.44%
精神科 4.27%
病房 4.23%
综合诊断 3.11%
心脏病科 3.04%
注射室 2.48%
外科学 2.07%
骨科病房 2.07%
药房 2.07%
折疗室 0.41%
破伊学 0.41%
拔头室 0.41%
分辨率实验室 0.41%
电疗诊所 0.41%
色疗室 0.41%
小丑诊所 0.41%
流行锅实验室 0.41%
有害动物防治 0.41%
脱光诊所 0.41%
X光 0.00%
员工级别 = 3, 全科药柜数量 = 15, 诊断室药柜数量 = 10, 诊断器材升级 = 2, 每种病人各来 1000 人:
全科 50.00%
全科初诊 30.25%
全科返诊 19.75%
DNA 8.45%
磁共振 5.55%
精神科 5.17%
病房 4.68%
注射室 3.70%
体液分析 3.70%
外科学 3.09%
骨科病房 3.09%
药房 3.09%
综合诊断 1.85%
心脏病科 1.47%
折疗室 0.62%
破伊学 0.62%
拔头室 0.62%
分辨率实验室 0.62%
电疗诊所 0.62%
色疗室 0.62%
小丑诊所 0.62%
流行锅实验室 0.62%
有害动物防治 0.62%
脱光诊所 0.62%
X光 0.00%
员工级别 = 5, 全科药柜数量 = 15, 诊断室药柜数量 = 10, 诊断器材升级 = 2, 每种病人各来 1000 人:
全科 50.00%
全科初诊 35.00%
全科返诊 15.00%
DNA 8.49%
精神科 5.72%
磁共振 4.92%
病房 4.89%
注射室 4.29%
外科学 3.57%
骨科病房 3.57%
药房 3.57%
体液分析 1.62%
综合诊断 1.43%
心脏病科 0.80%
折疗室 0.71%
破伊学 0.71%
拔头室 0.71%
分辨率实验室 0.71%
电疗诊所 0.71%
色疗室 0.71%
小丑诊所 0.71%
流行锅实验室 0.71%
有害动物防治 0.71%
脱光诊所 0.71%
X光 0.00%