与实例相关的确定性随机数生成器(与线程无关)
这里已经很好地介绍了随机数,所以我将保持简短。
我使用 srand 和 rand 在模拟中生成一些确定性随机数。然而,当在单独的线程上同时运行多个模拟时,单个序列会变得混乱并且变得不确定,因为所有线程都从同一个池中提取。有没有一种简单的方法可以“绑定”rand 以从特定实例进行绘制?或者我是否必须切换到诸如 Boost.Random
之类的东西?
Random numbers have been well covered here, so I'll keep it brief.
I use srand
and rand
to generate some deterministic random numbers in a simulation. However, when running multiple simulations at once on separate threads, the individual sequence gets muddled up and becomes non deterministic, because all threads draw from the same pool. Is there an easy way to "bind" rand
to draw from a specific instance? Or would I have to switch to something like Boost.Random
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您的编译器很可能已经有类似 Boost.Random 的东西。
C++0x 包含一个基于 Boost.Random 的
标头(这里和那里进行了一些调整)。在此之前,TR1(一组“半标准”库)也可用于大多数编译器,其中包含几乎相同的
标头。Your compiler most likely already has something very like Boost.Random.
C++0x includes a
<random>
header which is based on Boost.Random (with a few tweaks here and there).Before then, TR1, a set of "semi-standard" libraries was available for most compilers as well, which contains nearly the same
<random>
header.在 Linux 上,
rand_r
是rand
的可重入版本,但它是一个相当弱的 PRNG,因此可能需要使用*rand48_r
中的某些内容函数族。rand_s
是 Windows 上rand
的可重入版本,但由于其状态是无符号整数,因此它也必然相当弱。长话短说,使用 Boost.Random 可能会更好。
On Linux,
rand_r
is a reentrant version ofrand
, but it is a rather weak PRNG, so might want to use something from the*rand48_r
family of functions.rand_s
is a reentrant version ofrand
on Windows, but since its state is an unsigned int, it is also bound to be quite weak.Long story short, you're probably better off with Boost.Random.
我强烈建议使用
或
来细粒度访问高质量的 PRNG 类,您可以在每个线程中实例化一个完整的 PRNG 类。控制它们的种子以及由此产生的随机数序列。I strongly recommend using
<random>
or<tr1/random>
for fine-grained access to high-quality PRNG classes which you can instantiate one in each thread with full control over their seeds and thus their resulting sequence of random numbers.您可以使用此代码,为每个线程保留一个
rnd_state
结构。您可以使用rand()
初始化rnd_state。这只是一个想法,这也是一个合理的RNG。从linux内核源代码(random32.c)来看,
rnd_state中的值应该初始化为:s1> 1、s2> 7、s3> 15.
论文声称这是一个最大均匀分布的组合 Tausworthe 生成器
基于 GNU Scientific Library 1.5(2004 年 6 月 30 日)的代码
学术界:http ://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
You can use this code, keeping a
rnd_state
struct for each of the threads. You may initialize the rnd_state withrand()
. It's just an idea and this is a reasonable RNG.From the linux kernel source code (random32.c)
the values in rnd_state should be initialized like: s1 > 1, s2 > 7, s3 > 15.
The paper claims this is a maximally equidistributed combined Tausworthe generator
based on code from GNU Scientific Library 1.5 (30 Jun 2004)
Academia: http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
大量 PRNG 正在被添加到标准库中。另一种选择是为每个线程预先生成大量数字,然后一次发出一个。
A bunch of PRNGs are being added to the standard library. Another option is to pregenerate a large pool of numbers for each thread and then issue them one-at-a-time.
我的 C++ 随机数库 RandomLib 的文档包含
在 OpenMP 中使用并行数字流的说明;看
http://randomlib.sourceforge.net/html/parallel.html。你可能是
能够将其中提出的想法适应您的应用。
The documentation for my C++ random number library, RandomLib, contains
an illustration of using parallel number streams in OpenMP; see
http://randomlib.sourceforge.net/html/parallel.html. You might be
able to adapt the ideas presented there to your application.