python - SimPy 中的接收器状态
问题描述
我正在探索SimPy
通过护理流程模拟患者流程。在模拟模型中,患者要么接受治疗,要么死亡。显然,这些都是相互竞争的风险,患者死后应该无法接受治疗。但是,我对 SimPy 还很陌生,我还没有发现如何为水槽建模,这样这些已故的患者就无法继续进行模拟。
我比较熟悉 中的simmer
包R
,在里面可以branch()
进行模型结构,并指定模型结构的哪个分支是死胡同。SimPy 中是否有类似的功能?还是有其他优雅的选择?
为了说明我的意思,下面是模拟模型:
from random import seed, randint
seed(123)
MAX_CYCLES = 5
PROB_DEATH = 0.2
class Patient:
def __init__(self, env, treatment_cycles = 0):
self.env = env
self.treatment_cycles = treatment_cycles
self.treatment_proc = env.process(self.get_treatment(env))
def get_treatment(self, env):
while self.treatment_cycles < MAX_CYCLES:
self.treatment_cycles += 1
rand = random.uniform(0, 1)
if (rand < PROB_DEATH):
yield env.timeout(random.randint(20, 40))
print('I have died at {}'.format(env.now))
### Once this point has been reached, patients should not be able to continue ###
else:
yield env.timeout(randint(20, 80))
print("I have completed a full cycle of treatment after {} days.".format(int(env.now)))
env = simpy.Environment()
pat = Patient(env)
env.run(until=250)
这会导致明显不受欢迎的输出:
I have died at 22
I have completed a full cycle of treatment after 59 days.
I have died at 80
I have completed a full cycle of treatment after 135 days.
I have completed a full cycle of treatment after 209 days.
解决方案
有两种主要的模拟类型 经典的实体流,其中站点拥有所有逻辑,而实体很少,站点决定实体的命运。实体/代理拥有所有代码并决定自己命运的代理基地。
实体流的经典示例是制造生产线,其中工作站/机器决定对实体做什么以及下一步将其发送到哪里(分支到)。您的 R 代码听起来像是使用这种范例
您的示例更像是实体/患者控制自己行为的代理。
要解决这个问题,您只需要在类中添加一个“状态”属性来跟踪患者是活还是死。然后在您的 while 循环中检查患者的状态
见下文:
"""
Show how to use a state variable to change behavior
programmer: Michael R. Gibbs
"""
from random import seed, randint, uniform
import simpy
seed(123)
MAX_CYCLES = 5
PROB_DEATH = 0.2
class Patient:
"""
patient seeking treatment
"""
def __init__(self, env, treatment_cycles = 0):
self.state = 'Live' # starts out as a living patient
self.env = env
self.treatment_cycles = treatment_cycles
self.treatment_proc = env.process(self.get_treatment(env))
def get_treatment(self, env):
"""
gets a treatment that can change the patient's
state from live, to dead
"""
while self.treatment_cycles < MAX_CYCLES and self.state=='Live':
# treat untile done, or patient has died
self.treatment_cycles += 1
rand = uniform(0, 1)
if (rand < PROB_DEATH):
# patient has died
yield env.timeout(randint(20, 40))
print('I have died at {}'.format(env.now))
# update state to dead
self.state = 'Dead'
### Once this point has been reached, patients should not be able to continue ###
else:
yield env.timeout(randint(20, 80))
print("I have completed a full cycle of treatment after {} days.".format(int(env.now)))
env = simpy.Environment()
pat = Patient(env)
env.run(until=250)
推荐阅读
- android - 使用 Flutter Blue 连接到 BLE 设备时出现问题
- node.js - 我无法使用 multer 上传 2 个文件
- javascript - 如何在 QuaggaJS 中使用后置摄像头而不是自拍摄像头
- r - 如何将 xtabs() 的结果转换为 R 中的数据框?
- javascript - 后台脚本和内容脚本循环通信
- python - Python 从 JSON 变量中提取值 - TypeError:字符串索引必须是整数
- php-7 - 如何在 cloudera quickstart 上安装 PHP7?
- javascript - Headless chrome print-to-pdf 错误地显示 Chart.JS javascript 画布
- python - 抽象工厂设计模式实现
- python - 用变音符号编码阿拉伯字母(如果存在)