Sim*_*mon 33 matlab combinatorics cartesian-product
我想生成给定数量的向量的元素的所有可能组合.
例如,对于[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中帮助我吗?是否已有可以执行此任务的预定义功能?
Amr*_*mro 50
使用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
Run Code Online (Sandbox Code Playgroud)
或者,如果您需要任意数量的集合的通用解决方案(无需手动创建变量),请使用此函数定义:
function result = cartesianProduct(sets)
c = cell(1, numel(sets));
[c{:}] = ndgrid( sets{:} );
result = cell2mat( cellfun(@(v)v(:), c, 'UniformOutput',false) );
end
Run Code Online (Sandbox Code Playgroud)
请注意,如果您愿意,可以对结果进行排序:
cartProd = sortrows(cartProd, 1:numel(sets));
Run Code Online (Sandbox Code Playgroud)
此外,上面的代码不会检查集合是否没有重复值(例如:) {[1 1] [1 2] [4 5]}.如果您想要添加以下一行:
sets = cellfun(@unique, sets, 'UniformOutput',false);
Run Code Online (Sandbox Code Playgroud)
yuk*_*yuk 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
Run Code Online (Sandbox Code Playgroud)
cha*_*pjc 11
这个迟到的答案提供了两个额外的解决方案,其中第二个是解决方案(在我看来)和Amro的答案解决方案的改进,ndgrid通过应用MATLAB强大的逗号分隔列表而不是单元阵列来实现高性能,
combvec就像Amro在他的回答中所做的那样,逗号分隔列表语法(v{:})提供了输入和输出ndgrid.差异(第四行)是它避免cellfun并cell2mat通过应用逗号分隔列表再次,现在作为输入cat:
N = numel(a);
v = cell(N,1);
[v{:}] = ndgrid(a{:});
res = reshape(cat(N+1,v{:}),[],N);
Run Code Online (Sandbox Code Playgroud)
使用cat和reshape减少执行时间差不多一半.这种方法在我对另一个问题的回答中得到了证明,更正式的是Luis Mendo.