如何确保在后续进程启动时RNG的种子是唯一的
How to ensure uniqe seeds for the RNG on subsequent process launches?
总结:我需要一个简单的自包含的方式来播种我的RNG,以便每次启动程序时种子都不同。
细节:
我经常需要多次运行相同的程序(使用随机数进行计算,例如蒙特卡罗模拟等)以获得良好的统计结果。在这种情况下,重要的是随机数生成器在每次运行时都有不同的种子。
我想有一个简单的,跨平台的解决方案,可以包含在程序本身。(也就是说,我不想总是让一个脚本用不同的种子参数启动程序的每个实例。)
请注意,使用time(0)
作为种子不是一个好的解决方案,因为定时器分辨率很差:如果多个进程并行启动,它们很可能从time(0)
获得相同的种子。
要求:
- 尽可能简单
- 跨平台(目前我需要它在Windows上工作&Linux, x86 &仅x64)。
- 自包含:不应该依赖于启动程序的特殊方式(从启动脚本传递种子作为参数太麻烦了)。
- 我想把整个东西包装成一个小的库,我可以包含在任何新的项目中,只需做一些像
SeedMyRNG(getSeed());
虽然我的主要问题是关于在C(或c++)中这样做,但根据答案中提供的指针,我发现os.urandom()
作为Python解决方案(这对我也很有用)。
相关问题:如何在C中使用/dev/random或urandom ?
"跨平台"是一个主观术语。您是指"任何平台"(将来可能会遇到)还是"每个平台"(在您支持的平台列表中)?以下是我通常采用的实用方法:
-
检查是否有
/dev/urandom
; -
在Windows上,使用
CryptGenRandom()
-
如果这些都失败,从
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())() );
- 如何创建一个空的全局类并在启动时实例化它
- 即使我读取了所有内容,在FIFO上打开的QSocketNotifier也会一直启动
- 使用 std::string () const 函数启动线程或未来
- 如何修复valgrind启动时的致命错误(与libc6-dbg和libc6-dbg:i386连接)
- 将向量作为类>(值)<向量启动和向量<类>[值]有什么区别
- 如何创建线程序列以按照启动顺序执行任务?
- WINAPI 注册应用程序重新启动时不清除打开的套接字
- 在挂钩启动新线程时解除挂钩进程
- 程序无法启动,因为缺少 libmpc-3.dll
- 从 exe 文件 (Visual Studio ) 启动时调试断言失败
- QSerialPort 在应用程序启动之前正在使用中
- 无法在 Arch Linux 中启动虚幻引擎 4
- C++关于指针和使用函数将它们启动到堆的行为究竟是什么?
- 如何使用 ctypes 停止和重新启动从 Python 运行的C++代码
- 程序在使用 system() 启动另一个可执行文件时停止
- Qt 和 Android - 如何使用 Qandroidjniobject 启动相机
- Q没有管理权限的 exe 无法启动维护工具
- 启动类函数作为失去引用的线程
- 如何使用C++确定应用程序是否已在窗口中启动?
- 如何确保在后续进程启动时RNG的种子是唯一的