找到二维矩阵的行方向组合

时间:2014-10-08 07:45:38

标签: matlab concatenation combinations

我有一个矩阵:

X = [2,6,1; 3,8,1; 4,7,1; 6,2,1; 6,4,1; 7,3,1; 8,5,1; 7,6,1];

我想找到X的所有行方式组合,即

A(1) = [2, 6, 1; 3, 8, 1; 4, 7, 1]
A(2) = [2, 6, 1; 3, 8, 1; 6, 2, 1]
:
:
:

这是我尝试过的:

X = [2,6,1; 3,8,1; 4,7,1; 6,2,1; 6,4,1; 7,3,1; 8,5,1; 7,6,1];
p = 3
[m, n] = size(X);
comb = combnk(1:m, p);
[s, t] = size(comb);
c = [X(comb(:,1), :, :) X(comb(:,2), :, :) X(comb(:,3), :, :)];

这给了我一个矩阵:

c = 2     6     1     3     8     1     4     7     1
    2     6     1     3     8     1     6     2     1
    2     6     1     3     8     1     6     4     1

我想应用连接矩阵选项来获取c以使其动态,具体取决于p的值,但我不知道如何使用它。我不想使用For循环。请帮帮我。

3 个答案:

答案 0 :(得分:3)

这是完全矢量化的,所以它应该很快:

n = 3; %// number of rows to pick each time
ind = reshape(nchoosek(1:size(X,1), n).', [], 1); %'// indices of combinations
A = permute(reshape(X(ind,:).', size(X,2), n, []), [2 1 3]);

结果是

A(:,:,1)
ans =
     2     6     1
     3     8     1
     4     7     1

A(:,:,2)
ans =
     2     6     1
     3     8     1
     6     2     1

如果您需要以单元格数组的形式获得结果,可以通过以下方式将A从3D数组转换为单元格数组:

A = mat2cell(A, size(A,1), size(A,2), ones(1,size(A,3)));

答案 1 :(得分:2)

你的想法非常接近。这段代码完成了这项工作。我在代码中添加了注释,这应该很容易阅读。

X = [2,6,1; 3,8,1; 4,7,1; 6,2,1; 6,4,1; 7,3,1; 8,5,1; 7,6,1];
p = 3;
%// List all combinations choosing 3 out of 1:8.
v = nchoosek(1:size(X,1), p);
%// Use each row of v to create the matrices, and put the results in an cell array.
%// This is the A matrix in your question.
A = arrayfun(@(k)X(v(k,:), :), 1:size(v,1), 'UniformOutput', false);
%// And you can concatenate A vertically to get c.
flatA = cellfun(@(x)reshape(x, 1, []), A, 'UniformOutput', false);
c = vertcat(flatA{:});
PS:根据我的理解,我认为您想要的结果是 A ,这是一个易于使用的单元格数组。但为了以防万一,我添加了一个额外的步骤来完全按照你的问题获得 c

免责声明:就性能而言,arrayfun和cellfun几乎相当于for循环。

答案 2 :(得分:1)

你可以使用reshape和一堆转置来实现,因为Matlab是专栏 - major ordered

c = reshape(X(comb',:)',9,[])'

或者如果你想要一个3D矩阵:

A = permute(reshape(X(comb',:)',3,3,[])', [2,1,3])