
I was just checking over my suggestion and realized that clock() is not a good choice for seeding the generator, especially with my optimization. It returns the amount of time since the process started, which in a static initializer for a global variable, will provide very low entropy. In a few test runs, it even returned 0, which caused an assertion failure in the random number library. An ideal solution would be to use random_device, which is defined in boost/nondet_random.hpp. You could then replace the definition of generator with something like this: //Declare the generator as a global variable for easy reuse random_device nondet_generator; base_generator_type generator(nondet_generator()); If random_device isn't implemented on your platform, then you can look into other ways to seed the generator. On my system (Windows XP running VC8) I used GetTickCount(), which returns the number of milliseconds since Windows started. As a last resort, you could call clock() after the user has entered something, either the normal data entry for your program (preferred), or a special request to hit enter. Does anybody else know of other good sources of entropy to seed the generator? I also found that the loop to seed the generator (initialize() in my version) doesn't really help, since the seed function completely replaces the current value of the generator; it doesn't combine with the previous value.
-----Original Message----- From: Andrew Holden Sent: Friday, May 19, 2006 9:18 AM To: boost-users@lists.boost.org Subject: Re: [Boost-users] Newbie question: Random numbers.
My first thought is that you probably shouldn't reinitialize the generator for every random number you need. I would recommend that you create and seed "generator" once at the start of your program, then reuse it whenever you need a random number.
Perhaps something like the following:
namespace Random { typedef boost::minstd_rand base_generator_type; typedef boost::uniform_int<> distribution_type; typedef boost::variate_generator
gen_type; //Declare the generator as a global variable for easy reuse base_generator_type generator(static_cast<unsigned long>(clock()));
/*************************************************** * initializes the random number generator * **************************************************/ void initialize() { for (int i = 0; i < 30000; ++i) generator.seed(static_cast<unsigned long>(clock())); }
/*************************************************** * generates a random number between a and b * * @param a the starting range * * @param b the integer ending range * * @return N such that a <= N <= b * **************************************************/ template <class T> T rand_int (const T& a, const T& b) { //Check the parameters BOOST_STATIC_ASSERT(boost::is_integral<T>::value); assert (b >= a);
//Set up the desired distribution gen_type ran_gen(generator, distribution_type(a, b));
//Get a random number return ran_gen(); } }
using Random::rand_int;
int main(int argc, char* argv[]) { Random::initialize();
std::cout << rand_int (1,1000) << std::endl << rand_int (1,1000) << std::endl << rand_int (1,1000) << std::endl << rand_int (1,1000) << std::endl;
return 0; } ________________________________________ From: chun ping wang [mailto:cablepuff@gmail.com] Sent: Friday, May 19, 2006 3:55 AM To: boost-users@lists.boost.org Subject: [Boost-users] Newbie question: Random numbers.
I have a simple question, is there a very fast and effecient way to generate random numbers that are fast on the fly. The numbers are really randomize and distorted...
/*************************************************** * generates a random number between a and b * * @param a the starting range * * @param b the integer ending range * * @return N such that a <= N <= b * **************************************************/ template <class T> T randint(const T& a, const T& b) { BOOST_STATIC_ASSERT(boost::is_integral<T>::value); assert (b >= a); typedef boost::minstd_rand base_generator_type; typedef boost::uniform_int<> distribution_type; typedef boost::variate_generator
gen_type; base_generator_type generator(boost::numeric_cast<unsigned long>(clock())); gen_type ran_gen(generator, distribution_type(a, b)); for (int i = 0; i < 30000; ++i) generator.seed(boost::numeric_cast<unsigned long>(clock())); return ran_gen(); } This works but is super slow... are there effective ways to do it...
Thanks.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users