最初のステップでは、C ++ 11ラムダを使用して大きな効果を得ることができます(special.size()= K、およびall.size()= N)
#include <algorithm> // std::sort, std::transform, std::find, std::min_element
#include <iterator> // std::distance
std::vector<int> indices;
indices.reserve(special.size());
// locate exact index in all for every element of special. Complexity = O(K * N)
std::transform(special.begin(), special.end(), indices.begin(), [&all](Point2f const& s){
return std::distance(
all.begin(),
std::find(all.begin(), all.end(), s)
);
});
// sort special based on index comparison. Complexity = O(K * log(K))
std::sort(special.begin(), special.end(), [&indices](Point2f const& r, Point2f const& s){
auto i = std::distance(special.begin(), r);
auto j = std::distance(special.begin(), s);
return indices[i] < indices[j];
});
説明:まず、のすべての点について、の開始との特別な要素の位置とのspecial
間の距離を計算し、その結果をベクトルに格納します。次に、要素のすべてのペアについて、ベクトル内の対応する要素を比較することにより、のすべての要素を並べ替えます。all
all
indices
special
indices
2番目のステップでは、インデックスの計算方法を変更するだけです。
// locate closest element in all for every element of special. Complexity = O(K * N)
std::transform(special.begin(), special.end(), indices.begin(), [&all](Point2f const& s){
return std::distance(
all.begin(),
std::min_element(all.begin(), all.end(), [&s](Point2f const& a){
return // Euclidean 2D-distance between a and s
});
);
});
説明:最初のステップと比較した唯一の変更点は、すべての要素について、それに最も近いspecial
要素を見つけることです。これは、質問で提案した最小ユークリッド距離を計算することによって行います。all
更新all
:最初にのすべての要素のインデックスをハッシュテーブルに格納し、次にそのハッシュテーブルへのルックアップに基づいてstd::unordered_map
の要素間の比較を行うことにより、時空間のトレードオフを行うことができます。special
これにより、最初のステップの時間計算量がO(N)に減少します(K <Nと仮定)が、ハッシュテーブルのストレージのO(N)が追加されます。