如何确保RNG在后续流程启动时获得独特的种子?

时间:2011-07-27 12:50:55

标签: c++ c random cross-platform seed

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

详细信息:

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

我希望有一个简单的跨平台解决方案,可以包含在程序本身中。 (即,我不想总是遇到一个脚本,它使用不同的种子参数启动程序的每个实例。)

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

要求:

  • 尽可能简单
  • 跨平台(目前我需要它才能在Windows& Linux,x86和x64上工作)。
  • 自包含:不应该依赖于启动程序的特殊方式(将种子作为参数从启动脚本传递太麻烦了。)
  • 我想将整个内容包装到一个小型库中,我可以轻松地将其包含在任何新项目中,只需执行SeedMyRNG(getSeed());
  • 之类的操作

编辑:

虽然我的主要问题是在C(或C ++)中执行此操作,但基于答案中提供的指针,我发现os.urandom()是一个Python解决方案(对我来说也很有用)。

相关问题:How to use /dev/random or urandom in C?

4 个答案:

答案 0 :(得分:4)

“跨平台”是一个主观术语。您的意思是“任何平台”(您将来可能会遇到)或“每个平台”(在您支持的平台列表中)?这是我通常采取的务实方法:

  1. 检查您是否/dev/urandom;如果是的话,从那里播种。

  2. 在Windows上,使用CryptGenRandom()

  3. 如果所有其他方法都失败,请从time()种子。

答案 1 :(得分:1)

您可以在Linux上使用dev random,在Windows上使用crypto api。编写一个小型库来呈现一个独立于平台的界面,它应该完全符合您的要求。

答案 2 :(得分:1)

结帐RandomLib 这是一个C ++随机数库,对种子有很好的支持。在 特别

Random r;
r.Reseed();

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

不太理想,你也可以使用RandomSeed :: SeedWord()种子 如果可能,从/ dev / urandom读取。但是,您通常会得到一个 2 ^ 16次运行后的种子冲突,单个32位字作为种子。 因此,如果您的应用程序运行多次,您最好使用 矢量提供更大的种子空间。

当然,这假设您使用的是随机数生成器 可以使用矢量种子。 RandomLib提供MT19937和 SFMT19937,它们都使用矢量种子。

答案 3 :(得分:0)

2014-08-04更新:

Boost has a cross-platform implementation now, random_device。以下是使用不可预测的种子从boost播种伪随机生成器的示例:

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/random_device.hpp>

boost::random::mt11213b rng( (boost::random_device())() );