Как генерировать дискретные случайные события с распределением Пуассона?

Мне известен алгоритм Кнута для генерации случайных распределенных чисел Пуассона (ниже в 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 ответа

Решение

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

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

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

// 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();
}

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

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

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

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

Другие вопросы по тегам