简体   繁体   English

Haskell用于随机排序列表不能正常工作(Homework)初学者

[英]Haskell functions to randomly order a list not working properly (Homework) beginner

Only began using Haskell a couple of weeks ago - I am attempting to randomly shuffle a list of type Card by splitting the list into two at a random point int eh list (depending on an array of random integers produced by the randomList function) and swapping the order of these two parts a number of times, but the output is not at all random, and the parse only seems to be happening once, pretty desperate as I need it working and the deadline is tonight! 几周前才开始使用Haskell - 我试图通过将列表分成两个随机点列表(取决于randomList函数生成的随机整数数组)并交换,随机地随机洗牌类型Card列表这两个部分的顺序很多次,但输出完全不是随机的,而且解析似乎只发生过一次,非常绝望,因为我需要它工作,截止日期是今晚!

randomList :: (Random a) => (a,a) -> Int -> StdGen -> [a]
randomList bnds n = take n . randomRs bnds

randomise :: [Int] -> [Card] -> [Card]
randomise [] p = p
randomise (x : xs) p = do
                    randomise xs ((drop x p) ++ (take x p))

shuffle :: Int -> [Card] -> [Card]
shuffle r p = do
          let g = mkStdGen r
          randomise(randomList (1, (length p)-1) 500 g :: [Int]) p

You can just make a random number of permutations on your list. 您可以在列表中随机排列一些排列。 You can do it like: 你可以这样做:

import System.Random
import Data.List

shuffle xs = do
    gen <- getStdGen
    let (permNum,newGen) = randomR (0,fac (length xs) -1) gen
    return $ permutation permNum xs

permutation makes n permutations on the (assumed sorted) list xs . permutation在(假定排序的)列表xs上进行n个排列。 When randomizing, xs need not be sorted however. 随机化时,不需要对xs进行排序。

fac is just an implementation of the factorial function. fac只是阶乘函数的一个实现。

shuffle makes a random number and applies that many permutations to xs . shuffle产生一个随机数并将这许多排列应用于xs

It's a bit different from what you are trying to do, but it works wonders. 它与你想要的东西有点不同,但它可以创造奇迹。 I assumed you didn't need to explicitly use your proposed method. 我假设您不需要明确使用您提出的方法。 You will have to implement permutation and fac yourself though. 你必须自己实现permutationfac

For help on permutation , you could look here . 有关permutation帮助,你可以看看这里 It's a description to solve a Project Euler Problem, but you could use the same procedure to make n permutations. 这是解决项目欧拉问题的描述,但您可以使用相同的过程来进行n个排列。

EDIT: I don't know if anyone cares anymore, but I found another way to do it WAY easier: 编辑:我不知道是否有人关心,但我发现另一种方式做到更容易:

import System.Random

randPerm :: StdGen -> [a] -> [a]
randPerm _ []   = []
randPerm gen xs = let (n,newGen) = randomR (0,length xs -1) gen
                      front = xs !! n
                  in  front : randPerm newGen (take n xs ++ drop (n+1) xs)

Quite late to the party, but a small improvement over the suggested solution is to use splitAt instead of take & drop: 聚会很晚,但对建议的解决方案的一个小改进是使用splitAt而不是take&drop:

shuffle :: [a] -> StdGen -> [a]
shuffle []   _   = []
shuffle list generator = let (index,newGenerator) = randomR (0,length list -1) generator
                             (listUntilIndex, element:listAfterIndex) = splitAt index list
                         in  element : shuffle (listUntilIndex ++ listAfterIndex) newGenerator

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM