2

したがって、x、y、zポイントの2つのリストのセットがあります。

List1 and List2.

List2にも存在するList1に存在するすべてのポイントを削除したいと思います。この例では、List2のほとんどのポイント(おそらく100%)がList1に存在します。例:

リスト1

1, 2, 3
4, 5, 6
7, 8, 9

リスト2

7, 8, 9

出力

1, 2, 3
4, 5, 6

これは、リストサイズごとに数千ポイントで発生します。明らかに、これは、List2をループして、時刻がO(n * m)のリスト1を検索することで実行できます。これを行うためのより高速でよりMATLABネイティブな方法はありますか?

助けてくれてありがとう。

4

3 に答える 3

4

試す: SETDIFF(List1, List2, 'rows')

(効率はわかりませんが、ネイティブメソッドなので最適化されていると思います。)

于 2012-06-29T05:19:18.603 に答える
2

これを行うためのわずかに高速な(一般的ではありませんが)方法を見つけました。最初の答えなので、フォーマットを学ぶので我慢してください...

目立ったスケーリング効果は見られなかったので、例として次の Lists オブジェクトを使用します。

example_step=3;
max_value_outer=example_step*333;
max_value_inner=example_step*33;
List1=[1:example_step:max_value_outer; 2:example_step:max_value_outer; 3:example_step:max_value_outer]';
List2=[1:example_step:max_value_inner; 2:example_step:max_value_inner; 3:example_step:max_value_inner]';

Turix の組み込み setdiff 呼び出しは、これまでで最高の結果を提供し、次のコード ブロックをわずか 3 秒未満で実行します。

tic; 
  for i=1:10000 result=setdiff(list1,list2,'rows'); 
  end;
toc
>> Elapsed time is 2.821303 seconds.

ただし、サンプル データ セットが、データがベクトル、整数、および合理的に制限された範囲内にあるという事実を表している場合は、次のように sub2ind を使用して、トリプレットの代わりに同等の線形インデックスを比較することで速度を上げることができます。

range=max_value_outer*ones(1,3);
[c,ia] = setdiff(sub2ind(range,List1(:,1),List1(:,2),List1(:,3)), sub2ind(range,List2(:,1),List2(:,2),List2(:,3))); result=List1(ia,:);
  result=List1(ia,:); 

これを 10,000 回実行して、行ごとの直接 setdiff と比較すると、次のようになります。

tic;
for i=1:10000 
  range=max_value_outer*ones(1,3); 
  [c,ia] = setdiff(sub2ind(range,List1(:,1),List1(:,2),List1(:,3)), sub2ind(range,List2(:,1),List2(:,2),List2(:,3))); 
  result=List1(ia,:); 
end; 
toc
>> Elapsed time is 2.285992 seconds.

そのため、setdiff(,,'row) の実行時間は約 20% 減少し、for ループの実装 (表示されていません) は約 98% 減少します。データがどのように見えるかに応じて、さらに高速化するいくつかのアイデアを思いつくことができます。たとえば、検討している maximum_value がメモリに比べて比較的小さい場合、サンプル空間をメモリにマッピングし、List1 の線形インデックスを使用してビットを高く設定し、その後に List2 のセットを設定して、線形インデックスを利用することができます。それらは低いです。High のままのビットは List1 にはありますが、List2 にはありません。私はその実装を保証しませんが、ここにその簡略化されたバージョンがあります。

それが役立つことを願っています!

于 2012-06-29T19:21:30.747 に答える
2

@Turix のsetdiffオプションが機能するはずです。別のオプション(キックのみ)は

List1(~ismember(List1,List2,'rows'), :);
于 2012-06-29T05:29:50.880 に答える