Я хочу генерировать случайные числа в соответствии с некоторыми распределениями. Как я могу это сделать?
Стандартный генератор случайных чисел, который у вас есть ( rand ()
в C после простого преобразования, эквиваленты на многих языках) является довольно хорошим приближением к равномерному распределению в диапазоне [0,1 ]. Если это то, что вам нужно, все готово. Также тривиально преобразовать это в случайное число, сгенерированное в несколько большем целочисленном диапазоне.
Преобразование равномерного распределения в нормальное распределение уже рассматривалось в SO , как и переход к экспоненциальному распределению .
[РЕДАКТИРОВАТЬ]: Для треугольного распределения преобразование равномерной переменной относительно просто (во что-то вроде C):
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, чтобы получить случайное значение с желаемым распределение.
На самом деле это зависит от дистрибутива. Самый общий способ следующий. Пусть P (X) будет вероятностью того, что случайное число, сгенерированное в соответствии с вашим распределением, меньше X.
Вы начинаете с генерации равномерного случайного числа X между нулем и единицей. После этого вы найдете Y такое, что P (Y) = X, и выведите Y. Вы можете найти такой Y, используя двоичный поиск (поскольку P (X) является возрастающей функцией X).
Это не очень эффективно, но работает для распределений, в которых можно эффективно вычислить P (X).