2014-03-29 64 views
1

我有一个关于Matlab中所有矩阵行组合的问题。我现在创建一个组合矩阵出一个两列矩阵的:matlab中两列矩阵的所有组合

输入:

1 2 
1 3 
1 4 
2 3 
2 4 
3 4 

我得到的是以下几点:

1 2 3 4 
1 3 2 4 
1 4 2 3 

而当输入矩阵具有从1:6它看起来像这样:

1 2 3 4 5 6 
1 2 3 5 4 6 
1 2 3 6 4 5 
1 3 2 4 5 6 
1 3 2 5 4 6 
.... 

现在我已经实施了以下解决方案,其中我窝rks近完美(感谢路易斯门多):

M = [1 2 
    1 3 
    1 4 
    2 3 
    2 4 
    3 4]; %// example data 
n = floor(max(M(:))/2); %// size of tuples. Compute this way, or set manually 

p = nchoosek(1:size(M,1), n).'; %'// generate all n-tuples of row indices 
R = reshape(M(p,:).', n*size(M,2), []).'; %// generate result... 
R = R(all(diff(sort(R.'))),:); %'//...removing combinations with repeated values 

我现在的问题是大小。我需要这个矩阵来实现优化算法,但是nchoosek-command会创建一个休眠矩阵,它会在最后一个命令行中缩短。实际上,我只能将此解决方案用于长度为15位的输入向量,因为nchoosek命令无法处理更多。

我现在正在搜索的是一种不使用nchoosek命令创建这些组合的方法。有人有一个想法如何?

感谢和最好的方面

乔纳斯

+0

看看这个:http://stackoverflow.com/questions/22301115/efficient-matlab-implementation-of-multinomial-系数 – tashuhka

回答

0

它不是从你解释清楚,但我相信:

  1. 所有M行是唯一的。
  2. 寻找行号为M的组合,其中没有数字出现两次。
  3. 每个组合的长度是floor(max(M(:))/2)*2

然后使用递归,这应该工作。

function [ U ] = searchappend(R,M, d, max_d) 

    % termination criteria 
    if d==max_d 
     U=R; 
     return; 
    end 

    lM = length(M(:,1)); 
    k=0; 
    U = []; 

    % seek for the row to append 
    for i=1:lM 
     if sum(ismember(M(i,:),R))==0 
      S = [R,M(i,:)]; 
      T = searchappend(S, M(i+1:end,:), d+1, max_d); 
      if k==0 && (~isempty(T)) 
       k=k+1; 
       U = [U;T]; 
      end 
     end 
    end 

end 
_____________ 

lM = length(M); 
n = floor(max(M(:))/2); 
A = []; 

for i=1:(lM-n+1) 
    R = M(i,:); 
    T = searchappend(R,M(i+1:end,:),1,n); 

    if ~isempty(T) 
     A = [A;T]; 
    end 

end 

请注意,我没有优化它,所以它可能会很慢。复杂度应该是O(n!),其中n是M中的行数。

+0

谢谢,代码非常好。我只需删除“if k == 0”...部分即可获得所有必需的组合。但不幸的是它并没有改变那么多。当我以例如M = nchoosek(1:16,2)开始程序时,我的matlab崩溃或需要数小时才能计算。似乎没有可能产生长度(M)> 15的矩阵 – Krus