Example #1
0
class MMSQueueModel(object):
    '''
    MMS Queue Model
    
    Very simple queuing simulation model.
    '''
    def __init__(self, args):
        self.env = simpy.Environment()
        self.mean_arrivals = args.mean_arrivals
        self.mean_delay = args.mean_delay
        self.servers = simpy.Resource(self.env, capacity=args.n_servers)
        self.entities = []
        self._rand = RandomState()
        
        
    def source(self, warm_up):
        """Create new entities until the sim time reaches end"""
        while True:
            iat = self._rand.exponential(self.mean_arrivals)
            yield self.env.timeout(iat) 
            
            arrival = Entity(self.env, self.servers, self.mean_delay)
            if self.env.now >= warm_up:
                self.entities.append(arrival)
            self.env.process(arrival.enter_queue())
            
    def run(self, run_length=1440, warm_up=0):
        """Start model run"""
        self.q_lengths = []

        self.env.process(self.source(warm_up))
        self.env.process(observe_queue(self.env, self.servers,
                                            120, self.q_lengths))
        self.env.run(until=run_length+warm_up)
Example #2
0
class OBPatientGenerator(object):
    """ Generates patients.

        Set the "out" member variable to the resource at which patient generated.

        Parameters
        ----------
        env : simpy.Environment
            the simulation environment
        adist : function
            a no parameter function that returns the successive inter-arrival times of the packets
        initial_delay : number
            Starts generation after an initial delay. Default = 0
        stoptime : number
            Stops generation at the stoptime. Default is infinite

    """
    def __init__(self,
                 env,
                 arr_stream,
                 arr_rate,
                 initial_delay=0,
                 stoptime=250,
                 debug=False):
        self.id = id
        self.env = env
        self.arr_rate = arr_rate
        self.arr_stream = arr_stream
        self.initial_delay = initial_delay
        self.stoptime = stoptime
        self.debug = debug
        self.num_patients_created = 0

        self.prng = RandomState(RNG_SEED)

        self.action = env.process(
            self.run())  # starts the run() method as a SimPy process

    def run(self):
        """The patient generator.
        """
        # Delay for initial_delay
        yield self.env.timeout(self.initial_delay)
        # Main generator loop that terminates when stoptime reached
        while self.env.now < self.stoptime:
            # Delay until time for next arrival
            # Compute next interarrival time
            iat = self.prng.exponential(1.0 / self.arr_rate)
            yield self.env.timeout(iat)
            self.num_patients_created += 1
            # Create new patient
            obp = OBpatient(self.env.now,
                            self.arr_stream,
                            patient_id=self.num_patients_created,
                            prng=self.prng)
            # Create a new flow instance for this patient. The OBpatient object carries all necessary info.
            obflow = obpatient_flow(env, obp, self.debug)
            # Register the new flow instance as a SimPy process.
            self.env.process(obflow)
Example #3
0
class Entity(object):
    '''
    Entity that moves through queuing and service
    in the model.
    '''
    def __init__(self, env, servers, mean_delay, random_state=None):
        self.env = env
        self.servers = servers
        self.mean_delay = mean_delay
        self.wait = 0.0
        self._rand = RandomState(seed=random_state)
        
        
    def enter_queue(self):
        self.arrive = self.env.now
        with self.servers.request() as server:
            yield server
            self.wait = self.env.now - self.arrive
            
            delay = self._rand.exponential(1 / self.mean_delay)
            yield self.env.timeout(delay)
class SimpleMonteCarloED(object):
    '''
    SimpleMonteCarloED.

    A very simple monte carlo ED
    
    For a given no. of patients simulate
    1. Triage assessment and treatment process time
    2. Admit or not admit
    3. For admitted patients only - delay in admission.
    '''
    def __init__(self, params, random_state=None):
        '''
        Constructor for SimpleMonteCarlosED
        
        Parameters:
        -------
        params - ScenarioParmaeters, dataclass for sim model
        
        random_state - int, random seed. Allows for common random
        numbers to be used across multiple versions of the same model and
        reduces the noise in comparisons. (detault=None.)
        '''
        self._params = params
        self._rs = RandomState(random_state)

    def simulate(self, n_patients):
        '''Performa a single replications/run of the simuation model

        Params:
        -------
        n_patients - int, no. of patients to simulate.
        '''
        process_times = self._simulate_ed_process_times(n_patients)
        admissions = self._simulate_admission(n_patients)
        admit_delays = self._simulate_dta_times(n_patients)

        #total time in ED for admitted patients
        ed_times_admit = process_times[admissions == 1] \
            + admit_delays[admissions == 1]
            
        #total time in ED for non-admitted patients    
        ed_times_not_admit = process_times[admissions == 0] 

        #distribution of ed times.
        return np.append(ed_times_admit, ed_times_not_admit)

    def _simulate_ed_process_times(self, n_patients):
        '''
        simulate ed process times for n patients
        '''
        return self._rs.exponential(self._params.mean_process_time, 
                                     size=n_patients)

    def _simulate_admission(self, n_patients):
        '''simulate admission Y/N for n patients
        '''
        return self._rs.binomial(n=1,
                                p=self._params.p_admit, 
                                size=n_patients)

    def _simulate_dta_times(self, n_patients):
        '''simulate admission delays for n patients
        '''
        return self._rs.exponential(self._params.mean_dta, 
                                    size=n_patients)
Example #5
0
class OBPatientGenerator(object):
    """ Generates patients.

        Set the "out" member variable to resource at which patient generated.

        Parameters
        ----------
        env : simpy.Environment
            the simulation environment
        arr_rate : float
            Poisson arrival rate (expected number of arrivals per unit time)
        patient_type : int
            Patient type id (default 1). Currently just one patient type.
            In our prior research work we used a scheme with 11 patient types.
        arr_stream : int
            Arrival stream id (default 1). Currently there is just one arrival
            stream corresponding to the one patient generator class. In future,
            likely to be be multiple generators for generating random and
            scheduled arrivals
        initial_delay : float
            Starts generation after an initial delay. (default 0.0)
        stoptime : float
            Stops generation at the stoptime. (default Infinity)
        max_arrivals : int
            Stops generation after max_arrivals. (default Infinity)
        debug: bool
            If True, status message printed after
            each patient created. (default False)

    """

    def __init__(self, env, arr_rate, patient_type=1, arr_stream=1,
                 initial_delay=0,
                 stoptime=simpy.core.Infinity,
                 max_arrivals=simpy.core.Infinity, debug=False):

        self.env = env
        self.arr_rate = arr_rate
        self.patient_type = patient_type
        self.arr_stream = arr_stream
        self.initial_delay = initial_delay
        self.stoptime = stoptime
        self.max_arrivals = max_arrivals
        self.debug = debug
        self.out = None
        self.num_patients_created = 0

        self.prng = RandomState(RNG_SEED)

        self.action = env.process(
            self.run())  # starts the run() method as a SimPy process

    def run(self):
        """The patient generator.
        """
        # Delay for initial_delay
        yield self.env.timeout(self.initial_delay)
        # Main generator loop that terminates when stoptime reached
        while self.env.now < self.stoptime and \
                        self.num_patients_created < self.max_arrivals:
            # Delay until time for next arrival
            # Compute next interarrival time
            iat = self.prng.exponential(1.0 / self.arr_rate)
            yield self.env.timeout(iat)
            self.num_patients_created += 1
            # Create new patient
            obp = OBPatient(self.env.now, self.num_patients_created,
                            self.patient_type, self.arr_stream,
                            prng=self.prng)

            if self.debug:
                print("Patient {} created at {:.2f}.".format(
                    self.num_patients_created, self.env.now))

            # Set out member to OBunit object representing next destination
            self.out = obunits[obp.planned_route_stop[1]]
            # Initiate process of requesting first bed in route
            self.env.process(self.out.put(obp))
Example #6
0
def exponential_lik(X: ndarray, rng: RandomState):
    return rng.exponential(X)