如何在特定条件下生成n个向量的所有可能组合

时间:2015-01-08 16:17:47

标签: matlab combinations

来自A = {[2 31 40],[11 17],[5 8]},并使用这三个向量的特定组合(为向量的每个元素添加100,而不更改其他元素):

  2   31  140         11  117         5  108
  2  131   40        111   17       105    8
102   31   40

我希望能够在这三个矩阵的不同行之间产生所有可能的组合(矩阵12x7)。

2 个答案:

答案 0 :(得分:1)

你可以这样结合cellfunbsxfun

B = cellfun(@(n) bsxfun(@plus, n, 100*eye(numel(n))), A, 'UniformOutput', false)

B{:}
ans =
   102    31    40
     2   131    40
     2    31   140

ans =
   111    17
    11   117

ans =
   105     8
     5   108

如果您 按照问题中的顺序排列,请尝试flipudfliplrbsxfun的替代方法是repmat

B = cellfun(@(n) 100*eye(numel(n))+repmat(n,numel(n),1), A, 'UniformOutput',false)

答案 1 :(得分:1)

你不断提出非常密切相关的问题,并为他们获得答案,你应该尝试自己连接所有的部分。

在这种情况下,从Horchler的优秀答案开始,将此结果注入Luis Mendo的(同样出色的)answer以获得所有可能的组合(在几个问题中你多次给出) ,然后建立你的最终矩阵。

在实践中:

%% // initial data
A = {[2 31 40],[11 17],[5 8]} ;

%% // count a few things before we start
nBlock = numel(A) ;                 %// number of elements sub matrix in "A"
nElem  = cellfun( @numel , A ) ;    %// number of elements in each sub matrix of "A"
nLines = prod(nElem) ;              %// number of lines in the final matrix

%% // Horchler solution (to get all the sub-matrix you requested)
B = cellfun(@(n) bsxfun(@plus, n, 100*eye(numel(n))), A, 'UniformOutput', false) ;

%% // connect both solution
Lines = arrayfun( @linspace , ones(1,nBlock) , nElem , nElem , 'UniformOutput',false) ;

%% // Luis Mendo solution
% // https://stackoverflow.com/questions/21895335/generate-a-matrix-containing-all-combinations-of-elements-taken-from-n-vectors
nBlock = numel(Lines);               %// number of vectors
combs = cell(1,nBlock);              %// pre-define to generate comma-separated list
[combs{end:-1:1}] = ndgrid(Lines{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(nBlock+1, combs{:});     %// concat the n n-dim arrays along dimension n+1
combs = reshape(combs,[],nBlock);    %// reshape to obtain desired matrix

%% // Finalisation (can be optimized but it works as it is)
for ii=nLines:-1:1
    tmpLine = [] ;
    for jj=1:nBlock
        tmpLine = [ tmpLine B{1,jj}(combs(ii,jj),:) ] ; %// %#ok<AGROW>
    end
    C(ii,:) = tmpLine ;
end

给你

>> C
C =
   102    31    40   111    17   105     8
   102    31    40   111    17     5   108
   102    31    40    11   117   105     8
   102    31    40    11   117     5   108
     2   131    40   111    17   105     8
     2   131    40   111    17     5   108
     2   131    40    11   117   105     8
     2   131    40    11   117     5   108
     2    31   140   111    17   105     8
     2    31   140   111    17     5   108
     2    31   140    11   117   105     8
     2    31   140    11   117     5   108