隣接リスト形式の大きな接続されたまばらなグラフがあります。できるだけ離れた2つの頂点、つまり グラフの直径 とそれを実現する2つの頂点を見つけたいと思います。
私は、さまざまなアプリケーションで、無向の場合と有向の場合の両方でこの問題に関心があります。有向の場合、私はもちろん有向距離(ある頂点から別の頂点への最短の有向パス)を気にします。
すべてのペアの最短経路を計算するよりも優れたアプローチはありますか?
編集:「可能な限り離れている」とは、もちろん「最長最短経路」を意味します。つまり、からの最短距離の頂点のすべてのペアの最大値です。一方から他方へ。
さて、私は問題と少しグーグルについて少し考えました、そして申し訳ありませんが、「すべてのペアの最短経路を見つけるだけ」ではないように見えるアルゴリズムを見つけることができません。
ただし、Floyd-Warshallがそのようなものを計算するための唯一のアルゴリズム(| V | ^ 3のBig-Theta)であると仮定すると、私はあなたに少し良いニュースがあります:Johnsonのスパースグラフのアルゴリズム(ありがとう、信頼できるCLRS!)は、(Big-Oh(| V | ^ 2 * lgV + VE))のすべてのペアの最短経路を計算します。これは、まばらなグラフの場合は漸近的に高速になるはずです。
ウィキペディアはそれが有向で機能すると言っています(無向についてはわかりませんが、少なくとも私はその理由を考えることができません)、ここに リンク があります。
グラフについて他に役立つものはありますか? 2D平面に簡単にマッピングできる場合(したがって、その平面とエッジの重みは三角不等式に従います[より厳しい要件を満たす必要があるかもしれませんが、よくわかりません])、いくつかの幾何学的アルゴリズムを破ることができるかもしれません。 (凸包はnlognで実行でき、そこから最も遠い点のペアを見つけるのは簡単です)。
お役に立てれば! -アゴール
編集:リンクが機能することを願っています。そうでない場合は、グーグルで検索してください。 :)
すべての最短経路以外に直径を計算するためのより良い方法はわかりませんが、MathematicaはPseudoDiameterに次の近似を使用します。
http://reference.wolfram.com/mathematica/GraphUtilities/ref/PseudoDiameter.html
編集コメントを続けることができるように、もう一度削除を取り消します。この回答の下に、ジョンソンのアルゴリズムに関するコメントがあります。 - アーロン
私の元のコメント:私もこの問題に興味がありますが、答えがありません。 最小全域木 、すべての頂点を接続しているが、エッジが最も少ない(または最も小さい)サブグラフに関連しているようです。これは、多くのアルゴリズムの古い問題です。そのうちのいくつかは実装が非常に簡単に思えます。
MSTが見つかったら、直径が明らかになることを当初は望んでいましたが、今は希望を失っています:-(おそらく、MSTを使用して、直径に妥当な上限を設定できます。これを使用して、速度を上げることができます。実際の直径をお探しですか?
無向グラフですべてのペアの最短経路よりもうまくいくことについてのいくつかの考えがありますが、それがどれだけ改善されるかはわかりません。
これは、距離D離れた2つのノードがある場合はそれを見つけるサブルーチンです。任意のノードxを選択し、M [x] = xから他のノードまでの最大距離を計算します(単一ソースの最短経路アルゴリズムを使用)。 M [x]> = Dの場合、xはノードの1つであり、もう1つは簡単に見つけることができます。ただし、M [x] <Dの場合、探しているエンドポイントはどちらもxからの距離D-M [x]より小さくすることはできません(そのノードからxを介して、距離< D)。したがって、xからD-M [x]未満の距離のすべてのノードを見つけて、それらを不良としてマークします。新しいxを選択します。今回は、不良としてマークされたすべてのノードを回避するようにして、繰り返します。うまくいけば、多くのノードを不良としてマークするので、| V |よりもはるかに少ない回数を実行する必要があります。最短経路計算。
ここで、D = diam(G)を設定し、上記の手順を実行する必要があります。 diam(G)が何であるかはわかりませんが、任意のx、M [x] <= diam(G)<= 2M [x]と同様に、かなり狭い範囲を取得できます。開始するxをいくつか選択し、それぞれについてM [x]を計算し、結果としてdiam(G)の上限と下限を計算します。次に、上記の手順を使用して、結果の範囲でバイナリ検索を実行し、推測された長さのパスがあればそれを見つけます。
もちろん、これは無向のみです。有向グラフでも同様のスキームができると思います。不良ノードは、D-M [x]未満でxに到達できるノードであり、diam(G)の上限が機能しないため、より大きなバイナリ検索範囲が必要になります。
それが法案に適合するかどうかはわかりませんが、興味深いです:
HADI:Hadoopを使用した大規模グラフでの高速直径推定とマイニング
U. Kang、C。Tsourakakis、A。P。Appel、C。Faloutsos、J。Leskovec、「HADI:Hadoopを使用した大規模グラフでの高速直径推定とマイニング」、CMU ML Tech Report CMU-ML-08-117、2008年。
グラフがツリー(および無向)の場合。 2つのdfを実行するだけです。ランダムなノードuとdfsから開始して、最も遠いノードvを見つけます。次に、vから開始して、最も遠い長さを見つけます。その長さが最適です
私の答えが構文に関して正しくないが、私のアルゴリズムコースが少し前だった(そして英語ではない)場合は許してください。
私があなたの問題を正しく理解しているなら、あなたはあなたのステップを「後退」せずにノードAから始めてノードBに到達することによってあなたが数えることができる最大の数が何であるかを知りたいです。この場合、グラフは非循環であると想像します(循環オプションは後で説明します)。
まず、上限はエッジの数です。私の見方は、1つのノードを取得し、そのノードがルートにあり、到達できる後続の各ノードが次のレベルにあるツリーを作成することです。構築する木の高さは直径であり、葉はその距離にあるノードです。その距離=エッジの数の場合は完了です。そうでない場合は、別のノードを選択して繰り返します。
幅優先探索の構築に似ていると思います。グラフについて他にあまり知らない場合は、ヒューリスティックを使用して、どのツリー方向(つまり、どのノードを最初に選択する必要があるか)が優れているかを確認できますが、それは別のトピックです。
グラフの周期性について-他の人が指摘しているように、それらは無限ループにつながる可能性があります。それらを取り除く方法は、サイクルに属するノードを「除外」し、サイクルに入って出て行くことによって得られる値として、それらの間の最長パスを追加することです。各ノードに1回だけ触れます。 。
さて、私が言ったように、この方法は、すべてのペアの最短経路を実行するのと非常に簡単に同じである可能性があります。最悪の場合の複雑さは確かに同じであり、そうでなければあり得ません。
無向グラフには利用可能な上限があり、それを下方に駆動できるため、すべてのペアを計算する必要がない場合があります。
Breath-First-Search(BFS)が任意のノードから実行されると、距離でソートされた他のすべてのノードのリストが生成されます。もちろん、最長距離は直径の下限とその候補です。
合計された上位2つの距離は、求める直径の上限です。これらの上位2つを取得する場合、これらのノードをエンドポイントとして使用する直径候補がすでにわかっているため、BFSを実行したノードを除外できます。長距離ノードをBFSを実行する次のノードとして優先することにより、上限は最終的に下限に到達します。これは、すべてのペアを完了する前に発生する可能性があります。
この数の推定を取得する1つの方法は、ランダムなポイントから開始し、幅優先の「グラスファイア」アルゴリズムを実行して、各ノードまでの最短距離をマークすることです。ここでの最長距離はあなたの見積もりです。
この非常に高速なアルゴリズムを異なる開始点で複数回実行してから最大値を取得すると、推定の精度が向上し、もちろん、適切な下限が得られます。グラフの分布と接続性によっては、この見積もりが正確になる場合もあります。
グラフが十分に大きい場合は、サンプルを追加するにつれて推定値がどのように変化するかを漸近的に分析することで、さらに適切な推測を行うことができます。
正確な答えに興味がある場合は、グラフが互いに弱く接続されているコンポーネントに簡単に分割できない限り、角を切りすぎて逃げることができないようです。その場合、検索を最短に制限できます。異なるコンポーネントの頂点のすべてのペア間のパス。
ある種のすべてのペアの最短パスアルゴリズムを使用せずに最長最短パスを見つける方法があるかどうかは本当に疑わしいです(単一ソースの最短パスを繰り返し見つけることは、基本的に最悪の場合すべてのペアを実行します)。
グラフがツリーまたはDAGでない場合、「直径」を「最長パス」で定義するのは困難になります。グラフにサイクルがある場合、「最長」パスは無限大になる可能性があります。したがって、グラフを単純にトラバースしても、すべてのノードで最長のパスを生成することはできません。グラフが必ずしも非周期的であるとは限らず、「最長最短」パスに関心があることをすでに述べているので、すべてのノードの最短パスを見つけることを回避できる方法はないようです。 Agorが示唆したように、Johnsonのアルゴリズムを使用することは、おそらくそれを行うのに最適です。
もちろん、ヒューリスティックベースのアプローチを使用することもできます。 疑似周辺頂点 を使用するアルゴリズムは、最も一般的に使用されるアプローチのようです。
頂点vを選択し、BFS(v)を実行します。これにより、すべての頂点のvからの距離が計算されます。最長距離を取得します。これはO(V + E)です
次に、すべてのv頂点に対してこのアルゴリズムを実行し、これらの最長距離の最大値を選択します。全体的な複雑さ:O(V *(V + E))