Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate random numbers using C++11 random library

As the title suggests, I am trying to figure out a way of generating random numbers using the new C++11 <random> library. I have tried it with this code:

std::default_random_engine generator;
std::uniform_real_distribution<double> uniform_distance(1, 10.001);

The problem with the code I have is that every time I compile and run it, it always generates the same numbers. So my question is what other functions in the random library can accomplish this while being truly random?

For my particular use case, I was trying to get a value within the range [1, 10]

like image 842
smac89 Avatar asked Oct 29 '13 18:10

smac89


People also ask

Does C++ have a random library?

In C++11, we can get the random library to generate random numbers. Here we have used random_device once to seed the random number generator object called mt. This random_device is slower than the mt19937, but we do not need to seed it. It requests for random data to the operating system.

How do you generate a random number in CPP?

One way to generate these numbers in C++ is to use the function rand(). Rand is defined as: #include <cstdlib> int rand(); The rand function takes no arguments and returns an integer that is a pseudo-random number between 0 and RAND_MAX.

What is #include random in C++?

rand() rand() function is an inbuilt function in C++ STL, which is defined in header file <cstdlib>. rand() is used to generate a series of random numbers. The random number is generated by using an algorithm that gives a series of non-related numbers whenever this function is called.

How do you generate a random number with a range in C++?

How to Generate Random Numbers in C++ Within a Range. Similar to 1 and 10, you can generate random numbers within any range using the modulus operator. For instance, to generate numbers between 1 and 100, you can write int random = 1+ (rand() % 100).

How to generate random numbers in C++11?

In C++11, we can get the random library to generate random numbers. Here we have used random_device once to seed the random number generator object called mt. This random_device is slower than the mt19937, but we do not need to seed it. It requests for random data to the operating system.

How to generate a random number in a given range?

With the help of rand () a number in range can be generated as num = (rand () % (upper – lower + 1)) + lower // random number in a given range.

Why do we need non random numbers in C++?

Some programs need numbers that reflect a nonuniform distribution. Programmers often introduce nonrandomness when they try to transform the range, type, or distribution of the numbers generated by rand. (quote from Lippmans C++ primer fifth edition 2012)

How to generate a number in range in C?

As C does not have an inbuilt function for generating a number in the range, but it does have rand function which generate a random number from 0 to RAND_MAX. With the help of rand () a number in range can be generated as num = (rand () % (upper – lower + 1)) + lower


2 Answers

Stephan T. Lavavej(stl) from Microsoft did a talk at Going Native about how to use the new C++11 random functions and why not to use rand(). In it, he included a slide that basically solves your question. I've copied the code from that slide below.

You can see his full talk here:

#include <random>
#include <iostream>

int main() {
    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<double> dist(1.0, 10.0);

    for (int i=0; i<16; ++i)
        std::cout << dist(mt) << "\n";
}

We use random_device once to seed the random number generator named mt. random_device() is slower than mt19937, but it does not need to be seeded because it requests random data from your operating system (which will source from various locations, like RdRand for example).


Looking at this question / answer, it appears that uniform_real_distribution returns a number in the range [a, b), where you want [a, b]. To do that, our uniform_real_distibution should actually look like:

std::uniform_real_distribution<double> dist(1, std::nextafter(10, DBL_MAX));
like image 75
Bill Lynch Avatar answered Oct 17 '22 17:10

Bill Lynch


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:

  1. Random number in a range

    auto val = Random::get(-10, 10); // Integer
    auto val = Random::get(10.f, -10.f); // Float point
    
  2. Random boolean

    auto val = Random::get<bool>( ) // 50% to generate true
    auto val = Random::get<bool>( 0.7 ) // 70% to generate true
    
  3. Random value from a std::initilizer_list

    auto val = Random::get( { 1, 3, 5, 7, 9 } ); // val = 1 or 3 or...
    
  4. 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

like image 32
Ilya Polishchuk Avatar answered Oct 17 '22 17:10

Ilya Polishchuk