4
$\begingroup$

I'm interested in generating random arrivals that should simulate the call arrivals of a call center. I chose to use a Poisson distribution, but the greatest problem comes with the fact that it's a discrete distribution.

So I thought that I could use it to generate an arrival rate in a time frame of 1 second; this way every second I re-compute the arrival rate, and spread every call in this frame of time.

But the problem is: to generate calls with a realistic rate, how should I "spread" the calls? I mean: if for example between a time frame of [4.0, 5.0], the generated arrival rate is 5, to just generate every calls every 0.2 seconds (arrivals: 4.0,4.2,4.4,4.6,4.8) is unrealistic.

A second problem comes with the fact that in reality the variance is much greater than the mean, but in a poisson process they're equal. A workaround could be to general arrival rates in a larger time frame, so that the variance increases, but this would make the process not homogeneous. Suggestions?

$\endgroup$
2
  • $\begingroup$ Do you want to generate a set of counts (eg, 9 calls came in Tuesday), or a set of times (eg, a call a 8:53 am, 9:45 am, etc)? $\endgroup$ Commented Feb 4, 2015 at 22:21
  • 1
    $\begingroup$ See stats.stackexchange.com/questions/129322/… for a detailed solution with step-by-step explanations. The Poisson arrival times are generated all at once with the single line of R code CUSTOMERS["Arrived", ] <<- cumsum(round(rexp(n.events, arrival.rate), 2)) $\endgroup$
    – whuber
    Commented Feb 4, 2015 at 22:50

3 Answers 3

4
$\begingroup$
  1. If it's a Poisson process, the inter-call time is exponential with mean equal to the inverse of the rate. It's probably easier at each step to simply generate the time to the next call than generate a number of calls in an interval and then try to place them in that interval.

    If you really want do it the way you were saying, you'd use a uniform distribution to place their time within each interval. Just generate a standard random uniform for each one, and that's the fraction of the way through the interval that it happened at.

  2. You can get larger variance either because there's heterogeneity of rates or because of some kind of dependence. You need to consider which change from a Poisson process might be more appropriate for your situation, and in what manner.

For example, you can get heterogeneity of rates because different time periods just tend to get more calls (e.g. more calls per hour in the late afternoon than the early morning). Or calls might tend to come in clusters (e.g. a TV ad might generate a burst of calls, but the appearance of the ad might happen any time). Or people might often tend to call back several times within a single day, but then not call again for a long time.

$\endgroup$
3
  • 1
    $\begingroup$ +1 Method (1) (accumulating independent exponential variates) is readily adapted to inhomogeneous Poisson processes where the rate is a function of the time (or of any other information available within the simulation up to that time): just compute the current value of the rate and generate the time to the next event using that rate. $\endgroup$
    – whuber
    Commented Feb 4, 2015 at 22:54
  • 2
    $\begingroup$ I still seem to be typing 'homo' when I mean 'hetero'. I don't know what the source of that particular tendency is. Good thing this isn't a dating site. $\endgroup$
    – Glen_b
    Commented Feb 4, 2015 at 23:08
  • $\begingroup$ @Glen_b comment of the year. $\endgroup$
    – Sycorax
    Commented Feb 5, 2015 at 0:25
1
$\begingroup$

The key to efficiently generating poisson distributed events is to realize the any number of events that exist within any interval occur independently. In other words,the occurrence time of each event is uniformly distributed in the interval. Each of n events with average arrival rate of mu occur uniformly in the interval (0 to n/mu). Simply generate n events randomly in this interval. Then place them in an ordered array.

Let mu equal the arrival rate per time interval. Let n equal the number of events to generated. The total time span is n/mu. The time distribution of events will approximate the Poisson distribution as n approaches infinity. In Python the algorithm is as follows:

#generate 10000 events with a mu of 5.0 events per unit time
import random
#n is the number of events to generate.
mu=5.0 
n=10000
#time span is n/mu
time_span=n/mu
events=[]
#place n events uniformly distributed and place in array events.
for j in range(0,n)  :
    events.append(random.random())
#sort the array
events.sort()

#at this point the events array contains n events distributed from 
#(0.0 to 1.0). The next step is to scale the timing of all events by multiplying 
#by n/mu which is the total time span of events.
for j in range(0,n)  :
    events[j]*=time_span
#The events array now contains an array of event times which are approximate the #Poisson distribution with a mean arrival rate of mu per time interval.
#This has been tested using a chi squared test and closely approximates the 
#Poisson Distribution.
$\endgroup$
1
$\begingroup$

It’s not an integer arrival time. Calls may arrive at any millisecond or nanosecond.

Where f is random between zero and one -ln(f) is the time until the next arrival if the average arrival time is 1.0 per unit of time. If a is the average arrival time the next arrival is -ln(f)/a. (If the arrival rate doubles, the average arrival time is cut in half.)

Say you want simulated 5-minute intervals. Sum the -ln(-f)/a values until the sum>= 5 minutes while counting the number of iterations. Subtract 5 minutes from the sum and resume summing -ln(-f)/a counting iterations again as needed.

My thinking was radioactive decay. But the math works for any Poisson process.

import math
import random

avgCountsPerHour = 1000.0
avgCountsPerMinute = avgCountsPerHour/60

print(avgCountsPerMinute*5) #average in 5 minutes

sum=0.5 # average value after sum-=5
tbl = []
for dummy in range(0,26): #25 results
    count=0
    while (sum < 5):
        count += 1
        f = random.random()
        m = -math.log(f)
        sum += m  / avgCountsPerMinute
    tbl.append(count)
    sum -= 5
print (tbl)

83.33333333333334 [67, 78, 85, 86, 70, 83, 88, 99, 88, 82, 76, 67, 84, 72, 72, 101, 87, 77, 100, 78, 90, 77, 78, 81, 89, 87]

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.