Boost:: random генерирует одинаковое число каждый раз

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

Ответ 1

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

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

/*
 * 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)));

Ответ 2

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

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

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

Ответ 3

Если вы работаете в системе 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) для всех ваших случайных чисел.

Ответ 4

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

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

boost::random::random_device()()