c++ - 使用连续种子生成均匀随机数?

标签 c++ c++11 random

我有一个有趣的问题,即

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

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

如果您的目标是生成约束在区间内的均匀分布,请使用 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 部分:

A uniform_real_distribution random number distribution produces random numbers x , a ≤ x < b , distributed according to the constant probability density function p ( x | a,b ) = 1 / ( b − a )

关于c++ - 使用连续种子生成均匀随机数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24477218/

相关文章:

c++ - C++ Lambda 的内存布局

c++ - 删除指针有时会导致堆损坏

c++ - 为容器中的不同字符串类型实现编译时 "static-if"逻辑

c++ - std::tr1::function 和 std::tr1::bind

random - 在 Julia 中使用 Sobol 序列计算圆周率

c++ - g++ ld 找不到 x86_64 架构的 RInside 符号

c++ - 使用 C++ 接口(interface)在 Prolog 中进行列表处理

c++ - boost 和图形化

php - 随机化整个文件夹

c++ - 以通用方式选择有效的随机枚举值