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

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

例如,对于[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这个吗? 是否已经有一个预定义的函数可以完成这个任务?

在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 

考虑使用NDGRID函数的这个解决方案:

 sets = {[1 2], [1 2], [4 5]}; [xyz] = 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); 

这个晚答案提供了两个额外的解决方案,其中第二个是解决方案 (在我看来),并通过应用MATLAB的强大的逗号分隔列表而不是单元阵列来提高ndgrid的性能,

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

就像Amro在他的回答中一样,逗号分隔列表语法( v{:} )提供了ndgrid的输入和输出。 差异(第四行)是通过将逗号分隔的列表再次作为cat的输入来避免cellfuncell2mat

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

catreshape的使用将执行时间减半。 这个方法在我对另外一个问题的回答中得到了证明, Luis Mendo更正式地 回答了这个问题 。