首页 > 解决方案 > SimPy 中的接收器状态

问题描述

我正在探索SimPy通过护理流程模拟患者流程。在模拟模型中,患者要么接受治疗,要么死亡。显然,这些都是相互竞争的风险,患者死后应该无法接受治疗。但是,我对 SimPy 还很陌生,我还没有发现如何为水槽建模,这样这些已故的患者就无法继续进行模拟。

我比较熟悉 中的simmerR,在里面可以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.

标签: pythonsimpy

解决方案


有两种主要的模拟类型 经典的实体流,其中站点拥有所有逻辑,而实体很少,站点决定实体的命运。实体/代理拥有所有代码并决定自己命运的代理基地。

实体流的经典示例是制造生产线,其中工作站/机器决定对实体做什么以及下一步将其发送到哪里(分支到)。您的 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)

推荐阅读