优化函数组合在输入上的排列的更好方法是什么



我有一个函数列表及其"应用优先级"。

它看起来像这样。其长度为33

listOfAllFunctions = [ (f1, 1)
, (f2, 2)
, ...
, ...
, (f33, 33)
]

我想做的是生成一个上面列表的排列列表,没有重复,我只想在内部列表中有8个唯一的元素。

我正在像这个一样实现

prioratizedFunctions :: [[(MyDataType -> MyDataType, Int)]]
prioratizedFunctions = nubBy removeDuplicates
$ sortBy (comparing snd)
<$> take 8
<$> permutations listOfAllFunctions

其中removeDuplicates被定义为类似

removeDuplicates a b = map snd a == map snd b

最后,我要把[(MyDataType -> MyDataType, Int)]的子列表变成函数和[Int]的组合

具有此功能的

compFunc :: [(MyDataType -> MyDataType, Int)] -> MyDataType -> (MyDataType, [Int])
compFunc listOfDataAndInts target = (foldr ((.) . fst) id listOfDataAndInts target
, map snd listOfDataAndInts)

(flip compFunc) target <$> prioratizedFunctions一样应用上述函数


以上所有内容都是实际代码的简化版本,但它应该提供要点。


问题是这个代码实际上需要很长时间才能执行。从一些原型设计来看,我认为这要归咎于我在prioratizedFunctions中实现了permutations函数。


所以我想知道,有没有更好的方法来做我想要的事情(基本上是生成listOfAllFunctions的排列,其中每个列表只包含8个元素,每个元素列表按其优先级排序,使用snd,并且不包含重复列表)

还是这个问题本质上是一个漫长的过程?

我生成了不必要的排列。

这个choose函数基本上是一个不确定的take函数

choose 0 xs = [[]] 
choose n [] = [] 
choose n (x:xs) = map (x:) (choose (n-1) xs) ++ choose n xs

这大大提高了性能。

最新更新