問題
私が空港に立っていると想像してみてください。地理座標のペアが与えられた場合、どの空港にいるのかを効率的に判断するにはどうすればよいですか?
入力
(x,y)
_の座標ペア。[(a1,b1), (a2,b2)...]
ここで、各座標ペアは1つの空港を表します。必要な出力
ポイント_(a,b)
_に最も近い空港を表す空港座標ペアのセットからの座標ペア_(x,y)
_。
非効率的なソリューション
この問題を解決するための非効率的な試みを以下に示します。空港セットの長さは明らかに直線的です。
_shortest_distance = None
shortest_distance_coordinates = None
point = (50.776435, -0.146834)
for airport in airports:
distance = compute_distance(point, airport)
if distance < shortest_distance or shortest_distance is None:
shortest_distance = distance
shortest_distance_coordinates = airport
_
質問
このソリューションはどのように改善できますか?これには、現在立っている場所の座標に基づいて空港のリストを事前にフィルタリングしたり、事前に特定の順序でソートしたりする方法が含まれる場合があります。
座標が並べ替えられていない場合、(latitude,longitude)
最初に地球と同様に緯度でフィルタリングする
球の緯度1度は111.2 kmまたは69マイル
しかし、それは大きなスピードアップを与えることはありません。
最初に空港を緯度で並べ替えると、バイナリ検索を使用してcouldに一致する最初の空港を見つけることができます(airport_lat >= point_lat-tolerance
)そして、最後のcouldに一致するものだけを比較します(airport_lat <= point_lat+tolerance
)-ただし、0度が360に等しいことに注意してください。このライブラリを直接使用することはできませんが、 bisect のソースは、バイナリ検索の実装に適しています。
技術的にはこのようにして検索は依然としてO(n)ですが、実際の距離の計算(許容差による)ははるかに少なく、緯度の比較はほとんどありません。だからあなたは巨大なスピードアップをするでしょう。
K次元ツリーの使用:
>>> from scipy import spatial
>>> airports = [(10,10),(20,20),(30,30),(40,40)]
>>> tree = spatial.KDTree(airports)
>>> tree.query([(21,21)])
(array([ 1.41421356]), array([1]))
ここで、1.41421356はクエリされたポイントと最近傍点の間の距離であり、1は近傍のインデックスです。
これから SO質問 :
_import numpy as np
def closest_node(node, nodes):
nodes = np.asarray(nodes)
deltas = nodes - node
dist_2 = np.einsum('ij,ij->i', deltas, deltas)
return np.argmin(dist_2)
_
ここで、node
は2つの値(x、y)を持つタプルであり、nodes
は2つの値を持つタプルの配列です([(x_1, y_1), (x_2, y_2),]
)