说我有3个牢房:
M1={ [1,1,1], [2,2,2] }
M2={ [3,3], [4,4] }
M3={ [5], [6] }
我想获取M1
中的每个元素,将其与M2
的每个元素组合,并将其与M3
的每个元素,等等。
对于上面的输入,我想产生一个像这样的巨型细胞:
[1,1,1],[3,3],[5]
[1,1,1],[3,3],[6]
[1,1,1],[4,4],[5]
[1,1,1],[4,4],[6]
[2,2,2],[3,3],[5]
[2,2,2],[3,3],[6]
[2,2,2],[4,4],[5]
[2,2,2],[4,4],[6]
我该怎么做?通常,单元格(M1,M2...Mn
)的数量及其大小是未知的(并且正在变化)。
答案 0 :(得分:1)
此功能可以满足您的要求:
function C = add_permutations(A,B)
% A is a cell array NxK, B is 1xM
% C is a cell array N*M x K+1
N = size(A,1);
A = reshape(A,N,1,[]);
C = cat(3,repmat(A,1,numel(B)),repmat(B,N,1));
C = reshape(C,[],size(C,3));
它创建两个单元格数组的所有组合,方法是将它们复制到不同的维度,然后沿第3维连接并折叠前两个维。因为我们想用不同的单元格数组重复调用它,所以输入A
(N
x K
)每行都有K
个矩阵,这些是先前的组合。 B
是一个单元向量,每个元素将与A
的每一行结合。
您可以按以下方式使用它:
M1 = { 'a', 'b', 'c', 'd' }; % These are easier for debugging than OP's input, but cell elements can be anything at all.
M2 = { 1, 2 };
M3 = { 10, 12 };
X = M1.';
X = add_permutations(X,M2);
X = add_permutations(X,M3);
X现在包含:
X =
16×3 cell array
'a' [1] [10]
'b' [1] [10]
'c' [1] [10]
'd' [1] [10]
'a' [2] [10]
'b' [2] [10]
'c' [2] [10]
'd' [2] [10]
'a' [1] [12]
'b' [1] [12]
'c' [1] [12]
'd' [1] [12]
'a' [2] [12]
'b' [2] [12]
'c' [2] [12]
'd' [2] [12]
答案 1 :(得分:0)
这不是一个排列,而是一个枚举:您有3个符号,每个符号都有2个可能的值,而您只是在枚举所有可能的“数字”。您可以像计算3位数的二进制数一样来思考它。
在这种情况下,枚举所有这些可能性的一种方法是使用ndgrid
。如果M1
具有n1
个元素,则M2
具有n2
个元素,依此类推:
n1 = numel(M1);
n2 = numel(M2);
n3 = numel(M3);
[a,b,c] = ndgrid(1:n1, 1:n2, 1:n3);
此处a,b,c
是每个3维数组,它们表示组合的“网格”。显然,您不需要这样做,因此可以对它们进行矢量化处理,并使用它们来创建M1, M2, M3
中各种元素的组合,就像这样
vertcat( M1(a(:)), M2(b(:)), M3(c(:)) )
如果您有兴趣对任意数量的M
进行概括,也可以这样做,但是请记住,随着尺寸的增加,这些“网格”的增长非常快。
注意: vertcat
代表“垂直串联”,之所以垂直而不是水平,是因为M1(a(:))
的结果是一个行形单元,甚至尽管a(:)
是列向量。那只是索引头痛,但如果需要Nx3
,您可以简单地转置结果。