最近点を見つけるアルゴリズム


18

数百の都市とその緯度/経度のリストがあります。別の場所(緯度/経度)がある場合、最も近い都市を見つける必要があります。

私はGISを使用していないので、今では明らかなアルゴリズムはすべての都市に対してループを作成し、ポイント間の距離を計算することです。

ループを作成することは私にとって実用的ですが、それをより効率的に達成するためのアルゴリズムを実装するのは簡単ですか?それとも、それを解決するのに役立つ軽いJavaライブラリですか?

:完全なGISソリューションや重い/複雑なライブラリは必要ありません。私が解決する必要があるのはそれだけであるため、あまり良くはないが最も簡単で軽いソリューションを好む。


それで、距離が正しくないことは問題ではありませんか?そして、ある都市を別の都市よりも遠くにする可能性のある道路(対角線対正方形)を考慮したくないですか?
ブラッドネソム

はい、道路は私にとって重要ではありません。天気予報のために、距離が最も近い都市が必要です。
ルジョップ

1
天気予報?スーパーコンピュータと訓練された気象学者のスタッフが自由に使えることを願っています。
マイケルトッド

予測はマイケルによって行われ、私だけが最も近いものを取ります:)
lujop

回答:


24

デスクトップGISを設計するときに、20年前にこの質問を正確に調査しました。ポイントツーポイントの距離をインタラクティブに見つける必要がありました。私たちの目標は、数千のポイントに対して1/2秒未満で計算を行うことでした。テスト(25 MHz 486 PC!)では、説明したとおりに(単純な明白なアルゴリズムを使用して)すべての距離を計算できるため、クアッドツリー構造などのより洗練されたソリューションを作成するのは無意味であることが示されました。

単一の「プローブ」ポイントまでの距離を計算するには、(a)プローブポイントを中心とした等距離投影を使用してすべてのポイントを投影するか、(b)球体地球モデルを採用してHaversine式を使用します。楕円モデルの精度が必要な場合は、最初の方法が適切です。どちらの場合でも、計算はかなり速く、おそらく1000ティック未満で済みます。単一のプロセッサで1秒あたり約100万ポイントをクエリできます。

あなたに十分な速さ?そうでない場合、ブルートフォース方式は簡単に並列化され、プロセッサの数に直接スケーリングされます。ポイントをプロセッサ間で分割し、各プロセッサで見つかった最も近いポイントの最終比較を行うだけです。

より速くする必要がある場合は、スクリーンポイントにさまざまな近似値を使用できます。たとえば、緯度が-88〜+88度で、これまでに見つかった最も近い地点が200 km離れている場合、緯度がプローブポイントの緯度と2度を超えて異なる点は、近くに位置することはできません。地球では、1度の緯度が約110 kmを超えています)。多くの場合、この種の事前スクリーニングにより、1秒間に何億ものポイントを処理できるようになります。



4

私は、単純なループが「数百の都市」に効果的であるべきだということに同意します。

アプリケーションを考えると、楕円体の距離を扱うのはおそらく大げさなやり過ぎです。おそらく、数メートルまでしか局所性がない天気予報を扱っているでしょう。球面形状は、ループ内で簡単に実行できるほど単純です。

さらに簡単にすることもできます(たとえば、デルタlatをyとして、デルタlon * cos(lat)をxとして使用し、最小x ^ 2 + y ^ 2を見つけます)。ターゲット緯度のコサインを使用していますが、これは一度だけ計算します。これは、遠方の都市ではますます不正確になりますが、とにかく拒否されるため、問題ではありません。最寄りの都市が一般に数百キロメートル以内にあると仮定すると、これを使用した場合とより正確な式を使用した場合の結果(最も近い都市)の可能性は非常に小さく、差が「どの予測がとにかく、他の要因に依存する可能性があります(つまり、ノイズで失われます)。

組み込みシステムまたは低速のインタープリターを使用している場合を除き、他の人が提案している球面形式を使用するだけで十分でしょう。


1

これは既に述べたことに追加されますが、適切なデータ構造を選択することの重要性に留意すると思いました。.NETでK-Functionのコードを独自に作成しましたが、効率的なコレクションを使用すると処理が大幅に高速化されることがわかりました。正確な速度のO表記がわかりません。ポイントIDをキーとして、x座標とy座標に2つの辞書を使用しました。私はJavaを知らないので、何も提案できませんでした。

乾杯、デビッド

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.