我有一个有趣的问题,即
通过在标准库(或任何其他随机生成器)中使用着名的mersenne twister std::mt19937 r
并使用种子r.seed(4)
进行设置,例如,可以获得均匀随机生成的数字(在uint_fast32_t
提供的范围内。
如果我们从1到100遍历种子并生成第一个随机数,究竟会发生什么?这个序列是否仍然均匀分布?
for(int i = 0;i<100;i++){
r.seed(i);
int v = r();
}
我有一些算法通过使用这个技巧更容易实现,而不是以通常的方式生成数字(每次都不重置种子)。
我实际上并不相信通过滥用这样的发生器,可以保持序列的均匀性。
有没有人有专业知识给出一些推理?
非常感谢!
答案 0 :(得分:2)
此代码按照您的说法执行,在每个数字生成之间重置种子:
#include <iostream>
#include <random>
int main ()
{
std::mt19937 r;
for(int i = 0;i<10;i++){
r.seed(i);
int v = r();
std::cout << v << std::endl;
}
return 0;
}
此计划的输出确定性。您不断重置每一代之间的状态(此状态用于生成下一个随机数)。您完全不能保证从不同的mersenne序列生成的数字的分布或均匀性(同样,每次重置种子时都会启动一个新序列)。
如果您的目标是生成限制在某个时间间隔内的统一分布,请使用std::uniform_real_distribution
:
Example from en.cppreference.com:
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(1, 2);
for (int n = 0; n < 10; ++n) {
std::cout << dis(gen) << ' ';
}
std::cout << '\n';
}
它在C ++标准中定义,§26.5.8.2.2部分:
uniform_real_distribution随机数分布产生随机 数字x,a≤x< b,按常数分配 概率密度函数p(x | a,b)= 1 /(b - a)