根据 demas 的评论,我试图调整你的算法。我们可能希望每个n
数字都与所有其他数字“相同”,因此我们将尝试直到得到正确的总和。也许有更好的方法。
-- f 0 rng = return []
-- f n rng = randomRIO (0,rng) >>= (\x-> fmap (x:) $ f (n-1) rng)
g n sumval =
let s = 2*sumval `div` n -- expected value upto z is probably z/2,
h i = do -- if all are equally likely
xs <- sequence $ replicate n (randomRIO (0,s))
if sum xs == sumval
then return (xs, i) -- i is number of attempts
else h (i+1)
in h 1
-- test:
Prelude System.Random> g 26 301
([15,23,15,0,13,8,23,11,13,19,5,2,10,19,4,8,3,9,19,16,8,16,18,4,20,0],2)
Prelude System.Random> g 26 301
([20,14,3,6,15,21,7,9,2,23,22,13,2,0,22,9,4,1,15,10,20,7,18,1,18,19],12)
Prelude System.Random> g 26 301
([4,3,4,14,10,16,20,11,19,15,23,18,10,18,12,7,3,8,4,9,11,5,17,4,20,16],44)
Prelude System.Random> g 26 301
([6,6,22,1,5,14,15,21,12,2,4,20,4,9,9,9,23,10,17,19,22,0,10,14,6,21],34)
Prelude System.Random> g 26 301
([20,9,3,1,17,22,10,14,16,16,18,13,15,7,6,3,2,23,13,13,17,18,2,2,8,13],169)