生成某些向量的元素的所有可能组合(笛卡尔积)

问题描述 投票:0回答:5

我想生成给定数量向量的元素的所有可能组合。

例如,对于

[1 2]
[1 2]
[4 5]
,我想生成元素:

[1 1 4; 1 1 5; 1 2 4; 1 2 5; 2 1 4; 2 1 5; 2 2 4; 2 2 5]

问题是我不知道需要计算组合的向量数量。在本例中可能有 3 个,也可能有 10 个,我需要一个概括。你能在 MATLAB 中帮我解决这个问题吗?是否已经有一个预定义函数可以完成此任务?

matlab combinatorics cartesian-product
5个回答
52
投票

考虑使用 NDGRID 函数来解决这个问题:

sets = {[1 2], [1 2], [4 5]};
[x y z] = ndgrid(sets{:});
cartProd = [x(:) y(:) z(:)];

cartProd =
     1     1     4
     2     1     4
     1     2     4
     2     2     4
     1     1     5
     2     1     5
     1     2     5
     2     2     5

或者,如果您想要任意数量的集合的通用解决方案(无需手动创建变量),请使用此函数定义:

function result = cartesianProduct(sets)
    c = cell(1, numel(sets));
    [c{:}] = ndgrid( sets{:} );
    result = cell2mat( cellfun(@(v)v(:), c, 'UniformOutput',false) );
end

请注意,如果您愿意,您可以对结果进行排序:

cartProd = sortrows(cartProd, 1:numel(sets));

此外,上面的代码不会检查集合是否没有重复值(例如:

{[1 1] [1 2] [4 5]}
)。如果您愿意,请添加这一行:

sets = cellfun(@unique, sets, 'UniformOutput',false);

17
投票

尝试 FileExchange 中的 ALLCOMB 功能。

如果将向量存储在元胞数组中,则可以像这样运行它:

a = {[1 2], [1 2], [4 5]};
allcomb(a{:})
ans =

     1     1     4
     1     1     5
     1     2     4
     1     2     5
     2     1     4
     2     1     5
     2     2     4
     2     2     5

13
投票

这个最新的答案提供了两个额外的解决方案,其中第二个是解决方案(在我看来)以及通过应用MATLAB强大的逗号分隔列表而不是单元数组来实现高性能,对Amro的答案解决方案进行了改进

ndgrid

  1. 如果您有神经网络工具箱:使用
    combvec
  2. 如果您没有有工具箱,通常情况就是这样:下面是推广任意数量集合的笛卡尔积的另一种方法。

正如 Amro 在他的回答中所做的那样,逗号分隔的列表语法 (

v{:}
) 提供了
ndgrid
的输入和输出。区别(第四行)是,它通过应用逗号分隔的列表来避免
cellfun
cell2mat
,现在再次作为
cat
的输入:

N = numel(a);
v = cell(N,1);
[v{:}] = ndgrid(a{:});
res = reshape(cat(N+1,v{:}),[],N);

使用

cat
reshape
将执行时间几乎减少一半。这种方法在我对另一个问题的回答以及路易斯·门多(Luis Mendo)更正式地中得到了演示。


0
投票

我们还可以使用matlab中的'combvec'指令

    no_inp=3 % number of inputs we want...in this case we have 3 inputs                  
    a=[1 2 3]
    b=[1 2 3]
    c=[1 2 3]

    pre_final=combvec(c,b,a)';
    final=zeros(size(pre_final));

    for i=1:no_inp
    final(:,i)=pre_final(:,no_inp-i+1);
    end
    final 

希望有帮助。 祝你好运。


0
投票

自 MATLAB 2023a 起,您可以使用

combinations
函数,它支持向量、矩阵、元胞数组及其混合:

>> combinations([1 2], [1 2], [4 5])

ans =

  8×3 table

    Var1    Var2    Var3
    ____    ____    ____

     1       1       4  
     1       1       5  
     1       2       4  
     1       2       5  
     2       1       4  
     2       1       5  
     2       2       4  
     2       2       5  

输出采用表格的形式。您可以使用

table2array
:

将输出转换为矩阵
>> table2array(combinations([1 2], [1 2], [4 5]))

ans =

     1     1     4
     1     1     5
     1     2     4
     1     2     5
     2     1     4
     2     1     5
     2     2     4
     2     2     5
© www.soinside.com 2019 - 2024. All rights reserved.