【问题标题】:Two-way random number generator [duplicate]双向随机数生成器[重复]
【发布时间】:2015-11-22 23:05:24
【问题描述】:

我需要 PRNG,它不仅是可重复的,而且能够在两个方向上遍历它的内部状态。

例如

r = prng_from_seed(seed)
r.next # => 0.12332132412
r.next # => 0.57842057177
r.next # => 0.74782915912
r.prev # => 0.57842057177
r.next # => 0.74782915912

有哪些比较强大的PRNG算法有这个特性?

【问题讨论】:

标签: algorithm random


【解决方案1】:

使用一个简单的计数器作为种子,你用 next 增加,用 prev 减少。然后将此计数器用作另一个随机生成器的种子,用于生成随机数。

【讨论】:

  • 可能值得注意的是,除了使用另一个 PRNG,您可以使用一些块密码(具有固定的,可能是秘密密钥,可以从初始种子派生)来加密计数器值,然后以某种方式将生成的(随机)块转换为输出数。
【解决方案2】:

RNG 具有快速对数 (log2(N)) 向前和向后跳过(又名跳跃式)。它们基于 F. Brown 的论文“任意步长的随机数生成”,Trans。是。核。社会党。 (1994 年 11 月)。

相对简单的一种用于著名的 MC 代码 MCNP、Fortran 和 C++ 实现https://github.com/Iwan-Zotow/LCG-PLE63,虽然它不会像 Diehard 那样通过测试。

PCG 随机系列有点复杂,但质量上乘,http://www.pcg-random.org/

【讨论】:

【解决方案3】:

几乎所有 PRNG 都具有此功能,但没有人实现过转到上一个状态方法。

考虑:

  • 由于 PRNG 具有有限大小的状态,重复调用 next() 最终会进入您之前的状态。

  • 如果您从一个状态开始,通过 N 次调用 next() 最终会再次到达,那么您总是可以通过 N-1 次调用 next() 来找到前驱状态。

当然,在现实生活中,您会想要一种更有效的方式来实现 prev()。怎么做取决于RNG,但一般不会太难。

请注意,为了充分利用其状态,PRNG 被设计为具有尽可能大的周期。通常所有可访问的状态都在同一个循环中。

编辑:

我应该补充一点,当人们在现实生活中想要这样做时,他们通常只是使用计数器作为内部状态,并对其进行哈希处理(或使用固定密钥对其进行加密)以生成每个随机数。在加密上下文中,这称为“CTR MODE”加密,可通过谷歌搜索。

当然,如果你这样做,那么你可以随机访问每个状态。

【讨论】:

  • but nobody ever implements the go-to-previous state method 嗯?!请检查我的答案
猜你喜欢
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 2018-06-25
  • 2015-06-22
  • 2015-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多