Как генерировать случайные числа с экспоненциальным распределением (со средним)?
Я пытаюсь сгенерировать экспоненциально распределенное случайное число со средним значением, равным 1. Я знаю, как получить случайное число для нормального распределения со средним и стандартным отклонением. Мы можем получить это по normal(mean, standard_deviation)
, но я не знаю, как получить случайное число для экспоненциального распределения.
Кто-нибудь может мне с этим помочь?
2 ответа
С C++11 стандарт фактически гарантирует, что существует ГСЧ, отвечающая требованиям экспоненциального распределения, доступного в STL, и, соответственно, тип объекта имеет очень описательное имя.
Среднее в экспоненциально распределенном случайном генераторе вычисляется по формуле E[X] = 1 / lambda
1
std::exponential_distribution
имеет конструктор, принимающий лямбду в качестве аргумента, поэтому мы можем легко создать объект, следуя вашим правилам, вычислив значение лямбды и передав его в наш генератор.
std::exponential_distribution rng (1/1); // lambda = 1 / E[X]
Сноски
1. согласно en.wikipedia.org - экспоненциальное распределение> среднее значение, дисперсия, моменты и медиана
Распределение в виде удобочитаемой диаграммы ascii
#include <iomanip>
#include <random>
#include <map>
#include <iostream>
int
main (int argc, char *argv[])
{
double const exp_dist_mean = 1;
double const exp_dist_lambda = 1 / exp_dist_mean;
std::random_device rd;
std::exponential_distribution<> rng (exp_dist_lambda);
std::mt19937 rnd_gen (rd ());
/* ... */
std::map<int, int> result_set;
for (int i =0; i < 100000; ++i)
++result_set[rng (rnd_gen) * 4];
for (auto& v : result_set) {
std::cout << std::setprecision (2) << std::fixed;
std::cout << v.first/4.f << " - " << (v.first+1)/4.f << " -> ";
std::cout << std::string (v.second/400, '.') << std::endl;
if (v.second/400 == 0)
break;
}
}
0.00 - 0.25 -> ........................................................
0.25 - 0.50 -> ...........................................
0.50 - 0.75 -> .................................
0.75 - 1.00 -> .........................
1.00 - 1.25 -> ....................
1.25 - 1.50 -> ...............
1.50 - 1.75 -> ............
1.75 - 2.00 -> .........
2.00 - 2.25 -> .......
2.25 - 2.50 -> .....
2.50 - 2.75 -> ....
2.75 - 3.00 -> ...
3.00 - 3.25 -> ..
3.25 - 3.50 -> ..
3.50 - 3.75 -> .
3.75 - 4.00 -> .
4.00 - 4.25 -> .
4.25 - 4.50 ->
Генерация случайной величины экспоненциального распределения может быть выполнена:
-ln(U)/lambda (where U~Uniform(0,1)).
Больше информации можно найти в этой статье в Википедии
В экспоненциальном распределении: lamda = 1/mean
, так что вы получите:
myVar = -ln(U) * mean (where U~Uniform(0,1)).