8

I'm aware of Knuth's algorithm for generating random Poisson distributed numbers (below in Java) but how do I translate that into calling a method, generateEvent(), randomly over time?

int poissonRandomNumber(int lambda) {
    double L = Math.exp(-lambda);
    int k = 0;
    double p = 1;
    do {
        k = k + 1;
        double u = Math.random();
        p = p * u;
    } while (p > L);
    return k - 1;
}
danodonovan
  • 19,636
  • 10
  • 70
  • 78
blank
  • 17,852
  • 20
  • 105
  • 159

2 Answers2

4

If you are looking to simulate the inter-event arrival time, you want the exponential distribution.

Take a look at Pseudorandom Number Generator - Exponential Distribution

Your code would then look like this:

// Note L == 1 / lambda
public double poissonRandomInterarrivalDelay(double L) {
    return (Math.log(1.0-Math.random())/-L;
}

...

while (true){
    // Note -- lambda is 5 seconds, convert to milleseconds
    long interval= (long)poissonRandomInterarrivalDelay(5.0*1000.0);
    try {
        Thread.sleep(interval);
        fireEvent();
}
Community
  • 1
  • 1
Jay Elston
  • 1,978
  • 1
  • 19
  • 38
  • Hi, I need to generate random numbers in Poisson interval rate using java.. I tried using your function and method poissonRandomInterarrivalDelay always returns zero for any value of lambda. – Learner May 15 '13 at 17:55
  • 4
    This implementation for `poissonRandomInterarrivalDelay()` is faulty. As written it will give negative results whenever `Math.random()` generates a value less than `Math.exp(-lambda)`. A correct implementation is: `return Math.log(1.0-Math.random())/-lambda;`. You can simplify this to `return Math.log(Math.random())/-lambda;` since `1.0-Math.random()` is uniformly distributed between 0 and 1. – pjs Jun 21 '13 at 17:11
  • Is lambda inverted in your example? Shouldn't 5.0*1000.0 instead be 1/(5.0*1000.0)? – tnunamak Feb 04 '14 at 04:59
  • 1
    @tnunamak -- You are correct, using lambda as the name of the input parameter is not correct. I was thinking that the input parameter would be the average inter-arrival time. I modified the example somewhat to make this more clear. – Jay Elston Feb 12 '14 at 01:09
  • since L is 1/lambda the formula should be (Math.log(1.0-Math.random())*-L) – jsh May 30 '18 at 20:22
0

The Poisson random numbers you are generating, as Scott mentioned, represent the frequency of your events. Once you have the frequency, you can fit their occurrences over the interval using a second distribution, say Uniform.

Suppose the number of events generated for an interval of N is k. Then you simply need to generate (k+1) random numbers that sum to N.

|<----------------------- N ------------------------->|
--r_0--(event)---r_1-..-(event_k)--r_(k+1)--

To do so, simply generate (k+1) random numbers and divide them by their sum, divided by N. The first k of these numbers become the timestamps of your events.

er0
  • 1,746
  • 2
  • 16
  • 31