生成列表中的所有combintations反复项目项目、列表中、combintations

2023-09-11 02:17:17 作者:握不住的沙

相关的this问题,我想知道的算法(和实际code在Java / C / C ++ / Python的/等,如果你有!)生成的所有组合研究 M 总元素的列表元素。有些 M 元素可以重复。

Related to this question, I am wondering the algorithms (and actual code in java/c/c++/python/etc., if you have!) to generate all combinations of r elements for a list with m elements in total. Some of these m elements may be repeated.

谢谢!

推荐答案

下面是一个递归,我相信有密切的关系让 - 伯纳德·Pellerin的算法,在数学的。

Here is a recursion that I believe is closely related to Jean-Bernard Pellerin's algorithm, in Mathematica.

此获得输入每个类型的元件的数目。输出采用类似的形式。例如:

This takes input as the number of each type of element. The output is in similar form. For example:

{a,a,b,b,c,d,d,d,d} -> {2,2,1,4}

功能:

f[k_, {}, c__] := If[+c == k, {{c}}, {}]

f[k_, {x_, r___}, c___] := Join @@ (f[k, {r}, c, #] & /@ 0~Range~Min[x, k - +c])

使用:

f[4, {2, 2, 1, 4}]

{{0, 0, 0, 4}, {0, 0, 1, 3}, {0, 1, 0, 3}, {0, 1, 1, 2}, {0, 2, 0, 2},
 {0, 2, 1, 1}, {1, 0, 0, 3}, {1, 0, 1, 2}, {1, 1, 0, 2}, {1, 1, 1, 1},
 {1, 2, 0, 1}, {1, 2, 1, 0}, {2, 0, 0, 2}, {2, 0, 1, 1}, {2, 1, 0, 1},
 {2, 1, 1, 0}, {2, 2, 0, 0}}

请求该code的说明。这是一个递归函数,它采用可变数量的参数。第一个参数是 K ,子集的长度。第二个是每种类型以供选择的计数的列表。第三个参数及以后在内部使用功能保持子集(组合),因为它是构建。

An explanation of this code was requested. It is a recursive function that takes a variable number of arguments. The first argument is k, length of subset. The second is a list of counts of each type to select from. The third argument and beyond is used internally by the function to hold the subset (combination) as it is constructed.

此定义,因此使用的时候有选择集中没有更多的项目:

This definition therefore is used when there are no more items in the selection set:

f[k_, {}, c__] := If[+c == k, {{c}}, {}]

如果组合(长度)的值的总和等于 K ,然后返回该组合,否则返回一个空集。 ( + C 的缩写加[C]

If the total of the values of the combination (its length) is equal to k, then return that combination, otherwise return an empty set. (+c is shorthand for Plus[c])

否则:

f[k_, {x_, r___}, c___] := Join @@ (f[k, {r}, c, #] & /@ 0~Range~Min[x, k - +c])

阅读左至右:

加入用于扁平化嵌套列表的水平,这样的结果是不是越来越深的张量。

Join is used to flatten out a level of nested lists, so that the result is not an increasingly deep tensor.

F [K,{R},C#]安培; 调用函数,下探选择集的第一个位置( X ),并加入了新的元素组合()。

f[k, {r}, c, #] & calls the function, dropping the first position of the selection set (x), and adding a new element to the combination (#).

/ @ 0〜范围〜敏[X,K - + C])零之间以及每个整数选择的第一个元素的小集,而 K 总组合少,这是可以在不超过组合大小 K 可选择的最大。

/@ 0 ~Range~ Min[x, k - +c]) for each integer between zero and the lesser of the first element of the selection set, and k less total of combination, which is the maximum that can be selected without exceeding combination size k.

 
精彩推荐
图片推荐