t | mean_iat | |
---|---|---|
0 | 0 | 15 |
1 | 60 | 15 |
2 | 120 | 20 |
3 | 180 | 23 |
4 | 240 | 25 |
5 | 300 | 28 |
6 | 360 | 25 |
7 | 420 | 22 |
8 | 480 | 18 |
9 | 540 | 16 |
10 | 600 | 15 |
11 | 660 | 13 |
12 | 720 | 10 |
13 | 780 | 8 |
14 | 840 | 10 |
15 | 900 | 11 |
16 | 960 | 8 |
17 | 1020 | 8 |
18 | 1080 | 7 |
19 | 1140 | 6 |
20 | 1200 | 9 |
21 | 1260 | 11 |
22 | 1320 | 13 |
23 | 1380 | 14 |
15 Modelling Variable Arrival Rates
It is often the case that arrivals to a system do not occur completely regularly throughout the day.
For example, in an emergency department, we may find that the number of arrivals climb in the afternoon and early evening before dropping off again overnight.
One way to implement this is to return to the sim-tools
package by Tom Monks, which we used in (Chapter 12): Choosing Distributions and Chapter 13: Reproducibility. We will use a class that creates a non-stationary poisson process via thinning.
15.1 The principle used
The documentation of the in sim tools says the following about the approach we will be using. > Thinning is an acceptance-rejection approach to sampling inter-arrival times (IAT) from a time dependent distribution where each time period follows its own exponential distribution.
The NSPP thinning class takes in a dataframe with two columns: - the first, called ‘t’, is a list of time points at which the arrival rate changes - the second, called ‘arrival_rate’, is the arrival rate in the form of the average inter-arrival time in time units
Let’s look at an example of the sort of dataframe we would create and pass in.
Let’s add a few more columns so we can better understand what’s going on.
t | time_minutes | mean_iat | arrival_rate | arrivals_per_hour | |
---|---|---|---|---|---|
0 | 0 | 00:00:00 | 15 | 1/15 | 4.0 |
1 | 60 | 01:00:00 | 15 | 1/15 | 4.0 |
2 | 120 | 02:00:00 | 20 | 1/20 | 3.0 |
3 | 180 | 03:00:00 | 23 | 1/23 | 2.6 |
4 | 240 | 04:00:00 | 25 | 1/25 | 2.4 |
5 | 300 | 05:00:00 | 28 | 1/28 | 2.1 |
6 | 360 | 06:00:00 | 25 | 1/25 | 2.4 |
7 | 420 | 07:00:00 | 22 | 1/22 | 2.7 |
8 | 480 | 08:00:00 | 18 | 1/18 | 3.3 |
9 | 540 | 09:00:00 | 16 | 1/16 | 3.8 |
10 | 600 | 10:00:00 | 15 | 1/15 | 4.0 |
11 | 660 | 11:00:00 | 13 | 1/13 | 4.6 |
12 | 720 | 12:00:00 | 10 | 1/10 | 6.0 |
13 | 780 | 13:00:00 | 8 | 1/8 | 7.5 |
14 | 840 | 14:00:00 | 10 | 1/10 | 6.0 |
15 | 900 | 15:00:00 | 11 | 1/11 | 5.5 |
16 | 960 | 16:00:00 | 8 | 1/8 | 7.5 |
17 | 1020 | 17:00:00 | 8 | 1/8 | 7.5 |
18 | 1080 | 18:00:00 | 7 | 1/7 | 8.6 |
19 | 1140 | 19:00:00 | 6 | 1/6 | 10.0 |
20 | 1200 | 20:00:00 | 9 | 1/9 | 6.7 |
21 | 1260 | 21:00:00 | 11 | 1/11 | 5.5 |
22 | 1320 | 22:00:00 | 13 | 1/13 | 4.6 |
23 | 1380 | 23:00:00 | 14 | 1/14 | 4.3 |
Let’s visualise this in a graph.
The key things to note here are
- A higher inter-arrival time means there are fewer arrivals per hour
- We store the time as a number of simulation units. Here we are interpreting this as the number of minutes, but we could correspond this instead to days, which we will do in a later example.
The NSPP thinning class uses this table to do a few things
- set up an exponential distribution using the highest observed arrival rate.
- works out the time interval between our dataframe rows
Let’s first look at 20,000 samples taken from the exponential distribution that is set up using the maximum arrival rate (1 divided by the lowest inter-arrival time).
Now let’s take a look at the distribution that is generated when the code thinks the simulation time is 480.
The index of the row to return from the dataframe - is 8
The value of lambda at this time is 0.05555555555555555
Let’s repeat this for all the different time periods in our dataset.