随机数生成器的类型和以它们为参数的函数

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

在 Stephan T. Lavavej 的演讲之后(参见 here),我正在使用 Mersenne Twister 随机数生成器并使用这种代码生成随机数

#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;
  }
}

我想使用 shuffle 函数(而不是 random_shuffle)函数进行随机播放(再次在演讲中推荐)。从 cppreference.com 中,我看到该函数将 URBG&& 作为参数。

我不太明白URBG是什么。我试着给 mt19937 喂食,它似乎工作正常。

#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;
  }
}

问题

URBG 是一个统一随机位生成器。用 C++ 的说法,它是一个函数对象,返回具有均匀概率分布的无符号整数值(即每个可能的结果与其他任何结果发生的可能性相同)。这些要求当然在标准中有严格的规定。

std::mt19937 个实例是 URBG,因为它们满足这个定义。 std::uniform_int_distribution 个实例也满足它,因此在这种情况下,将一个或另一个传递给 <random> 函数之间绝对没有区别。

但是,请注意 <random> 中定义的大多数分布在设计上 不是 统一的,因此它们不能用于需要 URBG 的地方(你会得到结果偏斜)。

URBG 是模板参数的名称;可以推导出多种类型,包括std::mt19937。如果您进一步查看 cppreference 页面,您会看到:

g - 结果类型可转换为 std::iterator_traits::difference_type

UniformRandomBitGenerator

因此 URBG 可以是满足以下条件的任何类型:

  • URBG::result_type是无符号整数类型
  • URBG::min() return 是 operator() 可以 return 的最小 URBG::result_type(严格小于最大值)
  • URBG::max() return 是 operator() 可以 return 的最大 URBG::result_type(严格大于最小值)
  • URBG::operator()(应用于提供的实例)returns,在摊销常数时间内,闭区间[URBG::min(), URBG::max()]
  • 中的一个值
  • URBG::result_type 可转换为 std::iterator_traits<RandomIt>::difference_type

新的随机数生成器通常具有某种形式的状态,但如果库函数可以某种方式接受它(例如,像 std::shuffle 那样采用随机生成器对象),那么当然,它们可以被使用。