【问题标题】:Enumerating combinations of cells枚举单元格的组合
【发布时间】:2018-07-25 19:20:50
【问题描述】:

假设我有 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) 的数量及其大小是未知的(并且会不断变化)。

【问题讨论】:

  • 您是否尝试过编写此代码?
  • 如果单元的数量未知,并且可能是无限的,则可能由于 RAM 不足等实际原因无法解决。
  • 您可以使用this answervectors = { M1 M2 M3 }

标签: matlab combinations cell-array


【解决方案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));

它通过在不同维度上复制两个元胞数组来创建它们的所有组合,然后沿第三维连接并折叠前两个维度。因为我们要用不同的元胞数组重复调用它,所以输入A (NxK) 每一行都有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]

【讨论】:

    【解决方案2】:

    这不是排列,而是枚举:您有 3 个符号,每个符号都有 2 个可能的值,您只是在枚举所有可能的“数字”。您可以像计算 3 位二进制数一样考虑它。

    在这种情况下,枚举所有这些可能性的一种方法是使用ndgrid。如果M1n1 元素,M2n2 元素等:

    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(:)) )
    

    如果您有兴趣将其推广到任意数量的 Ms,也可以这样做,但请记住,这些“网格”会随着您增加它们的维度而快速增长。

    注意: vertcat 代表“垂直连接”,之所以是垂直而不是水平是因为M1(a(:)) 的结果是一个行形单元格,即使a(:)是一个列向量。这只是索引令人头疼,但如果需要,您可以简单地转置结果Nx3

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-14
      • 1970-01-01
      • 1970-01-01
      • 2020-05-19
      • 2011-04-09
      相关资源
      最近更新 更多