約10億個の頂点を持つグラフがあり、それぞれがランダムに他の約100個の頂点に接続されています。
2点間の最短経路のlengthを検索したい。使用される実際のパスは気にしません。
ノート:
アルゴリズムを探しています。 Psuedocode、英語の説明、実際のコードはすべて素晴らしいです。
A *を使用することもできますが、パスファインディング用に最適化されているようです。
Dijkstraのアルゴリズム を使用することを考えましたが、すべての頂点の最短パス検出属性を無限大に設定する必要があるステップがあります
(ユースケースについて疑問がある場合は、アンダーハンドCコンテスト用です。)
基本アルゴリズム
開始ノードと終了ノードから到達できるノードの2つのセットを維持します。交互に、両側から3ステップ進みます。セットをノードに置き換えるたびに、もう1つのステップで到達できます。各ステップの後、2つのセットの共通ノードをチェックします。
最適化
単一のスイープで一般的なノードを検索できるように、セットをソートされたとおりに反復できることを確認してください:O(n + m)操作。リストはそれぞれ最大100万ノードになります。
セットを1ステップで拡張するには、元のセットのノードのすべての接続をクエリし、それらを新しいソート済みセットにマージします。ソートされた2つのリストのマージは、1回のスイープで再度実行できます。したがって、ソートされたノードの接続を照会できることを確認する必要もあります。 (これは前処理される可能性があります)。
最後の2つのステップでは、新しい各セットは、これらのクエリ結果の最大10000をマージした結果です。このマージアダプティブ(同じサイズのチャンクをマージ)を行うのが最善です。このようにして、ソートされたセットのデータ構造は、単純なリンクリストにすることができます。
このようにして、アルゴリズム全体がO(6 * n + 6 * n * log n)になります。ここで、nは最大です。 1,000,000。
ブレスファースト検索を使用してください(すべてのエッジが均一な長さなのでダイクストラのアルゴリズムは必要ありません)(そして、クリスヴァンバエルが言ったように、両側から実行してください)。
"All edges have a length of 1"
これは Dijkstra's Algorithm を完全な貪欲なアルゴリズムの選択にする最良のシナリオです。高速行列乗算を含む Floyd-Warshallアルゴリズム を使用しても、うまく機能します。