4

次の 2 つの行列があるとします。

m1 = [ 1 1;
       2 2;
       3 3;
       4 4;
       5 5 ];

m2 = [ 4 2;
       1 1;
       4 4;
       7 5 ];

次のような関数を探しています。

indices = GetIntersectionIndecies (m1,m2);

その出力は

indices = 
          1
          0
          0
          1
          0

ループを使用せずに、これら 2 つの行列間の行の交差インデックスを見つけるにはどうすればよいですか?

4

2 に答える 2

6

考えられる解決策の 1 つ:

function [Index] = GetIntersectionIndicies(m1, m2)
[~, I1] = intersect(m1, m2, 'rows');
Index = zeros(size(m1, 1), 1);
Index(I1) = 1;

ところで、私は @Shai の独創的なソリューションが大好きで、行列が小さい場合は私のソリューションよりもはるかに高速です。しかし、マトリックスが大きい場合は、私のソリューションが支配的になります。これは、 を設定すると、@Shai の応答T = size(m1, 1)tmp変数が T*T になるためです。つまり、Tが大きい場合は非常に大きな行列になります。簡単な速度テストのコードを次に示します。

%# Set parameters
T = 1000;
M = 10;

%# Build test matrices
m1 = randi(5, T, 2);
m2 = randi(5, T, 2);

%# My solution
tic
for m = 1:M
[~, I1] = intersect(m1, m2, 'rows');
Index = zeros(size(m1, 1), 1);
Index(I1) = 1;
end
toc

%# @Shai solution
tic
for m = 1:M
tmp = bsxfun( @eq, permute( m1, [ 1 3 2 ] ), permute( m2, [ 3 1 2 ] ) );
tmp = all( tmp, 3 ); % tmp(i,j) is true iff m1(i,:) == m2(j,:)
imdices = any( tmp, 2 );
end
toc

と を設定するT = 10M = 1000、次のようになります。

Elapsed time is 0.404726 seconds. %# My solution
Elapsed time is 0.017669 seconds. %# @Shai solution

しかし、設定するT = 1000M = 100、次のようになります。

Elapsed time is 0.068831 seconds. %# My solution
Elapsed time is 0.508370 seconds. %# @Shai solution
于 2013-01-24T06:33:08.533 に答える
3

使ってみてはどうですかbsxfun

function indices = GetIntersectionIndecies( m1, m2 )
    tmp = bsxfun( @eq, permute( m1, [ 1 3 2 ] ), permute( m2, [ 3 1 2 ] ) );
    tmp = all( tmp, 3 ); % tmp(i,j) is true iff m1(i,:) == m2(j,:)
    indices = any( tmp, 2 );
end

乾杯!

于 2013-01-24T06:31:09.040 に答える