Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating a uniform random integer in C++

Tags:

c++

random

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.

like image 224
user1546083 Avatar asked Apr 22 '13 17:04

user1546083


People also ask

How do you generate random uniform numbers?

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 .

Is rand () in C uniform?

The rand() function in the standard C library returns a uniformly random number in [0, RAND_MAX-1].

Is rand () uniformly distributed?

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.


2 Answers

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';
}
like image 137
Johnny Mnemonic Avatar answered Oct 09 '22 16:10

Johnny Mnemonic


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

like image 44
Drew Dormann Avatar answered Oct 09 '22 16:10

Drew Dormann