Я работаю исходя из предположения, что вы (или ваш инструктор) хотите сделать это из первых принципов, а не просто вызывать встроенный генератор Пуассона. Алгоритм довольно прост. Вы подсчитываете, сколько экспонент вы можете сгенерировать с указанной скоростью, пока их сумма не превысит 1.
Мой R заржавел, и в любом случае это звучит как домашнее задание, поэтому я выражу его в виде псевдокода:
count <- 0
sum <- 0
repeat {
generate x ~ exp(lambda)
sum <- sum + x
if sum > 1
break
else
count <- count + 1
}
Значение count
после того, как вы break
вышли из цикла, является результатом Пуассона для этого испытания. Если вы оберните это как функцию, верните count
, а не break
ing из цикла.
Вы можете улучшить это вычислительно несколькими способами. Во-первых, обратите внимание, что член 1-U
для генерации экспонент имеет равномерное распределение и может быть заменен только U
. Более значительное улучшение достигается при записи оценки как максимизировать i
s.t. SUM(-log(Ui) / rate) <= 1
, значит SUM(log(Ui)) >= -rate
.
Теперь возведите в степень обе стороны и упростите, чтобы получить
PRODUCT(Ui) >= Exp(-rate).
Правая часть этого числа постоянна и может быть вычислена заранее, уменьшая объем работы от k+1
вычислений журнала и дополнений до одного возведения в степень и k+1
умножений:
count <- 0
product <- 1
threshold = Exp(-lambda)
repeat {
generate u ~ Uniform(0,1)
product <- product * u
if product < threshold
break
else
count <- count + 1
}
Предполагая, что вы выполняете замену U
на 1-U
для обеих реализаций, они алгебраически равны и дадут идентичные ответы с точностью до арифметики с плавающей запятой для заданного набора U
.
person
pjs
schedule
23.10.2017
rpois
для генерации случайных чисел для распределения Пуассона с параметром лямбда. - person Samuel   schedule 23.10.2017