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()()