Search code examples
c++randomgeneratorrandom-seedstochastic

Types of random number generators and functions that take them as arguments


Following Stephan T. Lavavej's talk (see here), I am using a Mersenne Twister random number generator and am producing random numbers with this kind of code

#include <iostream>
#include <random>
int main()
{
  std::mt19937 mt(132);
  std::uniform_int_distribution<int> dist(0,50);
  for (int i =0;i<10;i++)
  {
     std::cout << dist(mt) << std::endl;
  }
}

I would like to shuffle using the shuffle function (and not the random_shuffle) function (as recommended in the talk again). From cppreference.com, I see the function takes a URBG&& as argument.

I don't really understand what a URBG is. I tried to feed the mt19937 instead and it seems to work fine.

#include <iostream>
#include <random>
int main()
{
  std::vector<int> v;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);

  std::mt19937 mt(132);

  std::shuffle(v.begin(),v.end(),mt);
  for (int i=0;i<v.size();i++)
  {
    std::cout << v[i] << std::endl;
  }
}

Question

  • What is a URBG? Is mt19937 a subclass of URBG?
  • Can all types of random number generators given as argument to any function the produce a stochastic result (such as rand, shuffle or any function from random.h)?

Solution

  • URBG is the name of the template argument; it can be deduced to a variety of types, including std::mt19937. If you look further down on the cppreference pages, you'll see:

    g - a UniformRandomBitGenerator whose result type is convertible to std::iterator_traits::difference_type

    So URBG can be any type such that that:

    • URBG::result_type is an unsigned integer type
    • URBG::min() returns the smallest URBG::result_type that operator() could return (strictly less than max)
    • URBG::max() returns the largest URBG::result_type that operator() could return (strictly greater than min)
    • URBG::operator() (applied to the instance provided) returns, in amortized constant time, a value in the closed interval [URBG::min(), URBG::max()]
    • URBG::result_type is convertible to std::iterator_traits<RandomIt>::difference_type

    The new random number generators typically have some form of state, but if the library function can accept that in some way (for example, by taking a random generator object as std::shuffle does), then sure, they could be used.