PRNG可调期

时间:2010-08-26 04:40:58

标签: language-agnostic random

我需要构建一个具有可调周期的就地伪随机数发生器。此外,一个时期内不得有任何冲突。也就是说,以下必须返回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是不可接受的;它必须至少有点随机。

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

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

1 个答案:

答案 0 :(得分:3)

我认为一个好的候选者是 Fibonacci线性反馈移位寄存器(LFSR)

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

只是摘录:

The initial value of the LFSR is called the seed, and because the operation 
of the register is deterministic, the stream of values produced by the 
register is completely determined by its current (or previous) state. 
Likewise, because the register has a finite number of possible states, it must 
eventually enter a repeating cycle. However, an LFSR with a well-chosen 
feedback function can produce a sequence of bits which appears random and 
which has a very long cycle.

唯一的问题是LFSR的周期总是2 N -1。
您可以克服这一点,注意到对于任何需要的时间段P,选择给出“下一个”2 N -1值的N可能会留下2 (N-1) - 从循环中抑制1个数字(因为如果你需要压制更多,只需用N-1生成)。

因此,抑制k值(k =((2 N -1) - P)⋳{1 ...,2 (N-1) - 1})你可以添加一些逻辑,如

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