What is the best way to generate random numbers?
问题:
回答1:
If and only if:
you are not looking for "perfect uniformity" or
you have no C++11 support and not even TR1 (thus you don't have another choice)
then you might consider using the following C-style solution, which (for the sake of the reputation of this community ~ see rand() Considered Harmful) is written in strike-through font:
Here's the simple C-style function that generates random number from the interval from min
to max
, inclusive. Those numbers seem to be very close to being uniformly distributed.
int irand(int min, int max) {
return ((double)rand() / ((double)RAND_MAX + 1.0)) * (max - min + 1) + min;
}
and don't forget to call srand
before you use it:
int occurences[8] = {0};
srand(time(0));
for (int i = 0; i < 100000; ++i)
++occurences[irand(1,7)];
for (int i = 1; i <= 7; ++i)
printf("%d ", occurences[i]);
output: 14253 14481 14210 14029 14289 14503 14235
Also have a look at:
Generate a random number within range?
Generate random numbers uniformly over an entire range
and find some time and watch at least first 11 minutes of aforementioned video
Otherwise:
use <random>
just like it was pointed out by Kerrek SB already.
回答2:
You should use <random>
:
#include <random>
typedef std::mt19937 rng_type;
std::uniform_int_distribution<rng_type::result_type> udist(0, 7);
rng_type rng;
int main()
{
// seed rng first:
rng_type::result_type const seedval = get_seed(); // get this from somewhere
rng.seed(seedval);
rng_type::result_type random_number = udist(rng);
return random_number;
}
Pre C++11 you could find this either in TR1 (<tr1/random>
, std::tr1::mt19937
etc.), or in Boost.random, with essentially the same interface (though there are minor differences).
回答3:
Boost.Random is an excellent library for producing pseudorandom numbers (or truly random, if the platform supports it).
回答4:
If you're talking standard C++ library pre C++11, rand and srand are your random number generators. There are ways to get more accuracy out of these functions than using modulus with integer arithmetic. You could use doubles, for example, if high speed isn't a concern and round the results to int.
As for custom libraries, if you really want good random distribution and speed, google Mersenne Twister. There are also options in boost.
With C++11 you have <random>
. http://en.cppreference.com/w/cpp/numeric/random
回答5:
My 'random' library provide a high convenient wrapper around C++11 random classes. You can do almost all things with a simple 'get' method.
Examples:
- Random number in a range
auto val = Random::get(-10, 10); // Integer
auto val = Random::get(10.f, -10.f); // Float point
- Random boolean
auto val = Random::get<bool>( ) // 0.5% to generate true
auto val = Random::get<bool>( 0.7 ) // 0.7% to generate true
- Random value from a std::initilizer_list
auto val = Random::get( { 1, 3, 5, 7, 9 } ); // val = 1 or 3 or...
- Random iterator from iterator range or all container
auto it = Random::get( vec.begin(), vec.end() ); // it = random iterator
auto it = Random::get( vec ); // return random iterator
And even more things ! Check out the github page:
https://github.com/effolkronium/random