2016-05-04 4 views
1

мне удалось получить рабочую нормальное распределение в моей основной функции(), используя следующий код:Как создать произвольное нормальное распределение C++, которое работает в отдельном методе?

default_random_engine generator(time(0)); 
normal_distribution<double> distribution(6.0,5.0); 


for (int i = 0; i < 51; i++) 
{ 
    cout << "#" << i << "= " << distribution(generator); 
} 

Это будет счастливо распечатать 50 значений, которые следуют за распределением со средним значением 6,0 и в среднем 5,0, например:

#0= 0.999998 
#1= 3.43872 
#2= 6.83918 
#3= -3.81324 
#4= 16.0962 
#5= 1.26236 

Однако, как только я перехожу один и тот же код в метод и вызов указанного способа вернуть отдельные значения, которые населяют вывод, что только возвращает то же значение снова:

double normalGenerator(double mean, double stdDev) 
{ 
    default_random_engine generator(time(0)); 
    normal_distribution<double> distribution(mean,stdDev); 
    return distribution(generator); 
} 

(в главном()):

for (int i = 0; i < 51; i++) 
    { 
     cout << "#" << i << "= " << distribution(generator); 
     cout << " " << normalGenerator(6.0,5.0) << endl; 
    } 

Выход:

#0= 5.49136 5.49136 
#1= 7.6902 5.49136 
#2= 14.4971 5.49136 
#3= 11.946 5.49136 
#4= 4.37424 5.49136 
#5= 9.91711 5.49136 

Первый столбец имеет исходный код, второй метод называемого значение.

Я предполагаю, что мой вопрос основан на линиях с

default_random_engine generator(time(0)); 
normal_distribution<double> distribution(6.0,5.0); 

находящихся в методе, но мое понимание того, как они работают, не велико и я не нашел хорошую документацию начинающего уровня, чтобы помочь Я понимаю это.

+5

Посев в петле - очень распространенная ошибка. – LogicStuff

ответ

4

Давайте проанализируем ваш normalGenerator метода:

double normalGenerator(double mean, double stdDev) 
{ 
    default_random_engine generator(time(0)); // We initialize a generator 
    normal_distribution<double> distribution(mean,stdDev); // And a distribution 
    return distribution(generator); // distribution operator() always take the same generator with the same state 
} 

псевдослучайных Генераторы детерминированные, так что если вы держите на поставку генератора в том же состоянии, к объекту распределения он будет держать на outputing то же значения снова и снова. Однако каждый раз, когда вы используете генератор, его внутреннее состояние будет меняться и, таким образом, при генерации других значений вы получите другие выходы.

Быстрое изменение и вы хорошо идти:

default_random_engine generator(time(0)); 
normal_distribution<double> distribution(mean,stdDev); 

становится:

static default_random_engine generator(time(0)); 
normal_distribution<double> distribution(mean,stdDev); 

Как @PeterBecker отметил, вы должны также попытаться продолжать использовать один и тот же объект распределения. Таким образом, вы можете извлечь выгоду из потенциального кэширования переменных поколений.

Однако этого не может быть достигнуто путем создания объекта static, поскольку вам могут потребоваться другие нормальные распределения с другими параметрами (среднее значение и дисперсия).

+1

OP не инициализирует свой генератор с помощью 0, он делает это с 'time (0)', который будет меняться от запуска до запуска, но это тоже не очень хорошее решение. Я думаю, он должен использовать 'std :: random_device' для инициализации. – user2807083

+0

@ user2807083 Это хорошая точка – Rerito

+2

Распределение также должно быть статическим. Он работает нормально, как написано, но дистрибутивы иногда генерируют более одного значения за раз и сохраняют дополнительные функции для последующего использования. Создание нового дистрибутива каждый раз обходит это кэширование и может привести к поражению производительностью. –