Алгоритм для генерации случайных чисел Пуассона и биномиальных?

StackOverflow https://stackoverflow.com/questions/1241555

Вопрос

Я смотрел вокруг, но я не уверен, как это сделать.

я обнаружил эта страница Что в последнем абзаце говорит:

Простой генератор для случайных чисел, взятых из распределения Пуассона, получается с использованием этого простого рецепта: если x1, Икс2, ... - это последовательность случайных чисел с равномерным распределением между нулем и одним, k - первое целое число, для которого продукт x1 · Икс2 · ... · ИксK+1 <e

я обнаружил другая страница Описывая, как генерировать биномиальные числа, но я думаю, что он использует приближение поколения Пуассона, что мне не помогает.

Например, рассмотрим биномиальные случайные числа. Биномиальное случайное число - это количество голов в n броска монеты с вероятностью p голов на любом броске. Если вы генерируете n равномерные случайные числа на интервале (0,1) и считаете число меньше P, то число является биномиальным случайным числом с параметрами n и p.

Я знаю, что есть библиотеки, чтобы сделать это, но я не могу их использовать, только стандартные унифицированные генераторы, предоставленные языком (Java, в данном случае).

Это было полезно?

Решение

распределение Пуассона

Вот Как Википедия говорит, что Кнут говорит, чтобы сделать это:

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: http://books.google.co.uk/books?id=4t-sybvuoqoc&lpg=pp1&ots=5ihminlhho&dq=numeric%20recipes%20in%20c&pg=pp1#v=onepage&q=&f=false

Код C должен быть очень легко перевести на Java.

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

Хотя ответ, опубликованный KIP, совершенно действителен для создания RVS Poisson с небольшим количеством прибывающих (Lambda), второй алгоритм, размещенный в Википедии Генерирование случайных переменных Пуассона лучше для большей скорости прибытия из -за численной стабильности.

Я столкнулся с проблемами во время реализации одного из проектов, требующих поколения Пуассона RV с очень высокой Lambda из -за этого. Поэтому я предлагаю другой путь.

В следующей библиотеке есть несколько реализаций CERN (код Java):

http://acs.lbl.gov/~hoschek/colt/

Что касается биномиальных случайных чисел, он основан на статье от 1988 года «Биномиальное генерация случайного вариата», которую я рекомендую вам, поскольку они используют оптимизированный алгоритм.

С Уважением

Вы можете добавить это в build.gradle

implementation 'org.kie.modules:org-apache-commons-math:6.5.0.Final'

и использовать класс Распределение Пуассона Более подробная информация для класса -пусководов

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top