简体   繁体   English

生成6个元素列表的所有组合,并对每个组合应用函数

[英]Generate all combinations of a 6 element list and apply a function to each combination

I want to generate all possible combinations of a 6 element list [x1,x2,x3,x4,x5,x6] with each xi being a number between 0 and 20. 我想生成6个元素列表[x1,x2,x3,x4,x5,x6]的所有可能组合,每个xi是0到20之间的数字。

I want to generate all possible combinations of such list, apply a function (takes the list as input and outputs a magical Int) to each list, then output the results to a list of tuples. 我想生成此类列表的所有可能组合,对每个列表应用一个函数(将列表作为输入并输出一个神奇的Int),然后将结果输出到元组列表。 So the list of tuples looks like 所以元组列表看起来像

[([x11,x21,x31,x41,x51,x61],Int1), ([x12,x22,x32,x42,x52,x62],Int2), ...]

I tried to this by hand by quickly realised that there are too many combinations and it is practically impossible to do by hand. 我很快就意识到有太多的组合,而手工几乎是不可能的。

The combinations are like [0,0,0,0,0,0], [1,7,0,10,11,6], [7,7,7,7,6,6], [20,20,20,20,20,20] and so on. 组合类似于[0,0,0,0,0,0],[1,7,0,10,11,6],[7,7,7,7,6,6],[20,20 ,, 20,20,20,20]等。

I know how to generate all combinations of a list and put them in a list of lists (because I asked this before) 我知道如何生成列表的所有组合并将它们放入列表列表中(因为我之前曾问过这个问题)

foo [] = [[]]
foo (x:xs) = foo xs ++ map (x:) (foo xs)

What I want to achieve this time is different because I am not trying to generate the different combinations within a particular list, I am trying to generate all 6 element lists. 这次我要实现的目标是不同的,因为我没有尝试在特定列表中生成不同的组合,而是试图生成所有6个元素列表。

As far as I can tell, you want a cartesian product (denoted by × here) of 6 lists [0..20] . 据我所知,您想要6个列表[0..20]的笛卡尔积(此处用×表示)。

So essentially, something like this: 所以本质上是这样的:

[0..20]×[0..20]×[0..20]×[0..20]×[0..20]×[0..20]

That's a lot of elements (85,766,121 to be exact). 这是很多要素(准确地说是85,766,121)。 But, it could be done. 但是,可以做到。

Perhaps an easier to understand version is as follows. 也许一个更容易理解的版本如下。

Let us define a function, cart , that would do something like a cartesian product over a list and a list of lists: 让我们定义一个函数cart ,它将对列表和列表进行类似笛卡尔乘积的操作:

let cart xs ls = [x:l | x <- xs, l <- ls]

This function will take all elements from xs , and all elements from ls and build a list of lists with all possible concatenations. 此函数将从xs提取所有元素,从ls提取所有元素,并构建一个包含所有可能串联的列表列表。

Now, we need a base case. 现在,我们需要一个基本案例。 Suppose you wanted a list of lists of a single element instead of six. 假设您想要一个由单个元素而不是六个元素组成的列表的列表。 How would you apply our cart function? 您将如何应用我们的cart功能? Well, since it adds each element from first argument to every element in second argument, we can pass a list of a single empty list as a second argument, and [0..20] as first argument: 好吧,由于它将第一个参数中的每个元素添加到第二个参数中的每个元素,因此我们可以将单个空列表的列表作为第二个参数,并将[0..20]作为第一个参数传递:

cart [0..20] [[]]

We get 我们得到

[[0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20]]

Great. 大。 Now we just apply it 6 times to its own result, starting with [[]] : 现在,我们将其应用到它自己的结果六次,从[[]]

foldr ($) [[]] $ replicate 6 (cart [0..20])

($) is function application. ($)是功能应用程序。

replicateM from Control.Monad (defined as sequence of n monadic actions: replicateM nx = sequence (replicate nx) ) basically does the same when applied to lists (see eg Why does application of `sequence` on List of Lists lead to computation of its Cartesian Product? for why exactly that is) So shorter answer would be like this: replicateMControl.Monad (定义为sequencen一元动作: replicateM nx = sequence (replicate nx)当施加到列表(参见例如基本上不相同为什么上列表的列表sequence`的`应用导致的计算其笛卡尔积?为什么会这样呢?

replicateM 6 [0..20]

You can map over those after this, eg 您可以在此之后映射,例如

map (\x -> (x, magicFunction x)) $ replicateM 6 [0..20]

foo f xs = map (\\ys -> (ys,f ys)) (replicateM (length xs) xs)

Here replicateM (length xs) xs will generate all combinations of the elements in xs . 在这里, replicateM (length xs) xs将生成xs元素的所有组合。 Then you just map over it. 然后,您只需将其映射即可。

Results in GHCI: GHCI中的结果:

>import Control.Monad
>let foo f xs = map (\ys -> (ys,f ys)) (replicateM (length xs) xs)
>foo sum [1,2]
[([1,1],2),([1,2],3),([2,1],3),([2,2],4)]

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

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