【发布时间】:2016-09-12 23:32:44
【问题描述】:
就在最近,我尝试编写一个程序,该程序基本上可以从在线游戏中模拟一个简单的系统。其背后的想法是,让程序计算最有效的项目集,以从一组中获得最大可能的统计效率。为了进一步澄清这一点: 你有 8 个物品槽和 74 种不同的物品,你不能使用任何物品两次,而且哪个物品在哪个槽中都没有关系。我什至还没有尝试计算一组统计数据,我之前就卡住了!
所以这个问题是过滤前(74 ^ 8)和过滤后(74选择8)的可能性数量。 当我尝试 head(permu' 2) 时,我的程序已经开始滞后。 既然我知道 Haskell 应该与无限列表一起使用,那么它如何与 899 万亿条目的列表一起使用?好吧,我显然知道 PC 需要很大的容量,但这就是我在这里问的原因:
如何处理 Haskell 中的大列表以便我可以使用它?
函数简化如下:
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort [a] = [a]
quicksort (x:xs) = (quicksort [y | y <- xs, y <= x]) ++ [x] ++ (quicksort [z | z <- xs , z > x])
eliminatedouble [] = []
eliminatedouble (x:xs) = if x `elem` xs then eliminatedouble xs else x:(eliminatedouble xs)
permu' n | n>8 = error "8 is max"
| otherwise = eliminatedouble (filter allSatisfied (generate n))
where
generate 0 = [[]]
generate x = [quicksort (a:xs) | a <- [1..74], xs <- generate (x-1)]
allSatisfied [] = True
allSatisfied (x:xs) = (checkConstraint x xs) && (allSatisfied xs)
checkConstraint x xs = not (doubled x xs)
doubled x xs = x `elem` xs
知道如何以更便宜的方式做到这一点会很有趣。
提前致谢,问候。
【问题讨论】:
-
供以后参考:
quicksort->Data.List.sort;eliminatedouble->Data.List.nub。elem的doubled别名似乎很奇怪。此外,nub与基于Data.Set的实现相比通常相当慢,并且allSatisfied也可能通过使用Data.Set加速很多。但正如我在回答中所描述的那样,最大的胜利将来自于首先只生成您关心的元素,而不是生成大量您不关心和过滤的东西。