相关的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
.