奇怪的偏差随机数随机生成

时间:2015-01-16 17:15:12

标签: haskell

我认为我在这里做错了什么:

ghci> take 10 $ randomRs (1,6) (mkStdGen 2)
[6,4,1,5,4,2,2,2,2,3]
ghci> take 10 $ randomRs (1,6) (mkStdGen 3)
[6,4,5,4,4,2,1,1,5,1]
ghci> take 10 $ randomRs (1,6) (mkStdGen 5)
[6,2,2,1,3,2,5,1,5,4]
ghci> take 10 $ randomRs (1,6) (mkStdGen 7)
[6,1,4,5,3,2,3,6,6,6]
ghci> take 10 $ randomRs (1,6) (mkStdGen 11)
[6,4,4,6,1,2,6,5,6,5]

为什么第一个随机数总是“随机”6 ......?

对于从a到z的字母,“n”的相同模式:

ghci> take 10 $ randomRs ('a','z') (mkStdGen 13)
"nnofwbxbtw"
ghci> take 10 $ randomRs ('a','z') (mkStdGen 17)
"novkmtfugl"
ghci> take 10 $ randomRs ('a','z') (mkStdGen 19)
"nhurafjvey"

我通过LYAHFGG(第9章关于随机性)偶然发现了这一点并且真的没有理解它。我希望种子没有模式。

2 个答案:

答案 0 :(得分:6)

System.Random.StdGen是一个可怕的发电机,很久以前就应该更换了。甚至还有快速检查属性显然是错误的,由于StdGen的质量差导致数千次检查后仍然通过,并且这是通过良好的播种来完成的。

有许多强大的生成器,包括加密种类和统计数据。对于加密随机生成器,请考虑使用tf-random包替换为StdGenDRBG,或者为快速且统计上良好的生成器使用mersenne-random-pure64

答案 1 :(得分:3)

这些种子都是非常小的数字,比如maxBound :: Int小得多。因此,它们不是随机发生器的现实世界内部状态的代表性样本。基本上,randomR的第一个结果只是"随机种子"随机,WRT各自的范围。

如果你想要第一个结果的变化,你需要正确地散列种子,所以这些值在允许的整数范围内分散。最简单的方法是丢弃第一个结果。