The problem is that I need to generate a random integer between 0 and 999 (for investigation of a mathematical conjecture). All of the values need to have the same probability of coming up.
I have tried rand()
, but with RAND_MAX
being 32767 (on my compiler) this means that just taking rand() % 1000
leads to the first 1–767 being significantly more likely to come up (and that's assuming that all possibilities have the same probability in rand()
in the first place).
I'm using Windows so /dev/random
isn't an option.
The inversion method relies on the principle that continuous cumulative distribution functions (cdfs) range uniformly over the open interval (0,1). If u is a uniform random number on (0,1), then x = F - 1 ( u ) generates a random number x from any continuous distribution with the specified cdf F .
The rand() function in the standard C library returns a uniformly random number in [0, RAND_MAX-1].
X = rand returns a random scalar drawn from the uniform distribution in the interval (0,1). X = rand( n ) returns an n -by- n matrix of uniformly distributed random numbers.
You can do something like this using uniform_int_distribution
with C++11:
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 999);
for (int n=0; n<1000; ++n)
std::cout << dis(gen) << ' ';
std::cout << '\n';
}
Your modulus observation is correct, and one of several reasons that rand()
doesn't hold up to mathematical scrutiny. From the notes here:
There are no guarantees as to the quality of the random sequence produced. In the past, some implementations of rand() have had serious shortcomings in the randomness, distribution and period of the sequence produced (in one well-known example, the low-order bit simply alternated between 1 and 0 between calls). rand() is not recommended for serious random-number generation needs, like cryptography.
C++11 introduces several new random number generators that hold to stricter standards that would likely be suitable for your purposes..
If you can sacrifice more than a few bytes of overhead (it's safe to assume that you can), I recommend std::mersenne_twister_engine
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With