Алгоритм генерации случайных чисел Пуассона и бинома?
Я огляделся вокруг, но не знаю, как это сделать.
Я нашел эту страницу, на которой в последнем абзаце написано:
Простой генератор случайных чисел, взятых из распределения Пуассона, получается по следующему простому рецепту: Если x1, x2, ... представляет собой последовательность случайных чисел с равномерным распределением между нулем и единицей, k-первое целое число, для которого произведение x1 · x2 · ... * x k+1 - λ
Я нашел другую страницу, описывающую, как генерировать биномиальные числа, но я думаю, что она использует аппроксимацию генерации Пуассона, которая мне не помогает.
Например, рассмотрим биномиальные случайные числа. Биномиальное случайное число - это число Орлов в N бросках монеты с вероятностью p Орлов при любом одиночном броске. Если вы сгенерируете N однородных случайных чисел на интервале (0,1) и посчитаете число меньше p, то подсчет будет биномиальное случайное число с параметрами N и p.
Я знаю, что для этого существуют библиотеки, но я не могу их использовать, только стандартные однородные генераторы, предоставляемые языком (java, в данном случае).
4 ответов:
Распределение Пуассона
Вот как Википедия говорит, что кнут говорит это сделать :
init: Let L ← e^(−λ), k ← 0 and p ← 1. do: k ← k + 1. Generate uniform random number u in [0,1] and let p ← p × u. while p > L. return k − 1.В Java это будет:
public static int getPoisson(double lambda) { double L = Math.exp(-lambda); double p = 1.0; int k = 0; do { k++; p *= Math.random(); } while (p > L); return k - 1; }
Биномиальное распределение
Переходя к главе 10 из неравномерная генерация случайных вариаций (PDF) Люком Девройе (который я нашел связанным с статьей Википедии ) дает следующее:
public static int getBinomial(int n, double p) { int x = 0; for(int i = 0; i < n; i++) { if(Math.random() < p) x++; } return x; }
Пожалуйста, обратите внимание
Ни один из этих алгоритмов не является оптимальным. Первый составляет o(λ), второй O (n). В зависимости от того, насколько велики эти значения обычно, и как часто вам нужно вызывать генераторы, вам может понадобиться лучший алгоритм. В статье, на которую я ссылаюсь выше, есть более сложные алгоритмы, которые работают в постоянном времени, но я оставлю эти реализации в качестве упражнения для читателя. :)
Для этой и других числовых задач Библия - это книга числовых рецептов.
Здесь есть бесплатная версия для C: http://www.nrbook.com/a/bookcpdf.php (требуется плагин)
Или вы можете увидеть его на google books: http://books.google.co.uk/books?id=4t-sybVuoqoC&lpg=PP1&ots=5IhMINLhHo&dq=numerical%20recipes%20in%20c&pg=PP1#v=onepage&q=&f=false
Код C должен быть очень легко перенесен на Java.
Эта книга стоит на вес золота. для множества численных задач. На вышеуказанном сайте вы также можете приобрести последнюю версию книги.
Хотя ответ, опубликованный Кипом, идеально подходит для генерации Пуассоновских RV с малой скоростью поступления (лямбда), второй алгоритм, опубликованный в Википедии , генерирующий Пуассоновские случайные величины, лучше подходит для большей скорости поступления из-за численной стабильности.
Из-за этого я столкнулся с проблемами при реализации одного из проектов, требующего генерации Пуассоновских RV с очень высокой лямбдой. Поэтому я предлагаю другой путь.
Существует несколько реализаций CERN в следующей библиотеке (Java-код):
Http://acs.lbl.gov/~hoschek/Кольт/
Что касается биномиальных случайных чисел, то он основан на статье 1988 года "генерация биномиальных случайных переменных", которую я рекомендую вам, поскольку они используют оптимизированный алгоритм.
С уважением
Comments