Как генерировать дискретные случайные события с распределением Пуассона? - PullRequest
8 голосов
/ 05 февраля 2010

Мне известен алгоритм Кнута для генерации случайных распределенных чисел Пуассона (ниже в Java), но как мне перевести это в вызов метода, generateEvent(), случайным образом по времени?

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;
}

Ответы [ 2 ]

3 голосов
/ 11 апреля 2011

Если вы хотите смоделировать время прибытия между событиями, вы хотите экспоненциальное распределение.

Взгляните на Генератор псевдослучайных чисел - экспоненциальное распределение

Ваш код будет выглядеть так:

// 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();
}
0 голосов
/ 15 ноября 2013

Произвольные числа Пуассона, которые вы генерируете, как упоминал Скотт, представляют частоту ваших событий. Когда у вас есть частота, вы можете подогнать их вхождения за интервал, используя второе распределение, скажем, Uniform.

Предположим, что количество событий, сгенерированных за интервал N, равно k. Тогда вам просто нужно сгенерировать (k + 1) случайных чисел, сумма которых равна N.

| <----------------------- N --------------------- ----> |
--r_0 - (событие) --- r_1 -..- (event_k) - R_ (к + 1) -

Для этого просто сгенерируйте (k + 1) случайных чисел и разделите их на их сумму, деленную на N. Первые k из этих чисел станут временными метками ваших событий.

...