随机数生成器的类型和以它们为参数的函数
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
? mt19937
是 URBG
的子类吗?
- 是否所有类型的随机数生成器都可以作为任何函数的参数给出并产生随机结果(例如
rand
、shuffle
或 random.h
中的任何函数)?
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 那样采用随机生成器对象),那么当然,它们可以被使用。
在 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
?mt19937
是URBG
的子类吗? - 是否所有类型的随机数生成器都可以作为任何函数的参数给出并产生随机结果(例如
rand
、shuffle
或random.h
中的任何函数)?
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 那样采用随机生成器对象),那么当然,它们可以被使用。