如何正确初始化C ++ 11 std :: seed_seq

时间:2014-03-20 03:22:21

标签: c++ c++11 random

我有一个C ++ 11程序需要创建几个独立的随机生成器,供并行计算中的不同线程使用。应使用不同的种子值初始化这些生成器,以便它们都产生不同的伪随机序列。

我发现std::seed_seq课程似乎是为了这个目的,但是不清楚构建课程的正确方法是什么。我见过的例子,例如the one on cppreference.com,用一些在程序中硬编码的整数常量初始化它:

std::seed_seq seq{1,2,3,4,5};

我怀疑这实际上是推荐的最佳做法,所以我想知道 推荐的做法是什么。特别是:

  • 由于seed_seq可以使用任意数量的整数进行初始化,因此初始值列表长度的重要性是什么?如果我想为100个随机生成器生成种子,我是否需要用100个整数初始化seed_seq
  • 如果初始化列表的长度不必与我想要生成的种子数匹配,那么只用一个整数初始化seed_seq是否可以然后用它来生产大量的种子?
  • 如何使用 no 整数进行初始化,即使用默认构造函数? (这意味着我每次都会得到相同的种子。)
  • 如果可以从单个整数构造seed_seq然后从中生成大量种子,那么使用seed_seq代替普通随机的好处是什么?发电机?为什么不从该单个整数构造std::mt19937并使用 为其他生成器生成种子值?

2 个答案:

答案 0 :(得分:9)

使用像这样的固定序列的麻烦在于你得到了相同的种子序列,就像你在程序开始时调用srand(42)一样:它生成相同的序列。

C ++ 11标准声明(在26.5.7.1 Class seed_seq部分中):

  

种子序列是消耗一系列整数值数据并产生所请求数量的无符号整数值i,0 i< 2 32 ,基于消费数据。

     

[注意:这样的对象提供了一种避免随机变量流复制的机制。例如,这在需要大量随机数引擎的应用中是有用的。 - 后注]

它还指出如何将那些整数转换为该部分8中的种子,这样即使整数输入项是非常相似。因此,您可以将其视为种子值的伪随机数生成器。

更多的项目将提供更多随机性"在种子价值中,只要他们自己有一些随机性。因此,使用常量作为输入是一个坏主意。

我倾向于做的非常类似于您通常使用srand (time (0))随机化一个生成器的方式。换句话说:

#include <random>
#include <cstdint>
#include <ctime>
#include <iostream>

int main()
{
    std::seed_seq seq{time(0)};
    std::vector<std::uint32_t> seeds(10);
    seq.generate(seeds.begin(), seeds.end());
    for (std::uint32_t n : seeds) {
        std::cout << n << '\n';
    }
}

如果您有多个随机源,例如在Linux下从/dev/random读取的值,或某些描述的白噪声生成器,或者按键之间的平均毫秒数,上次用户运行此程序时,您可以将它们用作额外输入:

std::seed_seq seq{time(0), valFromDevRandom(), getWhiteNoise(), avgMillis()};

但我怀疑常数是要走的路,因为它们不会给等式增加随机性。

答案 1 :(得分:0)

根据C ++ 11标准(在26.5.7.1.8节中),seed_seq可以生成一个可能由哈希函数生成的序列,该序列均匀且随机地位于范围内。

我尝试回答以下问题:

Q1“由于可以使用任意数量的整数来初始化seed_seq,所以其初始化程序列表长度的意义是什么?如果我想为100个随机生成器生成种子,我是否需要使用100个整数来初始化我的seed_seq ?”

A1。您无需使用很多整数来初始化seed_seq。即使使用一个随机整数初始化seed_seq,生成的序列也保持随机性。但是,您可以使用更多的整数并在更宽的范围内初始化seed_seq,所生成的序列几乎不会受到攻击者的“碰撞”。

第二季度。 “如果初始化列表的长度不必与我打算生成的种子数匹配,那么可以只用一个整数初始化seed_seq,然后使用它来产生大量种子吗?”

A2。是的,如果您不需要密码安全级别,可以只用一个整数初始化seed_seq。

Q3。 “如何不使用整数初始化,即使用默认构造函数呢?(当然,这意味着我每次都会得到相同的种子。)”

A3。通过默认构造的seed_seq运行更多,您将获得相同的序列。这样它将成为一个安全漏洞。

Q4。 “如果可以从单个整数构造seed_seq,然后从中生成很多种子,那么使用seed_seq代替普通的随机生成器有什么好处?为什么不从该单个整数构造std :: mt19937并使用它为其他发电机产生种子值?”

A4。 seed_seq是一种轻量级算法,仅迭代填充序列3次。我猜您可以使用其他随机生成器代替seed_seq。