C++ 具有C+的不相关平行随机种子+;2011?

C++ 具有C+的不相关平行随机种子+;2011?,c++,random,c++11,seed,C++,Random,C++11,Seed,目前,我在Fortran中有一个主要应用程序,它需要一个种子来生成伪随机数。 我希望使用完全不相关的种子(以及完全独立的伪随机数链)多次运行此应用程序 我的问题是:在主线程中如何用C++ 2011?< /p> 生成种子,从一个好的随机源中提取单个种子(或种子序列)(例如,在Linux上从 /DEV/URANDOM < /代码>)。使用该数据为单个根PRNG设定种子。然后使用该PRNG为线程本地PRNG生成种子值 #include <random> #include <vecto

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


我的问题是:在主线程中如何用C++ 2011?< /p> 生成种子,从一个好的随机源中提取单个种子(或种子序列)(例如,在Linux上从<代码> /DEV/URANDOM < /代码>)。使用该数据为单个根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...
}
#包括
#包括
类型定义标准::mt19937 rng_类型;
标准:统一国际分布标准;
int main()
{
rng_型rng;
//首先对rng进行种子设定,并将结果存储在日志文件中:
rng_type::result_type const root_seed=get_seed();
种子(根和种子);
//制作线程种子:
std::向量种子(线程数);
对于(auto&n:seeds){n=udist(rng);}
//制作线程。。。
}
中的随机数引擎接口允许您从单个整数和整数序列中进行种子设定。如果需要额外的随机性,您可以从几百个整数的序列中为mt19937播种。

您无法真正生成随机种子。你把他们从某处拉出来。操作系统可能有一种检索伪随机值的方法(例如,Linux上的/dev/uradom),该方法可用于种子

获取表示当前时间的时间戳也是一个常见的选项——为了确保为每个线程获取不同的种子,只需确保它们在稍微不同的时间请求时间戳,并使用高分辨率计时器确保它们实际获取不同的值作为种子


C++11中没有内置“获取良好种子”函数,因为这样的函数本质上是没有意义的。计算机不能生成随机数据。你必须挑选一些看起来足够随机的东西来满足你的目的,并使用它来为随机生成器种子

C++11提供了
std::random\u设备
,如果源可用,则提供不确定的随机数。您必须检查您的实现,以确保它是好的。libc++默认使用/dev/uradom。如果定义了宏
\u GLIBCXX\u USE\u RANDOM\u TR1
,libstdc++也会这样做。不幸的是,VisualStudio的实现不是不确定的。编辑:从VS2012开始,他们的实现使用Windows的加密服务

如果
std::random\u设备
提供对非确定性随机性源的访问(通常/dev/uradom使用加密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);

}

我猜单核架构上的数字是伪随机的,你会生成像1,2,3,4,5,6,7,8这样的数字,然后通过CPU按顺序运行的进程只会取下一个,它的行为就像
rand();兰德();返回rand()
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);
}
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