4

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

细节:

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

我想为此提供一个简单的跨平台解决方案,该解决方案可以包含在程序本身中。(即,我不想总是麻烦地让一个脚本用不同的种子参数启动程序的每个实例。)

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

要求:

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

编辑:

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

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

4

4 回答 4

4

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

  1. 检查你是否有/dev/urandom;如果是,请从那里播种。

  2. 在 Windows 上,使用CryptGenRandom().

  3. 如果一切都失败了,从time().

于 2011-07-27T12:54:18.247 回答
1

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

于 2011-07-27T13:00:43.707 回答
1

查看RandomLib ,它是一个 C++ 随机数库,对种子有很好的支持。尤其

Random r;
r.Reseed();

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

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

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

于 2011-07-28T15:11:57.523 回答
0

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())() );
于 2014-08-05T03:11:38.607 回答