Генерировать случайные числа в соответствии с распределениями

Я хочу генерировать случайные числа в соответствии с некоторыми дистрибутивами. Как я могу это сделать?

Ответ 1

Стандартный генератор случайных чисел, который у вас есть (rand() в C после простого преобразования, эквиваленты на многих языках) является довольно хорошим приближением к равномерному распределению по диапазону [0,1]. Если это то, что вам нужно, все готово. Также тривиально преобразовать это в случайное число, сгенерированное в несколько большем целочисленном диапазоне.

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

[EDIT]: для треугольного распределения преобразование единой переменной относительно просто (в чем-то C-like):

double triangular(double a,double b,double c) {
   double U = rand() / (double) RAND_MAX;
   double F = (c - a) / (b - a);
   if (U <= F)
      return a + sqrt(U * (b - a) * (c - a));
   else
      return b - sqrt((1 - U) * (b - a) * (b - c));
}

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

Ответ 2

Правильный способ сделать это - разложить распределение на двоичные распределения n-1. То есть, если у вас есть такой дистрибутив:

A: 0.05
B: 0.10
C: 0.10
D: 0.20
E: 0.55

Вы преобразуете его в 4 бинарных дистрибутива:

1. A/E: 0.20/0.80
2. B/E: 0.40/0.60
3. C/E: 0.40/0.60
4. D/E: 0.80/0.20

Выберите одно из распределений n-1, а затем выберите первый или второй символ на основе вероятности, если каждый из двоичного дистрибутива.

Код для этого здесь

Ответ 3

На самом деле это зависит от распределения. Самый общий способ заключается в следующем. Пусть P (X) - вероятность того, что случайное число, генерируемое в соответствии с вашим распределением, меньше X.

Вы начинаете с создания равномерного случайного X между нулем и одним. После этого вы находите Y таким, что P (Y) = X и выводите Y. Вы можете найти такой Y, используя двоичный поиск (поскольку P (X) является возрастающей функцией X).

Это не очень эффективно, но работает для распределений, где P (X) можно было бы эффективно вычислить.

Ответ 5

Вы можете конвертировать из дискретных блоков в float/double с интерполяцией. Простая линейная работа хорошо. Если ваша память таблицы ограничена, могут использоваться другие методы интерполяции. -jlp