Generate Poisson Arrival in Java
Asked Answered
P

4

6

I would like to create a function in Java that generates Poisson arrivals given the mean arrival rate (lambda) and the mean service rate (mu).

In my example I have: 2,2 requests/day, in other words 2,2 arrivals/day and a mean service time of 108 hours. Considering that my program starts at t=0 minutes, I would like to create a function that returns arrivals[], which will contain, t1, t2, and a possible t3. T1,t2 and t3 are the instants (in minutes) during the day where this arrivals occur. I have the following restrictions:

t1 < t2 < t3 < 1440 minutes (24 hours*60 minutes/hour)

t2-t1 > 108 minutes

t3-t2 > 108 minutes

t3+ 108 minutes < 1440 minutes

Can someone please help me?

Thank you,

Ana

Pointtopoint answered 23/3, 2012 at 1:16 Comment(5)
What is the specific problem that's preventing you from doing this?Keishakeisling
possible duplicate of Simulating Poisson Waiting Times - JavaDejection
Welcome to SO. Please read the faq and How to Ask for details on how to post questions here. It is considered out-of-scope to post a problem with no evidence that you've made any attempt to solve it. SO users provide answers to specific questions, but generally don't do your work for you. Also, you're expected to have searched for an answer on the web and on SO before posting.Janel
i use this answer for implement class PoissonDistribution linkRishi
i use this answer for implement class PoissonDistribution linkRishi
S
7

You can use this algorithm proposed by D. Knuth:

private static int getPoissonRandom(double mean) {
    Random r = new Random();
    double L = Math.exp(-mean);
    int k = 0;
    double p = 1.0;
    do {
        p = p * r.nextDouble();
        k++;
    } while (p > L);
    return k - 1;
}

To understand how this works note that after k iterations the loop condition becomes

p1 * p2 * ... * pk > L

which is equivalent to

-ln(p1)/mean -ln(p2)/mean ... -ln(pk)/mean > 1

Note that if p is uniformly distributed then -ln(p)/mean has exponential distribution with a given mean. A random variable with Poisson distribution is equal to the number of times a given event occurs within a fixed interval when the lengths of the intervals between events are independent random variables with exponential distribution. Since we use the mean of the Poisson distribution as the mean of the exponential distribution for the intervals between events, the fixed internal in which we count occurrences is unit length. Thus, the loop condition sums up the lengths of the intervals between events and checks whether we have gone beyond the unit interval. If we have gone beyond the unit interval while counting kth event, then k-1 events occurred within the interval and so we return k-1.

Skeg answered 23/3, 2012 at 1:26 Comment(1)
This is Knuth's method. If you can live with generating time to wait until the next event you can use this:https://mcmap.net/q/827096/-simulating-poisson-waiting-timesInclinable
I
3

I found this solution, using inverse transform sampling:

http://preshing.com/20111007/how-to-generate-random-timings-for-a-poisson-process

It doesn't use a rejection sampling approach, is efficient and accurate.

It uses the fact that the distribution of the time between events is an exponential distribution, with parameter lambda which is the arrival rate. The Exponential distribution is lambda exp(-lambda x). In order to sample values from that distribution and avoid rejection sampling, it is easier to use its Cumulative Distribution Function (CDF): 1 - exp(-lambda x). The CDF is a function that starts at 0.0 and grows to 1.0 with larget parameters. Intuitively, the probability that you will get an event increases as time passes.

To sample the CDF, and again avoid rejection sampling, it is easier to pick a uniform random number U between [0,1] and to plug that value in the inverse function of the CDF, which gives: nextEvent = - Ln(U)/lambda. Because Ln(0) is undefined, and most random number generators include 0.0 and exclude 1.0, it is safer to use: nextEvent = -Ln(1.0-U)/lambda. If your code uses a millisecond based time/sleep function you can use:

double rate = 20.0/1000.0; // 20 per second on average

sleep(floor(-1.0 * log(1.0 - rand()*1.0/RAND_MAX) / rate) );

Inclinable answered 1/11, 2012 at 19:45 Comment(1)
by far the best methodSurmise
R
1

you can add this to build.gradle

implementation 'org.kie.modules:org-apache-commons-math:6.5.0.Final'

and use class PoissonDistribution more detail

Rishi answered 17/5, 2019 at 11:49 Comment(0)
J
0

Here's some simplified code to generate a poisson number with a given mean:

private static int poisson(double mean) {
    int r = 0;
    double a = random.nextDouble();
    double p = Math.exp(-mean);

    while (a > p) {
        r++;
        a = a - p;
        p = p * mean / r;
    }
    return r;
}

You should be able to use this or something similar to generate your arrival numbers for each time period: the input should be the mean number of arrivals you expect in the period.

Note that if your mean is very large (say 500+) you will want to approximate the number of arrivals with a normal distribution instead. This is more efficient, plus it avoid numerical overflow issues inherent in the code above (at some point Math.exp(-mean) gets rounded to zero......ooops!)

Jassy answered 23/3, 2012 at 1:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.