Matlab生成所有可能的团队组合

时间:2014-10-16 18:56:49

标签: matlab combinations discrete-mathematics

有许多类似于我的问题,但我还没有找到我正在寻找的东西。 我正在开发一个项目来优化课堂上的团队合作,并且不确定如何生成所有可能的团队组合。

说我有一个矢量,它是一个编号人员列表,比如

<1,2,3,4,5....,n>

我希望为每个团队k人生成所有可能的团队组合,其中k小于n。 输出应该是行是团队的矩阵。每个矩阵将包含k列和n/k行(对应于团队数量)。

例如,假设我的向量是<1,2,3,4>。我想要2个团队的所有组合。我可能的输出矩阵是[1,2;3,4][1,3;2,4][1,4;2,3]。我想知道如何将其扩展到任何nk值。

2 个答案:

答案 0 :(得分:2)

我只做了一些不完整的测试,但这似乎有效。

<强>代码

%// Data:
n = 6; %// number of people
k = 2; %// team size. Assumed to divide p

%// Let's go:
M = unique(perms(ceil((1:n)/k)), 'rows').'; %'// the transpose is for convenience
result = NaN(n/k, k, size(M,2)); %// preallocate
for t = 1:n/k
    [ii, ~] = find(M==t);
    result(t,:,:) = reshape(ii, k, []);
end
result = result(:,:,all(diff(result(:,1,:))>0, 1));

结果矩阵由result(:,:,1)result(:,:,2)等提供。

<强>解释

关键步骤是:

  • M = unique(perms(ceil((1:n)/k)), 'rows').':这会为k个人组分配n/k个不同的团队编号,并创建这些编号的所有不同排列。所以这包括所有可能的团队分组。

  • for循环:这会将上面的表示转换为您想要的矩阵格式:每个团队都由一行包含来自集合{1,2,...的n/k标签的行描述, n },告诉哪些人属于该团队。在每一行中,这些标签总是在增加。

  • result = result(:,:,all(diff(result(:,1,:))>0, 1)):这将删除作为其他行的排列的矩阵。它只通过保留第一列增加的矩阵来实现。

<强>实施例

n=4; k=2

>> result
result(:,:,1) =
     1     2
     3     4
result(:,:,2) =
     1     3
     2     4
result(:,:,3) =
     1     4
     2     3

n=6; k=2

>> result
result(:,:,1) =
     1     2
     3     4
     5     6
result(:,:,2) =
     1     2
     3     5
     4     6
result(:,:,3) =
     1     2
     3     6
     4     5
result(:,:,4) =
     1     3
     2     4
     5     6
...

答案 1 :(得分:1)

这太过分了,但似乎有效:

n = 4;
k = 2;

allCombinations = perms(1:n);

numComb = size(allCombinations,1);
selCombinations = zeros(size(allCombinations));
cellCombinations = cell(numComb,1);
for ii = 1:numComb
    candidate = sortrows(sort(reshape(allCombinations(ii,:),[],k),2));
    selCombinations(ii,:) = candidate(:);
    cellCombinations{ii} = candidate;
end

[~,idx] = unique(selCombinations, 'rows');
cellCombinations{idx}

我创建n元素的所有可能组合,然后选择符合条件的唯一组合。