这个问题经常以这样或那样的形式出现(例如参见here或here)。因此,我想我将以一种一般的形式提出它,并提供一个答案,以供将来参考。
给定一个任意数量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 ]
4条答案
按热度按时间pu3pd22g1#
ndgrid
函数几乎给出了答案,但有一个警告:n
输出变量必须显式定义才能调用它。由于n
是任意的,因此最好的方法是使用comma-separated list(由n
单元的单元阵列生成)作为输出。然后将得到的n
矩阵连接成所需的n
列矩阵:xdyibdwo2#
简单一点...如果你有神经网络工具箱,你可以简单地使用
combvec
:它以稍微不同的顺序返回一个矩阵:
如果你想要问题中的矩阵,你可以使用
sortrows
:这给
如果您查看
combvec
的内部(在命令窗口中键入edit combvec
),您将看到它使用的代码与@LuisMendo的答案不同。我不能说哪一个更有效率。如果你碰巧有一个矩阵,它的行类似于前面的单元数组,你可以用途:
zvms9eto3#
我已经对这两个提议的解决方案做了一些基准测试。基准测试代码基于
timeit
function,并包含在本文的末尾。我考虑两种情况:三个大小为
n
的向量,以及三个大小分别为n/10
、n
和n*10
的向量(两种情况给予相同的组合数目)。n
为240
(我选择这个值是为了避免在笔记本电脑中使用虚拟内存)。结果如下图所示。基于
ndgrid
的解决方案始终比combvec
耗时更少。同样有趣的是,combvec
所花费的时间在不同大小的情况下变化得不那么规律。基准代码
基于
ndgrid
的解决方案的功能:combvec
解决方案的功能:通过在这些函数上调用
timeit
来测量时间的脚本:qlckcl4x4#
这里有一个自己动手的方法,让我高兴地咯咯笑,使用
nchoosek
,虽然它 * 不 * 比@Luis Mendo的公认解决方案更好。对于给定的示例,在运行1,000次后,该解决方案平均花费了我的机器0.00065935 s,而接受的解决方案为0.00012877 s。对于较大的向量,根据@Luis Mendo的基准测试帖子,这个解决方案始终比公认的答案慢。尽管如此,我还是决定把它贴出来,希望你能从中找到一些有用的东西:
验证码:
给
说明:
L
使用cellfun
获取每个向量的长度。虽然cellfun
基本上是一个循环,但考虑到向量的数量必须相对较低,因此它在这里是有效的。V
连接所有向量,以便稍后访问(这假设您将所有向量输入为行。v'将适用于列向量。)nchoosek
获取从元素总数L(end)
中挑选n=length(v)
元素的所有方法。这里的组合会比我们需要的多由于
v(1)
中只有两个元素,因此我们需要丢弃任何J(:,1)>2
的行。类似地,其中J(:,2)<3
、J(:,2)>5
等.使用L
和repmat
,我们可以确定J
的每个元素是否在其适当的范围内,然后使用any
丢弃包含任何坏元素的行。最后,这些不是来自
v
的实际值,只是索引。V(J)
将返回所需的矩阵。