PRNG(伪随机数生成器)和种子值

在 Lua 脚本中,我正在使用以下 PRNG:

inputseed = {763261}
seedobja = 1103515.245
seedobjc = 12345
seedobjm = 4294967.295 --0x100000000

function srandom(seedobj, fVal1, fVal2)
    seedobj[1] = mod(seedobj[1] * seedobja + seedobjc, seedobjm)
    local temp_rand = seedobj[1] / (seedobjm - 1)
    if (fVal2) then
        return floor(fVal1 + 0.5 + temp_rand * (fVal2 - fVal1))
    elseif (fVal1) then
        return floor(temp_rand * fVal1) + 1
    else
        return temp_rand
    end
end

-- 返回值应该是一个 0 到 1 之间的浮点数
local randomvalue_a = srandom(inputseed)
-- 返回值应该是一个 10 到 20 之间的整数
local randomvalue_b = srandom(inputseed, 10, 20)

我的问题是,当通过这样的 PRNG 运行类似的种子值时,它们会产生类似的结果吗?

我的意思是,数字 3 和数字 5 相比于像 3001 这样的大数字更接近。前两个数字是否可能产生类似的伪随机值?

谢谢。

点赞
用户2417578
用户2417578

对于大多数伪随机数生成器(PRNGs),类似种子极不可能产生相似的结果,如果你需要多个种子,那相邻的整数是一个理想的选择,因为可以很容易地证明它们都是不同的,并且适当地分配这些种子是 PRNG 设计者的职责(尽管他们可能正在糟糕地执行他们的工作)。

对于那个特定的生成器,你应该直接运行一下算法,看看你得到了什么。如果它正确地工作,你应该看到种子 3 和 5 以同样快的速度分散,就像种子 3 和 3001 一样。

2016-07-10 18:18:55
用户4687565
用户4687565

Lua 和本问题无关。

记住,谷歌喜欢我们所有人。

这是一个线性同余生成器,在你的函数定义的第三行加了附加的风笛。

如果我们看第2行和第3行的公式,你会看到x*a+bx/(c-1)是具有完全相同属性的线性操作,然而在第2行也有mod(x,c)的操作,这实际上是周期性线性的,其周期为c。 因此,它是线性周期性的。除了少数点外,它是线性的。

如果你实际上测试这个算法,(例如这里),你会发现对于给定的参数,周期大约是3或4。

也就是说,对于像3和3.1这样的值,结果是接近的,但对于3和6.87的结果也是接近的。


顺带一提,这个高周期性意味着你的生成器不正确。因为你应该将生成器的输出馈入生成器本身,你希望它在输出的跨度范围内不是线性的(它的周期在(0,1)范围内的输出中必须显著小于1)。

为了实现这一点,在mod函数中分母必须低于分子。在你的情况下,seedobjcseedobjm必须交换。

2016-07-10 18:44:10