【问题标题】:PRNG with adjustable period具有可调周期的 PRNG
【发布时间】:2010-08-26 04:40:57
【问题描述】:

我需要构建一个具有可调周期的就地伪随机数生成器。此外,一个周期内不得发生碰撞。也就是说,以下内容必须返回 true:

// prng is "generated" at run-time
// (though a by-hand solution would work)

bool test(func prng, int period) {
    int seed = 0;  // Any number should work
    int cur = seed;

    for (int i = 0; i <= period; ++i) {
        cur = prng(cur);

        if (cur == seed) {
            if (i == period) {
                // We hit our period on target
                return true;
            }

            // Period too low (we hit our seed already!)
            return false;
        }
    }

    // Period too high
    return false;
}

(示例是伪代码;任何常用可读语言(C++、Python、Haskell 等)的答案都是可以接受的。)

在生成数字时,PRNG 必须依赖于可变的静态状态。也就是说,我不能有一个大表已经返回的数字或类似的东西。它应该只依赖给定的输入来生成下一个术语。

算法不必是密码学上的强(当然),或“强”随机。但是,x % period 是不可接受的;它必须至少是有点随机的。

我已经研究过线性同余生成器,但这似乎是针对我的特定约束的错误路径。

(暴力破解不是一种选择,除非它相对较快(几秒钟)。)

【问题讨论】:

    标签: language-agnostic random


    【解决方案1】:

    我认为一个很好的候选者是 斐波那契线性反馈移位寄存器 (LFSR)

    您可以从Wikipedia获取相关信息和算法。

    只是摘录:

    LFSR 的初始值称为种子,因为操作 寄存器的值是确定性的,由产生的值流 寄存器完全由其当前(或先前)状态决定。 同样,由于寄存器具有有限数量的可能状态,它必须 最终进入一个重复的循环。然而,一个具有良好选择的 LFSR 反馈函数可以产生一个随机的比特序列 周期很长。

    唯一的问题是 LFSR 的句点始终是 2N-1 的形式。
    您可以克服这一点,注意对于任何想要的周期 P,选择为您提供“下一个”2N-1 值的 N 可能会留下 2(N-1)-从循环中抑制 1 个数字(因为如果您需要抑制更多,只需使用 N-1 生成)。

    所以,要抑制 k 值 (k = ((2N-1) - P) ⋳ {1 ... ,2(N-1)- 1})您可以添加一些逻辑,例如

        If (Mod(cur,2(N-1)+1-k) == 0) Then
           cur=Mod(cur+1,2N-1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-13
      • 1970-01-01
      • 2016-03-12
      • 1970-01-01
      • 2023-03-09
      • 2014-05-19
      • 2021-03-01
      • 1970-01-01
      相关资源
      最近更新 更多