C++ TR1:как использовать normal_distribution?
-
12-09-2019 - |
Вопрос
Я пытаюсь использовать Технический отчет C ++ STD1 расширения для генерации чисел в соответствии с обычным распределением, но этот код (адаптированный из эта статья):
mt19937 eng;
eng.seed(SEED);
normal_distribution<double> dist;
// XXX if I use the one below it exits the for loop
// uniform_int<int> dist(1, 52);
for (unsigned int i = 0; i < 1000; ++i) {
cout << "Generating " << i << "-th value" << endl;
cout << dist(eng) << endl;
}
выводит только 1 сообщение журнала "Генерирую ...", затем никогда не выходит из цикла for!Если я использую вместо этого закомментированный дистрибутив, он завершается, поэтому мне интересно, что я делаю не так.Есть какие-нибудь идеи?
Большое спасибо!
Решение
Это точно не приведет к зависанию программы.Но не уверен, действительно ли это соответствует вашим потребностям.
#include <random>
#include <iostream>
using namespace std;
typedef std::tr1::ranlux64_base_01 Myeng;
typedef std::tr1::normal_distribution<double> Mydist;
int main()
{
Myeng eng;
eng.seed(1000);
Mydist dist(1,10);
dist.reset(); // discard any cached values
for (int i = 0; i < 10; i++)
{
std::cout << "a random value == " << (int)dist(eng) << std::endl;
}
return (0);
}
Другие советы
У меня была такая же проблема с первоначально опубликованным кодом, и я исследовал реализацию GNU
сначала несколько замечаний:с g ++-4.4 и использованием кода зависает, с g ++-4.5 и использованием -std=c ++ 0x (т.е.не TR1, а реальная вещь) приведенный выше код работает
ИМХО, произошло изменение между TR1 и c ++ 0x в отношении адаптеров между генерацией случайных чисел и потреблением случайных чисел - mt19937 выдает целые числа, normal_distribution использует удвоения
c ++ 0x использует адаптацию автоматически, код g ++ TR1 этого не делает
чтобы заставить ваш код работать с g ++-4.4 и TR1, выполните следующие действия
std::tr1::mt19937 prng(seed);
std::tr1::normal_distribution<double> normal;
std::tr1::variate_generator<std::tr1::mt19937, std::tr1::normal_distribution<double> > randn(prng,normal);
double r = randn();
Если ваша реализация генерации случайных чисел TR1 содержит ошибки, вы можете избежать TR1, написав свой собственный обычный генератор следующим образом.
Сгенерируйте две однородные (0, 1) случайные выборки u и v, используя любой генератор случайных чисел, которому вы доверяете.Затем пусть r = sqrt(-2 log(u)) и возвращает x = r sin(2 pi v).(Это называется методом Бокса-Мюллера.)
Если вам нужны нормальные выборки со средним мю и сигмой стандартного отклонения, верните сигма*х + мю вместо просто x.
Хотя это похоже на ошибку, быстрым подтверждением будет передача параметров по умолчанию 0.0, 1.0. normal_distribution<double>::normal_distribution()
должно быть равно normal_distribution<double>::normal_distribution(0.0, 1.0)