Проблемы с классом С++ 11 mersenne_twister_engine

Я пытался использовать класс С++ 11 mersenne_twister_engine (http://www.cplusplus.com/reference/random/mersenne_twister_engine/) для генерации чисел в интервале [0,1], однако я постоянно получаю 0 для каждого числа.

Вот мой фрагмент кода

unsigned seed1 = std::chrono::system_clock::now().time_since_epoch().count();   

std::mt19937 generator(seed1); 
for (int i=0; i < WIDTH * HEIGHT; i++) //GENERATES THE MATRIX OF CONNECTIVITY
{

    double random = generator()/generator.max();
    if ( random  > VERT_CONNECTIVITY )
    vert_con[i] = 0;
    else vert_con[i] = 1;


}

генератор() и генератор.max(), похоже, работают... Это просто случайное значение, которое дает мне 0!

Спасибо!


person ren    schedule 11.12.2013    source источник
comment
Целое число, деленное на целое число, является целым числом.   -  person chris    schedule 11.12.2013
comment
Почему бы не использовать uniform_int_distribution?   -  person Shafik Yaghmour    schedule 11.12.2013
comment
если int a ‹ int b (a/b=›0) (a%b=›a)   -  person Jekyll    schedule 11.12.2013
comment
bernoulli_distribution, вероятно, лучший выбор, учитывая двоичный результат   -  person Cubbi    schedule 11.12.2013
comment
Также имейте в виду, что вы можете использовать std::random_device вместо семени времени.   -  person chris    schedule 11.12.2013


Ответы (4)


В C++ / для целых чисел приводит к целому числу. Например, 11/2 дает 5, а не 5,5. Точно так же a / b всегда равно нулю, если a < b.

Ваша проблема здесь:

generator()/generator.max()

generator() и generator.max() возвращают целые числа и, конечно же, generator.max() >= generator(), поэтому результат равен нулю (если только вам не повезет получить число max, в этом случае результатом будет единица).

Чтобы исправить это, вы можете просто применить его:

(double)generator()/generator.max()
person Shahbaz    schedule 11.12.2013

Использование одного из дистрибутивов, указанных в случайном заголовке. наверное имеет больше смысла. Как отмечает Кубби, std::bernoulli_distribution выглядит так, как будто это хорошо подходит для вашей проблемы. . Он сгенерирует true или false в соответствии с переданным параметром распределения:

#include <iostream>
#include <random>
#include <vector>
#include <algorithm>

const int WIDTH = 5 ;
const int HEIGHT = 5 ;
const double VERT_CONNECTIVITY = 0.25 ;

int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());

    // give "true" 1/4 of the time
    // give "false" 3/4 of the time
    std::bernoulli_distribution d(VERT_CONNECTIVITY);

    std::vector<int> vert_con( WIDTH * HEIGHT ) ;

    std::generate( std::begin(vert_con), std::end( vert_con ), [&] () { return d(gen) ; } ) ;

    for (int i=0; i < WIDTH * HEIGHT; i++) 
    {
        std::cout << vert_con[i] << " " ;
    }
    std::cout << std::endl ;

    return 0 ;
}
person Shafik Yaghmour    schedule 11.12.2013
comment
ОП, вероятно, ищет std::generate(std::begin(vert_con), std::end(vert_con), [&]{ return d(gen); }); - person Casey; 11.12.2013

Возможно, вы ищете generate_canonical<double, bits>(gen)? Это сгенерирует десятичное значение, равномерно распределенное в интервале [0,1) с bits битами случайности (53 — стандартный максимум, доступный для двойного числа).

person Elliot Robinson    schedule 11.12.2013

mersenne_twister_engine возвращает результаты типа UIntType. Если вы хотите, чтобы результат был двойным, вам нужно привести его к двойному.

двойной случайный = (двойной) генератор()/генератор.макс();

person Community    schedule 11.12.2013