2

サイズ 3XN の行列があります。行列の各列は 3 次元の点です。重複を削除したいのですが、最初の 2 次元の重複だけを気にします。重複するポイントが存在する場合 (つまり、x、y が同一)、3 番目の次元 (z 座標) で最も高い値を持つものを選択したいと思います。例: (最初の 2 次元は最初の 2 行です)

M = [ 1 1 1 2 3 4 5 5 ;
      4 4 4 6 6 3 2 2 ;
      3 4 5 3 4 5 7 8 ];
          ^ ^ ^ ^   ^

私は取得したい:

Res = [ 1 2 3 4 5 ;
       4 6 6 3 2 ;
       5 3 4 5 8]

マトリックスが非常に大きいため、できるだけ速く動作させる必要があります。したがって、可能であればソートなしで。ループやソートを行わずに、これを行うための matlab の「ショートカット」を探しています。ありがとうマトラビット

4

2 に答える 2

3

これは、次の方法で簡単かつ効率的に実行できますaccumarray

% - choose pairs of row/column indices - first two rows of M
% - accumulate using MAX of the values in the third row - this step removes the duplicates
res = accumarray(M(1:2,:)', M(3,:)', [], @max);

% i/j indices of non-zero entries in the result matrix are
% the unique index pairs, and the value is the maximum third row
% value for all duplicates
[i, j, v] = find(res);

% construct the result matrix
[i j v]'


ans =

 5     4     1     2     3
 2     3     4     6     6
 8     5     5     3     4

resインデックスが非常に大きく、メモリ上の理由で行列を作成できない場合は、accumarray関数の疎バージョンを使用できます。非ゼロのエントリのみを格納する疎行列を作成します。残りは同じままです。

res = accumarray(M(1:2,:)', M(3,:)', [], @max, 0, true);
于 2012-12-05T09:34:47.763 に答える
0

最初の 2 行をスキャンし、要素を に挿入しますmax-heap。挿入中に、要素が既に存在するかどうかをその場で確認できます (この場合、要素をヒープに挿入しないでください)。存在する場合は、現在の最大値と比較し、必要に応じて最大値として設定します。最終的な最大値は、求める結果です。

ヒープの構築は複雑でありO(n)、最大のチェックはこの境界に違反しません。したがって、並べ替えを使用O(n)する場合と比較して、合計時間の複雑さはO(nlogn)です。追加のO(n)スペースも必要になります。

于 2012-12-05T07:17:51.667 に答える