我有矩陣:如何比較每隔一行一行的元素在同一矩陣
a = [ 1 2 3 4;
2 4 5 6;
4 6 8 9]
,我想每一行與每一其他兩行逐一進行比較。如果他們共享相同的密鑰,那麼結果會告訴他們有一個共同的密鑰。
我有矩陣:如何比較每隔一行一行的元素在同一矩陣
a = [ 1 2 3 4;
2 4 5 6;
4 6 8 9]
,我想每一行與每一其他兩行逐一進行比較。如果他們共享相同的密鑰,那麼結果會告訴他們有一個共同的密鑰。
這裏的一種解決方案(其推廣到比問題的樣品更大的矩陣):
comparisons = nchoosek(1:size(a,1),2);
N = size(comparisons,1);
keys = cell(N,1);
for i = 1:N
keys{i} = intersect(a(comparisons(i,1),:),a(comparisons(i,2),:));
end
功能NCHOOSEK用於生成所有行比較的獨特組合。對於您的問題中的矩陣a
,您將獲得comparisons = [1 2; 1 3; 2 3]
,這意味着我們需要比較第1行和第2行,然後是第1行和第3行,最後是第2行和第3行。keys
是存儲每個比較結果的cell array。對於每個比較,使用功能INTERSECT來查找公共值(即鍵)。對於問題中給出的矩陣a
,您將獲得keys = {[2 4], 4, [4 6]}
。
如果一個是100 * 20的矩陣還有一個問題,我們應該怎麼做才能比較100行與彼此的行並得到每一行的交集? – gurwinder 2009-11-17 16:36:09
@gurwinder:上面的代碼一般足以處理任何大小'a'可能。如果「a」是100乘20,那麼最終將執行4950個比較,所以「比較」將是4950乘2的矩陣,「keys」將是包含4950個元素的單元陣列(其中每個單元包含用於相應比較的一組公共密鑰)。 – gnovice 2009-11-17 16:43:17
@Amro:謝謝。我很想再次使用我的HANKEL解決方案(http://stackoverflow.com/questions/1702140/how-do-i-plot-lines-between-all-points-in-a-vector-in-matlab/1702336# 1702336),但NCHOOSEK有點清晰,我認爲OP將使用相對較小的矩陣。 – gnovice 2009-11-17 17:30:44
使用讓所有的組合與nchoosek的@gnovice的想法,我提出了另一種兩種解決方法:使用使用bsxfun ismember(由@loren說明)
唯一的區別是,相交排序並只保留唯一的公用密鑰。
a = randi(30, [100 20]);
%# a = sort(a,2);
comparisons = nchoosek(1:size(a,1),2);
N = size(comparisons,1);
keys1 = cell(N,1);
keys2 = cell(N,1);
keys3 = cell(N,1);
tic
for i=1:N
keys1{i} = intersect(a(comparisons(i,1),:),a(comparisons(i,2),:));
end
toc
tic
for i=1:N
query = a(comparisons(i,1),:);
set = a(comparisons(i,2),:);
keys2{i} = query(ismember(query, set)); %# unique(...)
end
toc
tic
for i=1:N
query = a(comparisons(i,1),:);
set = a(comparisons(i,2),:)';
keys3{i} = query(any(bsxfun(@eq, query, set),1)); %'# unique(...)
end
toc
...用下面的時間比較:
Elapsed time is 0.713333 seconds.
Elapsed time is 0.289812 seconds.
Elapsed time is 0.135602 seconds.
注意,即使通過預先分揀a
並增加了呼叫unique
環路(註釋部分)內,這兩種方法都仍然較快比intersect
。
Do * all *行必須共享一個公用密鑰才能被計數? – gnovice 2009-11-17 16:06:01
我的意思是在問題行中有1 2 3 4和第二行有2 4 5 6, 所以在這兩個共同的關鍵是2和4,我想知道我們如何得到這個交集在同一個矩陣? – gurwinder 2009-11-17 16:13:02