boost :: random генерирует одно и то же число каждый раз - PullRequest
10 голосов
/ 04 декабря 2009

main .cpp

#include        "stdafx.h"
#include        "random_generator.h"


        int
main ( int argc, char *argv[] )
{
        cout.setf(ios::fixed);
        base_generator_type base_generator;
        int max = pow(10, 2);
        distribution_type dist(1, max);

        boost::variate_generator<base_generator_type&,
distribution_type > uni(base_generator, dist);
        for ( int i=0; i<10; i++ ) {
                //cout << random_number(2) << endl;
                cout << uni() << endl;
        }

        return EXIT_SUCCESS;

}                               /* ----------  end of function main  ---------- */

random_gemerator.h

#include        "stdafx.h"

#include        <boost/random.hpp>
#include        <boost/generator_iterator.hpp>

typedef boost::mt19937 base_generator_type;
typedef boost::lagged_fibonacci19937 fibo_generator_type;
typedef boost::uniform_int<> distribution_type;
typedef boost::variate_generator<fibo_generator_type&,
distribution_type> gen_type;

        int
random_number ( int bits )
{
        fibo_generator_type fibo_generator;
        int max = pow(10, bits);
        distribution_type dist(1, max);

        gen_type uni(fibo_generator, dist);
        return uni();

}               /* -----  end of function random_number  ----- */

stdafx.h

 #include <iostream>
#include <cstdlib>
#include <cmath>

using namespace std;

каждый раз, когда я запускаю его, все генерирует одну и ту же последовательность чисел

как 77, 33,5, 22, ...

как правильно использовать boost: random?


вот и все. но, возможно, возникли небольшие проблемы, например:

кажется, звук

get_seed(); for (;;) {cout << generate_random() << endl; } // is ok 

генерирует то же случайное число

int get_random() {get_seed();return generate_random();} for (;;) {cout << get_random() <<endl;}  // output the same random number yet

Ответы [ 4 ]

13 голосов
/ 04 декабря 2009

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

вы найдете пример там , выдержка:

/*
 * Change seed to something else.
 *
 * Caveat: std::time(0) is not a very good truly-random seed.  When
 * called in rapid succession, it could return the same values, and
 * thus the same random number sequences could ensue.  If not the same
 * values are returned, the values differ only slightly in the
 * lowest bits.  A linear congruential generator with a small factor
 * wrapped in a uniform_smallint (see experiment) will produce the same
 * values for the first few iterations.   This is because uniform_smallint
 * takes only the highest bits of the generator, and the generator itself
 * needs a few iterations to spread the initial entropy from the lowest bits
 * to the whole state.
 */
generator.seed(static_cast<unsigned int>(std::time(0)));
6 голосов
/ 04 декабря 2009

Вам нужно запустить генератор случайных чисел, чтобы он не запускался каждый раз с одного и того же места.

В зависимости от того, что вы делаете с числами, вам может понадобиться подумать о том, как вы выбираете начальное значение. Если вам нужна случайность высокого качества (если вы генерируете криптографические ключи и хотите, чтобы они были достаточно безопасными), вам понадобится хорошее начальное значение. Если бы это был Posix, я бы предложил / dev / random - но вы, похоже, используете Windows, так что я не уверен, каким будет хороший исходный источник.

Но если вы не возражаете против предсказуемого начального числа (для игр, симуляций и т. Д.), Быстрое и грязное начальное число - это текущая временная метка, возвращаемая временем ().

5 голосов
/ 14 декабря 2009

Если вы работаете в системе 'nix, вы всегда можете попробовать что-то вроде этого;

int getSeed()
{
    ifstream rand("/dev/urandom");
    char tmp[sizeof(int)];
    rand.read(tmp,sizeof(int));
    rand.close();
    int* number = reinterpret_cast<int*>(tmp);
    return (*number);
}

Я предполагаю, что заполнение генератора случайных чисел таким способом быстрее, чем простое чтение /dev/urandom (или /dev/random) для всех ваших потребностей случайных чисел.

2 голосов
/ 13 июля 2012

Вы можете использовать класс boost :: random :: random_device либо как есть, либо для заполнения другого генератора.

Вы можете получить из него одноразовое случайное число с помощью простого:

boost::random::random_device()()
...