生成包含从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 ]


慕村9548890
浏览 888回答 3
3回答

RISEBY

这个ndgrid函数几乎给出了答案,但有一个警告:n必须明确定义输出变量才能调用它。自n是任意的,最好的方法是使用逗号分隔列表(从单元格数组生成的n作为输出。结果n然后将矩阵连接到所需的n-栏表:vectors = { [1 2], [3 6 9], [10 20] }; %// input data: cell array of vectorsn = 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 order combs = cat(n+1, combs{:}); %// concat the n n-dim arrays along dimension n+1combs = reshape(combs,[],n); %// reshape to obtain desired matrix

慕仙森

简单一点.。如果您有神经网络工具箱,您可以简单地使用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{:}).')

慕妹3146593

我已经对两种建议的解决方案做了一些基准测试。基准测试代码基于timeit功能,并包括在这篇文章的末尾。我考虑两种情况:大小的三个向量n,以及三个大小向量n/10, n和n*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
打开App,查看更多内容
随时随地看视频慕课网APP