如何确保 RNG 在后续流程启动时具有唯一的种子?
摘要:我需要一种简单的独立方式来为我的 RNG 提供种子,以便每次启动程序时种子都不同。
详细信息:
我经常需要多次运行相同的程序(使用随机数进行计算,例如蒙特卡罗模拟等),以便对结果进行良好的统计。在这种情况下,重要的是随机数生成器在每次运行时都具有不同的种子。
我希望有一个简单的跨平台解决方案,可以包含在程序本身中。 (即,我不想总是麻烦地使用一个脚本来使用不同的种子参数启动程序的每个实例。)
请注意,使用 time(0)
作为种子不是这是一个很好的解决方案,因为计时器分辨率很差:如果并行启动多个进程,它们很可能从 time(0)
获得相同的种子。
要求:
- 尽可能简单
- 跨平台(目前我需要它只能在 Windows 和 Linux、x86 和 x64 上工作)。
- 自包含:不应依赖于启动程序的特殊方式(从启动脚本将种子作为参数传递太麻烦)。
- 我想将整个事情包装到一个小库中,我可以以最小的努力将其包含在任何新项目中,只需执行类似
SeedMyRNG(getSeed());
EDIT:
根据我发现的答案中提供的指针 os.urandom()
作为 Python 解决方案(对我也很有用)。
Summary: I need a simple self-contained way to seed my RNG so that the seed is different every time the program is launched.
Details:
I often need to run the same program (which does calculations with random numbers, e.g. Monte Carlo simulation etc.) many times to have good statistics on the result. In this case it is important that the random number generator will have a different seed on each run.
I would like to have a simple, cross-platform solution for this that can be contained within the program itself. (I.e. I don't want to always go to the trouble of having a script that launches each instance of the program with a different seed parameter.)
Note that using time(0)
as a seed is not a good solution because the timer resolution is bad: if several processes are launched in parallel, they are likely to get the same seed from time(0)
.
Requirements:
- as simple as possible
- cross platform (currently I need it to work on Windows & Linux, x86 & x64 only).
- self contained: shouldn't rely on a special way of launching the program (passing the seed as a parameter from the launch script is too much trouble).
- I'd like to wrap the whole thing into a small library that I can include in any new project with minimal effort and just do something like
SeedMyRNG(getSeed());
EDIT:
Although my main question was about doing this in C (or C++), based on the pointers provided in the answer I found os.urandom()
as a Python solution (which is also useful for me).
Related relevant question: How to use /dev/random or urandom in C?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
“跨平台”是一个主观术语。您的意思是“任何平台”(您将来可能会遇到)还是“每个平台”(在您支持的平台列表中)?这是我通常采用的一种务实方法:
检查您是否有
/dev/urandom
;如果是,请从那里种子。在 Windows 上,使用
CryptGenRandom()
。如果所有其他方法均失败,则从
time()
进行种子。"Cross-platform" is a subjective term. Do you mean "any platform" (you might encounter in the future) or "every platform" (on your list of supported platforms)? Here's a pragmatic approach that I usually take:
Check if you have
/dev/urandom
; if yes, seed from there.On Windows, use
CryptGenRandom()
.If all else fails, seed from
time()
.您可以在 Linux 上使用 dev random,在 Windows 上使用 加密 api。编写一个小型库来呈现一个独立于平台的界面,它应该完全满足您的需求。
You could use dev random on Linux and the crypto api on Windows. Write a small library to present a platform independent interface and it should do exactly what you want.
查看 RandomLib
这是一个 C++ 随机数库,对种子有很好的支持。在
特定
导致 r 被播种为数字的向量(来自对
RandomSeed::SeedVector()) 几乎肯定是唯一的。这
包括时间、微秒、pid、hostid、年份。
不太理想的是,您还可以使用 RandomSeed::SeedWord() 进行播种
如果可能的话,从 /dev/urandom 读取。但是,您通常会得到一个
使用单个 32 位字作为种子运行 2^16 次后发生种子冲突。
因此,如果您的应用程序运行多次,您最好使用
向量提供更大的种子空间。
当然,这假设您正在使用随机数生成器
可以利用载体种子。 RandomLib 提供 MT19937 和
SFMT19937,两者都使用载体种子。
Check out RandomLib
which is a C++ random number library with good support for seeds. In
particular
causes r to be seeded with a vector of numbers (from a call to
RandomSeed::SeedVector()) which is almost certainly unique. This
includes the time, microseconds, pid, hostid, year.
Less optimally, you can also seed with RandomSeed::SeedWord() which
reads from /dev/urandom if possible. However, you will typically get a
seed collision after 2^16 runs with a single 32-bit word as your seed.
So, if your application is run many times, you are better off using the
bigger seed space offered by a vector.
Of course, this supposes that you are using a random number generator
that can make use of a vector seed. RandomLib offers MT19937 and
SFMT19937, which both use vector seeds.
2014年8月4日更新:
Boost 现在有跨平台实现,
random_device
。下面是一个使用不可预测的种子从 boost 中播种伪随机生成器的示例:Update on 2014-08-04:
Boost has a cross-platform implementation now,
random_device
. Here's an example for seeding a pseudo-random generator from boost using an unpredictable seed: