Генерация случайных чисел в соответствии с распределением - PullRequest
17 голосов
/ 18 августа 2010

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

Ответы [ 6 ]

18 голосов
/ 18 августа 2010

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

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

[РЕДАКТИРОВАТЬ]: Для треугольного распределения преобразование равномерной переменной является относительно простым (в чем-то С-образным):

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, чтобы получить случайное значение с желаемымраспределение.

11 голосов
/ 18 июня 2013

Правильный способ сделать это - разложить распределение на 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 дистрибутивов, а затем выберите первыйили второй символ, основанный на вероятности, если каждый в двоичном распределении.

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

4 голосов
/ 31 июля 2012

Вы можете посмотреть выборку с обратным преобразованием, выборку отклонения, а также книгу Деврой " Неоднородное генерирование случайных вариаций " / Springer Verlag 1986

4 голосов
/ 18 августа 2010

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

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

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

0 голосов
/ 01 июня 2019

Это стандартный учебник. См. здесь для некоторого кода или здесь в Разделе 3.2 для некоторого справочного математического фона (на самом деле очень быстрый и простой для чтения).

0 голосов
/ 07 марта 2017

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

...