使用连续种子生成均匀随机数

Using continuously seed to generate uniform random numbers?

本文关键字:随机数 连续 种子      更新时间:2023-10-16

我有一个有趣的问题,即

通过使用标准库(或任何其他随机生成器)中著名的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();
}

我有一些算法,通过使用这个技巧来实现,而不是以通常的方式生成数字(每次都不重置种子)。

我实际上不相信像这样误用生成器,序列的一致性可以继续保持。

有谁有专业知识能给出一些理由吗?

非常感谢!

这段代码按照您所说的,重置每个数字生成之间的种子:

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

程序的输出是deterministic。在每次生成之间不断重置状态(此状态用于生成下一个随机数)。你绝对不能保证从不同的mersenne序列生成的数字的分布或均匀性(同样,每次重置种子时都会启动一个新序列)。

如果您的目标是生成一个受区间约束的均匀分布,请使用std::uniform_real_distribution:

示例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>