List 将Haskell列表随机化
我想编写一个Haskell程序,它将“ramdominize”列表中的元素:List 将Haskell列表随机化,list,haskell,List,Haskell,我想编写一个Haskell程序,它将“ramdominize”列表中的元素: import System.Random (getStdGen, randomRIO) import Data.List (permutations) rndElem :: [a] -> IO a rndElem xs = do index <- randomRIO (0, length xs - 2) return $ xs !! index rndPermutation :: [a] -&g
import System.Random (getStdGen, randomRIO)
import Data.List (permutations)
rndElem :: [a] -> IO a
rndElem xs = do
index <- randomRIO (0, length xs - 2)
return $ xs !! index
rndPermutation :: [a] -> IO [a]
rndPermutation xs = rndElem . permutations $ xs
import System.Random(getStdGen,randomRIO)
导入数据列表(排列)
rndElem::[a]->IO a
rndElem xs=do
索引IO[a]
rndpermutate xs=rndElem。置换$xs
然而,运行此命令似乎并没有完全随机地列出列表。由于某种原因,它只对其他每个元素进行随机化,例如[1,2,3,4,5,6]
-->[5,2,1,4,3,6]
。此算法的每次运行都将奇数索引(2、4、6)元素保持在同一位置。上述算法的索引中是否存在任何逻辑错误?尝试运行以下代码:
import System.Random (getStdGen, randomRIO)
import Data.List (permutations)
rndElem :: [a] -> IO Int
rndElem xs = do
index <- randomRIO (0, length xs - 7)
return index
import System.Random(getStdGen,randomRIO)
导入数据列表(排列)
rndElem::[a]->IO Int
rndElem xs=do
索引尝试运行以下代码:
import System.Random (getStdGen, randomRIO)
import Data.List (permutations)
rndElem :: [a] -> IO Int
rndElem xs = do
index <- randomRIO (0, length xs - 7)
return index
import System.Random(getStdGen,randomRIO)
导入数据列表(排列)
rndElem::[a]->IO Int
rndElem xs=do
索引一个非常好的随机化有限列表的算法是。以下是来自罗塞塔的代码:
import System.Random
import Data.List
import Control.Monad
mkRands = mapM (randomRIO.(,)0 ). enumFromTo 1. pred
replaceAt :: Int -> a -> [a] -> [a]
replaceAt i c l = let (a,b) = splitAt i l in a++c:(drop 1 b)
swapElems :: (Int, Int) -> [a] -> [a]
swapElems (i,j) xs | i==j = xs
| otherwise = replaceAt j (xs!!i) $ replaceAt i (xs!!j) xs
knuthShuffle :: [a] -> IO [a]
knuthShuffle xs =
liftM (foldr swapElems xs. zip [1..]) (mkRands (length xs))
一个非常好的随机化有限列表的算法是。以下是来自罗塞塔的代码:
import System.Random
import Data.List
import Control.Monad
mkRands = mapM (randomRIO.(,)0 ). enumFromTo 1. pred
replaceAt :: Int -> a -> [a] -> [a]
replaceAt i c l = let (a,b) = splitAt i l in a++c:(drop 1 b)
swapElems :: (Int, Int) -> [a] -> [a]
swapElems (i,j) xs | i==j = xs
| otherwise = replaceAt j (xs!!i) $ replaceAt i (xs!!j) xs
knuthShuffle :: [a] -> IO [a]
knuthShuffle xs =
liftM (foldr swapElems xs. zip [1..]) (mkRands (length xs))
我运行了这个程序,得到了[4,2,1,5,6,3]
。为什么“randomRIO(0,length xs-2)”中的“2”?@ScottNewson这不是确保我们将列表随机化的最佳方法吗?像Chris一样,我得到的结果看起来是随机的-使用格拉斯哥-哈斯克尔编译系统,版本7.10。3@user327088这是确保我们永远不会选择最后一个排列的最佳方法。我运行了这个,得到了[4,2,1,5,6,3]
。为什么“randomRIO(0,length xs-2)”中的“2”?@ScottNewson不是确保我们将列表随机化的最佳方法吗?就像Chris一样,我得到的结果看起来是随机的——使用格拉斯哥哈斯克尔编译系统,版本7.10。3@user327088这是确保我们永远不会选择最后一个排列的最佳方法。仍然不确定为什么会得到你观察到的模式(奇数索引元素总是在同一点上),因为克里斯和我都没有得到那种行为。仍然不确定为什么你会得到你观察到的模式(奇怪的索引元素总是在同一点上),因为克里斯和我都没有得到那种行为。