与C++2011不相关的并行随机种子
Uncorrelated parallel random seeds with C++ 2011?
目前,我在Fortran中有一个主要应用程序,它需要一个种子来生成伪随机数。我想用完全不相关的种子(以及完全独立的伪随机数链)运行很多次这个应用程序。
我的问题是:如何用C++2011生成种子?
在主线程中,从一个好的随机源(例如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...
}
<random>
中的随机数引擎接口允许您从单个整数和整数的序列进行种子设定。如果需要额外的随机性,可以从几百个整数的序列中为mt19937
种子。
C++11提供std::random_device
,以便在源可用的情况下提供非确定性随机数。不过,您必须检查您的实现,以确保它是好的。libc++默认使用/dev/urandom。如果定义了宏_GLIBCXX_USE_RANDOM_TR1
,那么libstdc++也可以。不幸的是,VisualStudio的实现不是非确定性的edit:从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);
}
八个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
您永远无法真正生成随机种子。你把它们从某个地方拉出来。操作系统可能有一种方法来检索可用于种子的伪随机值(例如,Linux上的/dev/urandom
)。
获取表示当前时间的时间戳也是一种常见的选择——然后,为了确保每个线程获得不同的种子,只需确保他们在稍微不同的时间请求时间戳,并使用高分辨率计时器来确保他们实际上获得不同的值作为种子。
C++11中没有"获得一个好的种子"函数,因为这样的函数本质上是没有意义的。计算机无法生成随机数据。你必须选择一些看起来足够随机的东西来达到你的目的,并用它来为随机生成器
- 如何使用要传递给 mt19937 的可选随机种子参数设计函数
- 如何使用可选的随机种子参数创建 roll_die() 函数
- 除了 rand() 之外,是否有任何随机生成器库,开发人员可以手动设置种子?
- 如果我在每个平台上使用相同的种子,随机结果会相同吗?
- 随机化种子值C
- 为什么使用迭代器时必须重新设定随机生成器种子?
- 在给定种子和偏移量的情况下生成下一个伪随机值
- 设置随机种子独立rmath库
- 与C++2011不相关的并行随机种子
- 我应该使用从std::random_device种子的随机引擎,还是每次都使用std::random_device
- 如何生成随机种子/哈希以使Rand实际上是随机的
- 生成一个随机种子给srand()-不是时间(NULL)
- 在哪里初始化随机种子以通过多个随机模块使用
- 为什么起始值会影响种子随机的结果
- 更改程序 C++ 中的随机种子
- C++麦克风输入作为随机种子
- 使用srand作为随机种子时出现重复输出
- 随机生成器,种子不工作
- 多精度随机生成器种子错误
- 在伪随机生成器中使用常量种子从UT和GUI中获得不相同的数字