如何确保在后续进程启动时RNG的种子是唯一的

How to ensure uniqe seeds for the RNG on subsequent process launches?

本文关键字:RNG 启动 种子 唯一 进程 何确保 确保      更新时间:2023-10-16

总结:我需要一个简单的自包含的方式来播种我的RNG,以便每次启动程序时种子都不同。

细节:

我经常需要多次运行相同的程序(使用随机数进行计算,例如蒙特卡罗模拟等)以获得良好的统计结果。在这种情况下,重要的是随机数生成器在每次运行时都有不同的种子。

我想有一个简单的,跨平台的解决方案,可以包含在程序本身。(也就是说,我不想总是让一个脚本用不同的种子参数启动程序的每个实例。)

请注意,使用time(0)作为种子不是一个好的解决方案,因为定时器分辨率很差:如果多个进程并行启动,它们很可能从time(0)获得相同的种子。

要求:

  • 尽可能简单
  • 跨平台(目前我需要它在Windows上工作&Linux, x86 &仅x64)。
  • 自包含:不应该依赖于启动程序的特殊方式(从启动脚本传递种子作为参数太麻烦了)。
  • 我想把整个东西包装成一个小的库,我可以包含在任何新的项目中,只需做一些像SeedMyRNG(getSeed());
编辑:

虽然我的主要问题是关于在C(或c++)中这样做,但根据答案中提供的指针,我发现os.urandom()作为Python解决方案(这对我也很有用)。

相关问题:如何在C中使用/dev/random或urandom ?

"跨平台"是一个主观术语。您是指"任何平台"(将来可能会遇到)还是"每个平台"(在您支持的平台列表中)?以下是我通常采用的实用方法:

  1. 检查是否有/dev/urandom;

  2. 在Windows上,使用CryptGenRandom()

  3. 如果这些都失败,从time()种子

您可以在Linux上使用dev random,在Windows上使用crypto api。写一个小的库来呈现一个平台无关的接口,它应该做你想做的事情。

查看RandomLib这是一个c++随机数库,对种子有很好的支持。在特定的

Random r;
r.Reseed();

导致r被播种一个向量的数字(从调用到RandomSeed::SeedVector()),它几乎肯定是唯一的。这包括时间、微秒、pid、hostid、年份。

不太理想的,你也可以使用RandomSeed::SeedWord()如果可能的话,从/dev/urandom读取。然而,你通常会得到一个2^16之后的种子碰撞以单个32位单词作为种子运行。因此,如果您的应用程序要多次运行,那么最好使用向量提供更大的种子空间。

当然,这假定您正在使用随机数生成器可以利用矢量种子。RandomLib提供MT19937和

更新2014-08-04:

Boost现在有一个跨平台的实现,random_device。下面是一个使用不可预测种子从boost中播种伪随机生成器的示例:

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/random_device.hpp>
boost::random::mt11213b rng( (boost::random_device())() );