使用C++ 2011的不相关的并行随机种子?

Vin*_*ent 6 c++ random seed c++11

目前,我在Fortran中有一个主要的应用程序需要一个种子来生成伪随机数.我想用完全不相关的种子(以及完全独立的伪随机数链)运行这个应用程序很多次(很多次).

我的问题是:如何使用C++ 2011生成种子?

Ker*_* SB 7

在主线程中,从一个好的随机源(例如从/dev/urandomLinux上)中提取单个种子(或种子序列).使用该数据为单个根PRNG播种.然后使用 PRNG为线程本地PRNG生成种子值.

#include <random>
#include <vector>

typedef std::mt19937 rng_type;
std::uniform_int_distribution<rng_type::result_type> udist;

int main()
{
    rng_type rng;

    // seed rng first, and store the result in a log file:
    rng_type::result_type const root_seed = get_seed();
    rng.seed(root_seed);

    // make thread seeds:
    std::vector<rng_type::result_type> seeds(NUMBER_OF_THREADS);
    for (auto & n : seeds) { n = udist(rng); }

    // make threads...
}
Run Code Online (Sandbox Code Playgroud)

随机数引擎接口<random>允许您从单个整数和整数序列中播种.如果你想要额外的随机性,你可以mt19937从几百个整数的序列中播种.


bam*_*s53 6

std::random_device如果源可用,C++ 11 提供非确定性随机数.你必须检查你的实现,以确保它是好的.libc ++默认使用/ dev/urandom.libstdc ++也_GLIBCXX_USE_RANDOM_TR1可以定义宏.遗憾的是,Visual Studio的实现并不是非确定性的.编辑:从VS2012开始,他们的实现使用Windows的加密服务.

如果std::random_device提供对非确定性随机源的访问(通常/ dev/urandom使用加密PRNG),那么这应该足以生成独立种子.

#include <random>

int main() {
    std::random_device r;
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
    std::mt19937 engine(seed);

}
Run Code Online (Sandbox Code Playgroud)

一些引擎可以使用更多种子数据做得更好,而不是使用单个值作为种子.种子序列是标准提供的替代方案.可以使用种子序列播种引擎,种子序列是您使用任意数量的数据加载的对象,并基于此生成种子数据.

std::random_device r;
std::vector<std::mt19937> engines;

int engines = 50;
for (int i = 0; i < engines; ++i) {
    std::seed_seq s{r(), r(), r(), r(), r(), r(), r(), r()};
    engines.emplace_back(s);
}
Run Code Online (Sandbox Code Playgroud)

八个32位值,256位,就足够了,但如果你真的想要,你可以使用更多.每个标准引擎都记录了它从种子序列中使用了多少数据.

例如,每个mt19937引擎将从mt19937::state_size种子序列中检索(624)32位值.从种子序列中检索的种子与输入数据不同,但它们基于该数据,因此我们可以在序列中使用那么多随机数据.

std::random_device r;
std::vector<std::uint_least32_t> data;
std::generate_n(back_inserter(data), 624, std::ref(r));

std::seed_seq seed(begin(data), end(data));

std::mt19937 engine(seed); // 'fully' seeded mt19937
Run Code Online (Sandbox Code Playgroud)