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

drkbr07n  于 8个月前  发布在  Matlab
关注(0)|答案(5)|浏览(121)

我想生成给定数量的向量的元素的所有可能组合。
例如,对于[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中找到这个吗?是否已经有一个预定义的函数可以执行此任务?

3vpjnl9f

3vpjnl9f1#

考虑使用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

或者,如果你想要一个任意数量的集合的通用解决方案(而不必手动创建变量),使用这个函数定义:

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);
5n0oy7gb

5n0oy7gb2#

在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
k3fezbri

k3fezbri3#

这个迟到的答案提供了两个额外的解决方案,其中第二个是 * 解决方案 *(在我看来)和改进Amro的答案解决方案与ndgrid通过应用MATLAB的强大的逗号分隔列表,而不是高性能的单元阵列,
1.如果你有神经网络接口:使用combvec
1.如果你没有工具箱,通常情况下:下面是另一种将笛卡尔积推广到任意集合数的方法。
正如Amro在他的回答中所做的那样,逗号分隔列表语法(v{:})提供了ndgrid的输入和输出。不同之处(第四行)在于,它通过应用逗号分隔的列表来避免cellfuncell2mat,现在再次作为cat的输入:

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

catreshape的使用将执行时间缩短了近一半。这种方法在my answer to an different questionmore formally by Luis Mendo中得到了演示。

kxkpmulp

kxkpmulp4#

从MATLAB 2023a开始,您可以使用combinations函数,该函数支持向量,矩阵,单元阵列及其混合:

>> combinations([1 2], [1 2], [4 5])

ans =

  8×3 table

    Var1    Var2    Var3
    ____    ____    ____

     1       1       4  
     1       1       5  
     1       2       4  
     1       2       5  
     2       1       4  
     2       1       5  
     2       2       4  
     2       2       5

输出的格式为table,它支持混合类型。如果输出只需要一个类型,可以使用table2array将输出转换为矩阵:

>> table2array(combinations([1 2], [1 2], [4 5]))

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

值得一提的是,我写了一个shim,它在旧版本的MATLAB中模拟combinations的行为(直到2013b版),包括对混合类型的支持:

function grid = combinations(varargin)
    grid = cell(nargin, 1);
    [grid{:}] = ndgrid(varargin{:});

    combos = cellfun(@(it) it(:), grid, 'UniformOutput', false)';
    combos = table(combos{:});
end
pobjuy32

pobjuy325#

我们也可以使用matlab中的'combvec'指令

no_inp=3 % number of inputs we want...in this case we have 3 inputs                  
    a=[1 2 3]
    b=[1 2 3]
    c=[1 2 3]

    pre_final=combvec(c,b,a)';
    final=zeros(size(pre_final));

    for i=1:no_inp
    final(:,i)=pre_final(:,no_inp-i+1);
    end
    final

希望有帮助。祝你好运

相关问题