巨大なグラフでのダイクストラのアルゴリズム


15

私はダイクストラに非常に精通しており、アルゴリズムについて具体的な質問があります。35億ノード(すべてOpenStreetMapデータ)などの巨大なグラフがある場合、グラフをメモリに格納できないことは明らかなので、グラフはデータベースのディスクに保存されます。

そのようなグラフの最短経路を計算するために利用可能なライブラリがあります。彼らはどうやってこれをしますか?より具体的には、ダイクストラのアルゴリズムを実行するためにグラフの必要な部分をどのようにロードしますか?

訪問した各頂点の隣接リストを取得するには、統計データによると10,000ノードあたり約1,500のデータベースクエリが必要になるため、明らかにそうではありません。それはとても遅すぎるでしょう。

どうやってやっているの?自分で実装しようとしています。


2
彼らはダイクストラを使っていますか?あなたが説明する状況により適している可能性のある他の最短経路アルゴリズムがたくさんあります。
デビッドリチャービー

1
コードを調べましたか?どうやって知るべきですか?「データベースクエリ」-グラフの格納にDBMSを使用しないことを願っていますか?
ラファエル

@DavidRicherbyはい、このリンクを
-dimitris93

2
「[I] tは、純粋なCコードを調べるのに非常に退屈なプロセスです。」しかし、それがコードが何をするのかを知る唯一の方法です。あなただけ...あなたの質問のための最大の広告されていない、あなたのために面倒な作業を行うために私たちを求めているので
デヴィッドRicherby

1
@Shiro「これをどうやってやるの?」それが本当にあなたが尋ねたい質問ではない場合、言い換える必要があります。
ラファエル

回答:


6

そのようなグラフの最短経路を計算するために利用可能なライブラリがあります。彼らはどうやってこれをしますか?より具体的には、ダイクストラのアルゴリズムを実行するためにグラフの必要な部分をどのようにロードしますか?

DB、ディスクから読み取るカスタムファイル形式、およびインメモリ設定を使用できます。

しかし、DBを使用した私の経験からすると、「単純な」リンクリスト形式に基づいて独自のファイル形式を記述するよりも、約5〜10倍遅く、多くのメモリを消費します。

良いことは、OSMを使用するいくつかのソフトウェアフレームワークがあり、それらがオープンソースであるため、コードを詳しく調べることができることです。たとえば、こちらを参照してくださいGraphHopperオープンソースルーティングエンジンは、メモリから非常に簡単に切り替えることであるメモリ内の設定に(ディスクベース)を設定マップされた-両方の同じフォーマットを使用。「mmap」設定では、メモリが制限されたモバイルデバイスでの使用も許可され、サーバーなどの必要なRAMがある場合、モバイルデバイスははるかに高速に実行されます。たとえば、世界規模のグラフ(> 100mioノード)の場合、約8-10 GBのRAMが必要です。さらに、たとえば収縮階層を使用してすべてをさらに高速化する場合は、さらに多くのRAMが必要です。

この形式は非常に単純化されており、基本的に、必要なデータのみを保存し、いくつかのトリックを使用してコンパクトにします。詳細はこちらをご覧ください。免責事項:私はGraphHopperの著者です。

他の回答について:

ダイクストラスアルゴリズムは適用可能ですが、この問題には最適ではないと見なされます

「通常の」ダイクストラは非常に妥当なパフォーマンス(3mioノードの例のように国全体のクエリに対して1秒未満)を実行でき、「理論的な意味」で最適ですが、実稼働シナリオで高速にするには少し調整が必要です。また、Contraction Hierachiesなどの手法では、双方向の変更を使用して非常に優れたパフォーマンスを発揮します。

道路網は階層的で平面的です。

道路ネットワークは車の階層構造であり、平面ではありません(橋、トンネルなど)


もう一つ質問があります。NodeIDから最も近いノードをどのように見つけますlatitude/longitudeか?これは、最短パスA-> Bを計算するために必要です。また、すべての平方メートルにノードが含まれているわけではないため、AとBがノードとして存在しない可能性があることにも留意する必要があります。したがって、AとBの2つの最も近いNodeIDを見つける必要があります。
dimitris93

これは、たとえばGraphHopperの半径が約500mのセルにNodeIDを効率的に格納する4種類のツリーであるLocationIndexTreeで行われます。何も見つからない場合は、半径がある程度まで拡張されます。これは理論的には単純に聞こえますが、エリアを横断するエッジがある可能性があるため、非常に複雑です。エリアを作成およびクエリするときなどに、効率を上げる必要があります。
カルセル

最近傍を検索するとき、KD-Treesはより効率的ではありませんか?なぜKDツリーよりもクアッドツリーを選んだのですか?現在、ルーティングエンジンにKDツリーを実装しています。QuadTreesの実装を開始しましたが、KD-Treesは同じものであるが、コーディングが簡単で、最近傍のクエリが高速であると考えたため、停止しました。私が間違っている ?
dimitris93

クワッドツリーを使用する場合、バウンディングボックスを明示的に保存する必要はありません。これは、ストレージの利点をもたらします。クエリ速度は問題ではありません。実際、誰かがそのような試みを研究し、それは他の実装を含むすべてのパフォーマンスを上回りました。KDツリーですが、すべてが特定の実装に依存していると思います
...-Karussell

スタンフォードのこのPDFのページ9を見ると、KD-Treesで最近傍を検索するために境界ボックスを知る必要はまったくありません。もう1つは、すべてのポイントを事前に知っているため、lognの高さのバランスの取れたツリーを作成できることです。それでも、quadtreeにはkd-treeよりも有利な点があると確信していますか?
dimitris93

2

優先キューに隣接するすべてのエッジを配置する必要はありません。ダイクストラのアルゴリズムに「嘘をついて」、スタックから引き出された頂点、例えばwに付随する最短の頂点vのみを与えます。次に、vがキューから取り出されると、「おっと」と言いますが、私は間違いを犯したので、この頂点も指定する必要がありました。この方法で正しい解決策が得られ、キューサイズが多数ではなく1つのインシデント頂点に劇的に減少することが容易にわかります。ただし、必要に応じて、常に次の最も近い頂点を与えるために、発生を追跡する必要があります。道路網は平面的であると主張するコメントの1つは間違っています。実際、ある研究では、非常に非平面的であることが示されています。多くの非平面性を誘発する都市を通って橋を渡るすべての高速道路を考えてください。


0

ダイクストラスアルゴリズムは適用可能ですが、この問題には最適ではないと見なされますが、より効率的なバリアントは「類似」と見なされます。さまざまな単純化があります。道路網は階層的平面的です。基本的なアプローチは次のとおりです。このエリアは一般に「道路網のルート計画」として知られています。

  • グラフ構造は、隣接リストデータから「コンパイル」できます。これは、引用するライブラリ、SpatiaLiteのアプローチです。これらのグラフ構造は、グラフの場所がバイナリエンコードされた整数などで表される圧縮バイナリ形式で保存されるため、グラフの表示と操作は、すべての道路名などを保存するよりもはるかに少ないスペースで済みます。SpatiaLiteアルゴリズムは「オンライン」ではなく、完全にメモリ内で実行されるようです。

  • 並列/分散アルゴリズムがあります。たとえば、スケーラブルGPUグラフトラバーサル /メリル、ガーランド、グリムショーを参照してください。

  • 質問では、クライアントサーバーの用語、つまり「クエリ」を使用します。クライアント/サーバーの意味でデータベースを「照会」することによってアルゴリズムが実行されることはありません。SQLなどの高レベルのクエリ言語は、データベースへのインターフェイスであり、最小ルートを計算する要求を送信するために使用できますが、アルゴリズムによって内部的には使用されません。通常、アルゴリズムは「データベース内」、つまり完全に「サーバー側」で実行されます。そのため、データベースクエリで最短パスアルゴリズムを記述することは、小規模ネットワークには適していますが、中規模/大規模ネットワークには適していません。

  • わずかなパーセンテージ内の推定が許容される別のアプローチがあります。基本的な考え方は、ノード間の距離のインデックスを保持することです。たとえば、大きなグラフの最短経路の高速で正確な推定 / Gubichev、Bedathur、Seufert、Weikum

  • この(235p!)Phd論文は特に適用可能です。道路網 /シュルテスのルート計画

  • これらのアイデアの多くを使用するアルゴリズムもあれば、高度に調整された独自仕様のアルゴリズムがあり、競合する企業秘密に迫っています。たとえば、Googleの。このテーマに関する誤解を招くメディアがあるかもしれません。たとえば、Googleマップを可能にするシンプルでエレガントなアルゴリズムは、 Googleが引用なしでダイクストラアルゴリズムを使用していることを示しています。


1
Google Mapsは確かにDijskstraよりも優れたものにアップグレードされています。中途有能な開発者は誰でもロードマップにA *を使用しますが、以前の仕事では、Googleのエンジンがウェイポイント経由で2500 kmのルートを<100ミリ秒で再計画できることがわかりました。A *には速すぎるため、ArcFlagsのようなものを使用している可能性があります。
–MSalters

Karussellの答えは、「冒頭のダイクストラアルゴリズムは適用可能であるが、この問題には最適ではないと見なされる」というこの冒頭の文に挑戦しますが、これは物議を醸すものではありません。Schultes論文(初期)の主張に対する非常に強力なサポートがあります。これは、この分野の非常に包括的な/最近の調査であり、「階層的および平面的」「近似」も説明しています。残念ながら、大まかな検索に関する公開文献には、実際のGoogleアルゴリズムの兆候はないようです。
vzn

-2

そのような非常に大きなデータセットでは、このような高速の結果を得るには、パス圧縮を使用したユニオン検索データ構造を使用するのが最適であることがわかります。ただし、Djikstraのアルゴリズムのみを使用して最適化する場合は、グラフ内の各ノードが持つ情報に依存します。ほとんどの場合、1,500件すべてのクエリを実行する必要はありません。

たとえば、次の例を考えてみましょう。任意の2人の俳優(ベーコン数)の間の分離度を見つけようとしていて、最も重みの小さいパス(可能な限り最新の映画を使用したパス)を見つけたいとしましょう。ここで、という関数があるとしshortestPath(actor A, actor B);ます。次のシナリオを検討してください。

アクターAが1970年から演技し、アクターBが2000年から演技している場合、その情報があれば、アクターBの最初の映画から始まり、アクターAへの道をたどる方がはるかに論理的です。俳優Aが出演したすべての映画を反復処理することに反対

したがって、主なポイントは、ジクストラのアルゴリズムの最適化は、データセットが何であるかに本当に依存するということです。アルゴリズムを最適化するために、データセットに必要な情報をさらに提供する必要があります。

編集:同じ国の2つの都市間の最短経路を見つけようとしているとしましょう。この国がアルゼンチンよりも長い場合、国の経度と緯度に基づいてクエリを実行できます境界。次に、水平方向ではなく垂直方向(経度を使用)に移動し始めることができます。多くの場合、例外処理が必要になりますが、一般的な考え方は得られます。


1
ダイクストラでUnion-Findをどのように使用しますか?
ラファエル

データは、空間データ、緯度と経度です。それは明らかだと思いました。
-dimitris93
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.