2012-12-29 114 views
2

我試圖解決這個問題,但我無法實現。 你能幫我什麼嗎?在MATLAB中查找多個數組的交集

問題

Mat1 | Mat2 | Mat3 

1 2 | 1 3 | 2 6 

1 3 | 2 6 | 2 5 

2 4 | 3 1 | 3 1 

3 1 | 3 5 | 5 2 

4 5 | 

當有3點矩陣(例如上文),我想在[column1 column2 matrixnumber]形式來得到這樣的結果爲相交的行。

上面例子中的結果將是

1 3 1 

1 3 2 

2 6 2 

2 6 3 

3 1 1 

3 1 2 

3 1 3 

如果結果是形式[column1 column2 firstmatrix secondmatrix, ...]

1 3 1 2 

2 6 2 3 

3 1 1 2 3 

對於這個問題,這將是好的,我想至多一個換用循環。

你有這方面的任何想法?

+0

可以肯定的是:如果在所有三個矩陣中出現配對,您想查看哪些內容?所有三個兩兩發生? –

回答

4

這裏的替代解決方案(這似乎跑得比岡瑟的更快)使用MATLAB的intersect

Mat = {[1 2; 1 3; 2 4; 3 1; 4 5], 
     [1 3; 2 6; 3 1; 3 5], 
     [2 6; 2 5; 3 1; 5 2]}; 

result = zeros(sum(cellfun(@(x)size(x, 1), Mat)), 3); % # Preallocate memory 
k = 1; 
for cc = transpose(nchoosek(1:numel(Mat), 2)) 
    x = intersect(Mat{cc}, 'rows');     % # Find intersection 
    y = ones(size(x, 1), 2) * diag(cc);    % # Generate matrix indices 
    result(k:k + numel(y) - 1, :) = [[x; x], y(:)]; 
    k = k + numel(y); 
end 

result(all(~result, 2), :) = [];      % # Discard zero rows 
result = unique(result, 'rows');      % # Discard repeated rows 

矩陣result現在應該包含唯一的交集的行及其相應的矩陣指數,就像你想要的:

result = 
    1  3  1 
    1  3  2 
    2  6  2 
    2  6  3 
    3  1  1 
    3  1  2 
    3  1  3 
+1

謝謝你的回答,它運作良好! – jzk171

3

如果我理解正確,您有多組配對:Mat1Mat2,Mat3,... MatN。現在你想找到唯一的配對,然後找出每個獨特配對出現在哪一組中。

如果你有大量的套,我建議你開始使用cell array持有所有這些,使事情更容易:

N = 3; % total number of data sets 
Mat = cell(N,1); 
Mat{1} = [1 2; 
      1 3; 
      2 4; 
      3 1; 
      4 5]; 
Mat{2} = [1 3; 
      2 6; 
      3 1; 
      3 5]; 
Mat{3} = [2 6; 
      2 5; 
      3 1; 
      5 2]; 
% etc. 

首先,讓我們找到了獨特的雙:

uniq_pairs = unique(cat(1,Mat{:}),'rows'); 
M = size(uniq_pairs ,1); 

然後使用ismember檢查這臺含有對:

matcontpair = false(M,N); %preallocate 
for ii=1:N % unavoidable loop 
    matcontpair(:,ii) = ismember(uniq_pairs,Mat{ii},'rows'); 
end 

若要將此交集矩陣轉換爲每對的一組矩陣號,再次循環並將最終結果存儲在單元陣列中(不能使用數組,因爲它們的大小可能不一樣(僅限於某些對一旦發現,其他兩次,其他三次......)

pair_occurence= cell(M,1); 
d=1:N; 
for jj=1:M 
    pair_occurence{jj} = d(matcontpair(jj,:)); 
end 

現在你有大小包含唯一對Mx2的矩陣uniq_pairs和occurence單元陣列大小Mx1pair_occurence:每個單元對應於一對幷包含該對存在的矩陣列表。

如果你想從列表中刪除對它們只在一個矩陣目前,使用以下命令:

% find them 
lonely_pairs = cellfun(@numel,pair_occurence)<2; 
% and destroy them 
uniq_pairs(lonely_pairs,:) = []; 
pair_occurence(lonely_pairs) = []; 
+0

謝謝你的回覆。當我檢查解決方案時,可能需要一些時間才能找到唯一的行,並在for循環中使用ismember函數。如果行數很大,那麼'獨特'的行會花費很長時間。 for循環中的'ismember'函數意味着它會搜索每一行的所有矩陣,因此可能需要一些時間(O(唯一行的數量*所有行的數量))您認爲您的解決方案是最優解決方案嗎? – jzk171

+1

您是不是想在每個矩陣中找到每一行呢?試一試@EitanT的解決方案,如果有很多獨特的行,那應該會更快。 –

+0

@GuntherStruyf感謝您的支持! –