我有一个矩阵:
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循环。请帮帮我。
答案 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])