3

我在 Unix 系统上使用 srandom() 和 random() 在 c 中生成随机数。我想要多个RNG。每个给定相同的种子,都应该输出相同的序列。我还想保存和恢复每个的状态。这是一个伪代码示例:

R1 = new_rng(5); //5 is the seed
R2 = new rng(5); //5 is the seed here, too.
a = R1.random();
b = R1.random();
d = R2.random(); //a == d
s1 = R2.get_state(); //save the state of R2
e = R2.random(); //b == e
R2.set_state(s1); //restore the state of R2
f = R2.random(); //b == f

我该怎么做呢?有时 RNG 会分叉到不同的线程中,我也需要在创建新线程时复制 RNG 的状态。

4

5 回答 5

6

使用erand48()//nrand48()jrand48()分别生成双精度浮点数、非负长整数或有符号长整数随机数这些功能使您可以根据需要拥有尽可能多的独立序列;状态作为参数传入,可以轻松保存和恢复。此外,序列由标准定义,即使在不同的平台上也不会因运行而变化。

其他一些答案建议rand_r()。此功能在 POSIX.1-2008 中已过时,其中包含以下说明:

drand48()函数提供了一个更精细的随机数生成器。

一个函数调用和另一个函数调用之间可以携带的状态量的限制意味着该rand_r()函数永远不能以满足伪随机数生成器的所有要求的方式实现。因此,只要必须满足重要的要求(包括安全性),就应避免使用此功能。

rand_r()功能可能会在未来的版本中删除。

于 2009-06-30T14:18:04.493 回答
1

阅读有关梅森捻线机的这篇文章。在最底部有几个实现的链接。(换句话说,自己实现一个 PRNG。)

于 2009-06-30T11:17:11.893 回答
1

在各种 UNIX 风格上有一些 C 库扩展:

  • BSD 喜欢随机,检查 initstate/setstate
  • _r 变体(random_r、srandom_r、initstate_r 等)
  • rand_r (stdlib.h)

您的目标 UNIX 支持哪种风格?

于 2009-06-30T11:31:34.363 回答
1

使用和rand_r(unsigned *seed)代替。这样您就可以维护多个随机种子。srand()rand()

于 2009-06-30T11:31:57.340 回答
0

我不确定在给定相同种子的情况下,您是否可以依靠 PRNG 来产生完全相同的序列。我知道有些方法是这样工作的,但我相信一些更好的方法包含一定数量的不确定性,因此相同的种子可能会导致不同的序列。您必须使用细齿梳子浏览您的 libc 文档,看看是否在某处提到了这一点。如果没有,请检查代码(如果您很幸运能够访问代码)。

无论如何,这确实会将您的应用程序非常紧密地耦合到您的 libc 中的 PRNG 实现。你肯定会被你正在开发的 libc 的风格所束缚,甚至可能是 libc 版本。如果此功能非常重要,您可能必须在应用程序中重新实现随机数生成,以确保可移植性和可重现性。

于 2009-06-30T11:09:46.713 回答