用C ++ 2011不相关的平行的随机种子?(Uncorrelated parallel rando

2019-09-22 05:31发布

目前,我在Fortran语言需要种子来生成伪随机数的主要应用。 我想运行很多(多)次,完全不相关的种子(进而完全独立的伪随机数链)这个应用程序。

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

Answer 1:

在你的主线程,提取了良好的随机源(例如,从一个单一的种子(或种子序列) /dev/urandom在Linux上)。 使用该数据种子单个根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...
}

在随机数引擎接口<random>让你无论从单个整数和从整数的序列的种子。 如果你想要更多的随机性,可以播种mt19937从几百整数序列。



Answer 2:

C ++ 11提供std::random_device提供非确定性的随机数,如果源是可用的。 你必须检查你的实现,以确保它是很好的,但。 的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);

}

不要使用单个值作为种子,一些发动机可以有更多的种子数据做的更好。 种子序列是由标准所提供的替代物。 引擎可以与种子序列,它们是加载了任何数量的数据和产生基于该种子数据对象接种。

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

8个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


Answer 3:

你永远不能真正生成随机种子。 你拉他们从某处。 操作系统可能具有的方法来检索伪随机值( /dev/urandom可用于接种在Linux,例如)。

获取表示当前时间的时间戳也是常见的选项 - 那么,以确保您得到不同的种子为每个线程,只是确保他们为时间戳问时间略有不同,并使用高分辨率定时器,以确保他们真正得到不同的值的种子。

有内置到C ++ 11没有“获得了良好的种子”功能,因为这样的功能基本上是没有意义的。 电脑无法生成随机数据。 你必须选择一些看起来足够的随机你的目的,并用它来种子随机发生器



文章来源: Uncorrelated parallel random seeds with C++ 2011?