为了账号安全,请及时绑定邮箱和手机立即绑定

生成包含从n个向量中提取的所有元素组合的矩阵。

生成包含从n个向量中提取的所有元素组合的矩阵。

生成包含从n个向量中提取的所有元素组合的矩阵。这个问题经常以一种或另一种形式出现(例如,参见这里或这里)。所以我想我应该以一种一般的形式呈现出来,并给出一个答案,以供将来参考。给定任意数目n可能大小不同的向量,生成一个n-列矩阵,其行描述从这些向量中提取的所有元素的组合(笛卡尔积)。例如,vectors = { [1 2], [3 6 9], [10 20] }应给予combs = [ 1     3    10           1     3    20           1     6    10           1     6    20           1     9    10           1     9    20           2     3    10           2     3    20           2     6    10           2     6    20           2     9    10           2     9    20 ]
查看完整描述

3 回答

?
RISEBY

TA贡献1856条经验 获得超5个赞

这个ndgrid函数几乎给出了答案,但有一个警告:n必须明确定义输出变量才能调用它。自n是任意的,最好的方法是使用逗号分隔列表(从单元格数组生成的n作为输出。结果n然后将矩阵连接到所需的n-栏表:

vectors = { [1 2], [3 6 9], [10 20] }; %// input data: cell array of vectors


n = numel(vectors); %// number of vectors

combs = cell(1,n); %// pre-define to generate comma-separated list

[combs{end:-1:1}] = ndgrid(vectors{end:-1:1}); %// the reverse order in these two

%// comma-separated lists is needed to produce the rows of the result matrix in

%// lexicographical order 

combs = cat(n+1, combs{:}); %// concat the n n-dim arrays along dimension n+1

combs = reshape(combs,[],n); %// reshape to obtain desired matrix




查看完整回答
反对 回复 2019-06-05
?
慕仙森

TA贡献1827条经验 获得超7个赞

简单一点.。如果您有神经网络工具箱,您可以简单地使用combvec:

vectors = {[1 2], [3 6 9], [10 20]};combs = combvec(vectors{:}).' % Use cells as arguments

它以稍微不同的顺序返回矩阵:

combs =

     1     3    10
     2     3    10
     1     6    10
     2     6    10
     1     9    10
     2     9    10
     1     3    20
     2     3    20
     1     6    20
     2     6    20
     1     9    20
     2     9    20

如果您想要有问题的矩阵,可以使用sortrows:

combs = sortrows(combvec(vectors{:}).')% Or equivalently as per @LuisMendo in the comments: % combs = fliplr(combvec(vectors{end:-1:1}).')

这给了

combs =

     1     3    10
     1     3    20
     1     6    10
     1     6    20
     1     9    10
     1     9    20
     2     3    10
     2     3    20
     2     6    10
     2     6    20
     2     9    10
     2     9    20

如果你看看combvec(类型)edit combvec在命令窗口中,您将看到它使用的代码与@LuisMendo的答案不同。我不能说哪一个整体上更有效率。

如果碰巧有一个矩阵,其行与以前的单元格数组类似,则可以使用:

vectors = [1 2;3 6;10 20];vectors = num2cell(vectors,2);combs = sortrows(combvec(vectors{:}).')


查看完整回答
反对 回复 2019-06-05
?
慕妹3146593

TA贡献1820条经验 获得超9个赞

我已经对两种建议的解决方案做了一些基准测试。基准测试代码基于timeit功能,并包括在这篇文章的末尾。

我考虑两种情况:大小的三个向量n,以及三个大小向量n/10nn*10分别(这两种情况给出相同数目的组合)。n最多可达240(选择此值是为了避免在笔记本电脑中使用虚拟内存)。

结果如下图所示。这个ndgrid-基于解决方案的持续时间被认为比combvec..值得注意的是,combvec在不同大小的情况下,变化要少一些。



基准代码

功能ndgrid-基于基础的解决办法:

function combs = f1(vectors)n = numel(vectors); %// number of vectorscombs = cell(1,n); %
// pre-define to generate comma-separated list[combs{end:-1:1}] = ndgrid(vectors{end:-1:1}); %
// the reverse order in these two%// comma-separated lists is needed to produce the rows of the result matrix in%
// lexicographical ordercombs = cat(n+1, combs{:}); %// concat the n n-dim arrays along dimension n+1combs = reshape(combs,[],n);

功能combvec解决办法:

function combs = f2(vectors)combs = combvec(vectors{:}).';

通过调用来测量时间的脚本timeit关于这些职能:

nn = 20:20:240;t1 = [];t2 = [];for n = nn;
    %//vectors = {1:n, 1:n, 1:n};
    vectors = {1:n/10, 1:n, 1:n*10};
    t = timeit(@() f1(vectors));
    t1 = [t1; t];
    t = timeit(@() f2(vectors));
    t2 = [t2; t];end


查看完整回答
反对 回复 2019-06-05
  • 3 回答
  • 0 关注
  • 887 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信