Генерация случайного числа в диапазоне с использованием распределения Пуассона - PullRequest
0 голосов
/ 09 февраля 2019

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

В настоящее время у меня есть следующий код:

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

Мне было интересно, как я мог бы изменить его так, чтобы я мог сгенерировать x количество значений в пределах определенного диапазона, т.е. если a = 5, b = 10 и lambda = 6, все сгенерированные значения будут находиться в диапазоне от 5 до 10.

Примечание. Я могу перегрузить метод и, таким образом, принять параметры диапазона и вызвать метод getPossion впетля;отбрасывая все, что не соответствует этому диапазону.Однако я хотел бы проверить, существуют ли математически определенные средства для достижения этого и / или подходит ли этот подход.

РЕДАКТИРОВАТЬ: Средства, с помощью которых я отбрасываю значения «вне границ»:

public static int getPoisson(final double min, final double max, final double lambda) {
    int k = 0;
    do {
        k = getPoisson(lambda);
    } while (k < min || k > max);
    return k;
}

1 Ответ

0 голосов
/ 10 февраля 2019

Если вы хотите получить только несколько целых чисел в очень небольшом заданном диапазоне с заданной вероятностью с фиксированной (или редко изменяемой) лямбдой, самый простой способ - сохранить таблицы вероятностей для каждого из чисел и выполнить смещенную выборку.

Некоторыепсевдокод:

public class BoundedSampler {
  private final int min;
  private final double[] table;

  public BoundedSampler(int min, int max, double lambda) {
    this.min = min;
    this.table = new double[max - min + 1];

    double cumulative = 0;
    for(int x = min; x <= max; ++x) {
      double prob = probability(x, lambda);
      table[x - min] = cumulative + prob;
      cumulative += prob;
    }

    for(int i = 0; i < table.length; ++i) {
      table[i] /= cumulative;
    }
  }

  public int sample() {
    double r = Math.random();
    for(int i = 0; i < table.length; ++i) {
      if(table[i] <= r) {
        return i + min;
      }
    }
    return -1; // impossible: last table value == 1
  }
}

Или используйте метод псевдонима для быстрого выбора значения.

...