使用MATLAB生成重复的所有组合

时间:2015-02-02 18:51:08

标签: matlab combinations combinatorics multiset

如何使用MATLAB创建给定集合的所有k-combinations with repetitions(也称为 k-multicombinations multisubsets )?

这类似于笛卡尔积,但两行只有它们的排序不同应该被认为是相同的(例如,矢量[1,1,2]=~=[1,2,1]被认为是相同的),所以生成笛卡尔积,然后应用unique(sort(cartesianProduct,2),'rows')应该会产生相同的结果。

示例: 调用nmultichoosek(1:n,k)应生成以下矩阵:

nmultichoosek(1:3,3)
ans =
     1     1     1
     1     1     2
     1     1     3
     1     2     2
     1     2     3
     1     3     3
     2     2     2
     2     2     3
     2     3     3
     3     3     3

3 个答案:

答案 0 :(得分:15)

我们可以使用wikipedia article中提到的双重投射,它将组合映射而不重复类型n+k-1 choose kk - 大小n的多重组合。我们生成组合而不重复,并使用bsxfun(@minus, nchoosek(1:n+k-1,k), 0:k-1);映射它们。这导致以下功能:

function combs = nmultichoosek(values, k)
%// Return number of multisubsets or actual multisubsets.
if numel(values)==1 
    n = values;
    combs = nchoosek(n+k-1,k);
else
    n = numel(values);
    combs = bsxfun(@minus, nchoosek(1:n+k-1,k), 0:k-1);
    combs = reshape(values(combs),[],k);
end

答案 1 :(得分:1)

暴力方法:生成所有元组,然后仅保留已排序的元组。不适用于nk的大值。

values = 1:3;                               %//  data
k = 3;                                      %//  data
n = numel(values);                          %//  number of values
combs = values(dec2base(0:n^k-1,n)-'0'+1);  %//  generate all tuples
combs = combs(all(diff(combs.')>=0),:);     %'// keep only those that are sorted

答案 2 :(得分:1)

这可能比以前的帖子更加残酷(内存密集)方法,但整洁可读:

 combs = unique(sort(nchoosek(repmat(values,1,k),k),2),'rows');