Я хочу генерировать случайные числа в соответствии с некоторыми дистрибутивами. Как я могу это сделать?
Генерировать случайные числа в соответствии с распределениями
Ответ 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) можно было бы эффективно вычислить.
Ответ 4
Вы можете искать обратную выборку преобразований, отбор выборки, а также книгу Devroye " Неравномерная генерация случайных колебаний" /Springer Verlag 1986
Ответ 5
Вы можете конвертировать из дискретных блоков в float/double с интерполяцией. Простая линейная работа хорошо. Если ваша память таблицы ограничена, могут использоваться другие методы интерполяции. -jlp