简体   繁体   English

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

[英]Matlab generate all possible team combinations

There's lots of questions that are similar to mine but I haven't found quite what I'm looking for yet. 有很多与我的问题相似的问题,但是我还没有找到我想要的东西。 I'm working on a project to optimize teaming in a class, and am not sure how to generate all possible team combinations. 我正在研究一个优化班级团队合作的项目,但不确定如何生成所有可能的团队组合。

Say I have a vector that's a list of numbered people, like 假设我有一个向量,其中列出了已编号的人,例如

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

I want to generate all possible combinations of teams with k people per team, where k is smaller than n . 我想生成所有可能的团队组合,每个团队有k个人,其中k小于n The output should be matrices where the rows are the teams. 输出应该是矩阵,其中行是团队。 Each matrix will have k columns, and n/k rows (corresponding to the number of teams). 每个矩阵将有k列和n/k行(对应于团队数)。

For example, say my vector is <1,2,3,4> . 例如,假设我的向量是<1,2,3,4> I want all combinations of teams of 2. My possible output matrices would be [1,2;3,4] , [1,3;2,4] , and [1,4;2,3] . 我想要2个团队的所有组合。我可能的输出矩阵将是[1,2;3,4][1,3;2,4][1,4;2,3] I'd like to know how to scale this up to any n and k value. 我想知道如何将其缩放到任何nk值。

I have done only some incomplete testing, but this seems to work. 我只做了一些不完整的测试,但这似乎可行。

Code : 代码

%// 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));

The result matrices are given by result(:,:,1) , result(:,:,2) etc. 结果矩阵由result(:,:,1)result(:,:,2)等给出。

Explanation : 说明

The key steps are: 关键步骤是:

  • Line M = unique(perms(ceil((1:n)/k)), 'rows').' M = unique(perms(ceil((1:n)/k)), 'rows').' : this assigns k different team numbers, one to each group of n/k people, and creates all different permutations of those numbers. :这将分配k不同的团队编号,每组n/k个人一个,并创建这些编号的所有不同排列。 So this includes all possible team groupings. 因此,这包括所有可能的团队分组。

  • for loop: this translates the above representation into the matrix format you want: each team is described by a row containing n/k labels from the set {1,2,..., n }, telling which people belong to that team. for循环:这会将上面的表示形式转换为您想要的矩阵格式:每个团队由一行包含来自{1,2,..., n }集合中的n/k标签的行描述,告诉哪些人属于该团队。 Within each row, those labels are always increasing. 在每一行中,这些标签始终在增加。

  • Line result = result(:,:,all(diff(result(:,1,:))>0, 1)) : this removes matrices that are row-permutations of others. result = result(:,:,all(diff(result(:,1,:))>0, 1)) :这将除去作为其他行置换的矩阵。 It does so by keeping only matrices whose first column is increasing. 通过仅保留第一列正在增加的矩阵来实现此目的。

Examples : 例子

For n=4; k=2 对于n=4; k=2 n=4; k=2 , n=4; k=2

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

For n=6; k=2 对于n=6; k=2 n=6; k=2 , 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
...

It is quite overkilling, but it seems to work: 这是很过分的,但似乎可以解决:

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}

I create all the possible combinations of n elements, and then I select the unique combinations that follow your criteria. 我创建n元素的所有可能组合,然后选择符合您条件的唯一组合。

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

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