我在一个小型 ascii 游戏中玩程序生成,我在 haskell 中遇到了这个随机数问题。基本思想是提供一个随机数,以游戏世界的某些部分的 (x,y) 为种子,例如决定那里是否有一棵树 ( this guy explains it nicely )
这是我为每一代尝试不同种子时得到的结果:
randomFromSeed :: Int -> Int -> Int
randomFromSeed max seed = fst (randomR (0, max - 1) (mkStdGen seed))
Prelude> map (randomFromSeed 10) [1..20]
[5,9,3,7,1,5,9,3,7,1,5,9,3,7,1,5,9,3,7,1]
它的周期显然是 5,但另一方面在 mkStdGen docs 上它说:
The function mkStdGen provides an alternative way of producing an initial generator, by mapping an Int into a generator. Again, distinct arguments should be likely to produce distinct generators.
那么怎么会,似乎只有 5 个不同的生成器来了?
当给定不同的种子时,如何让它们真正随机?
编辑 出于某种奇怪的原因,使用更大的数字会更好:
Prelude> let mult = 1000000 in map (randomFromSeed 10) [0,mult .. 20*mult]
[3,7,0,6,9,2,8,1,4,0,3,9,2,5,1,4,7,3,6,9,5]
最佳答案
您可以使用 pcg-random 避免意外行为而不是 random :
import System.Random.PCG
import Control.Monad.ST
randomFromSeed :: Int -> Int -> Int
randomFromSeed max seed = runST $ do
g <- initialize (fromIntegral seed) 0
uniformR (0, max - 1) g
main :: IO ()
main = print $ map (randomFromSeed 10) [1..20]
关于haskell - haskell中给定种子的随机数质量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61969876/