web-dev-qa-db-ja.com

大きなグラフの2つのサブグラフ間の最短経路を見つけるにはどうすればよいですか?

私は重み付けされた無向マルチグラフを使用しています(ループは許可されていません。ほとんどのノード接続には多重度1があり、いくつかのノード接続には多重度2があります)。このグラフの2つのサブグラフの間で、互いに重なり合わない最短経路を見つける必要があります。始点/終点として使用するノードに他の制限はありません。

エッジは特定の時間にグラフから選択的に削除できるため( 私の前の質問 で説明されているように)、指定された2つのサブグラフについて、それらを接続する方法がない可能性があります。

このアルゴリズムは聞いたことがあると思いますが、それが何と呼ばれるか思い出せません。Googleが「サブグラフ間の最短経路」などの文字列を検索しても役に立たなかったのです。誰かが1つのサブグラフのすべてのノードと他のサブグラフのすべてのノード間の最短経路を比較するよりも、これを行うためのより効率的な方法を提案できますか?または、少なくともアルゴリズムの名前を教えて、自分で調べられるようにしますか?

たとえば、以下のグラフがある場合、赤で囲まれたノードは1つのサブグラフであり、青で囲まれたノードは別のサブグラフである可能性があります。画像には表示されていませんが、エッジにはすべて正の整数の重みがあります。赤のノードで始まり青のノードで終わる限り、総コストが最も短いパスを見つけたいと思います。これは、特定のノードの位置とエッジの重みが無視できないことを意味すると思います。

enter image description here

(これは私が手に入れたグラフの例です Wikimediaから で描いたもので、実際の問題ではありません。)

6
Pops

ダイクストラのアルゴリズムを適用できるはずです。

グラフに2つのポイントAとBを追加するだけで、それぞれサブグラフの1つに接続されます。次に、2つのポイントAとBの間の最短経路を計算します。

2つのサブグラフ間の最短経路は、結果からA&Bを削除した後に得られる経路でなければなりません。

4
Jens Schauder

設計が不十分なコードに偽のノードとエッジを作り込もうと一日苦労した後、私はSJuan76の提案が本当に非常にエレガントであると考え始めています。すべてのケースで機能することを証明することはできませんが、いくつかの例を手動で実行したところ、問題はないようです。

単純な古い Dijkstraのアルゴリズム から始めます。次の小さな変更を行います。

  • 通常のアルゴリズムは、すべての初期距離を「ソースノード」以外の無限大に設定します。代わりに、すべての初期距離を無限大に設定します。次に、「開始」サブグラフの各ノードの距離をゼロに変更します。 (私のような無向グラフの場合、どちらかのサブグラフを選択することができます。)

  • 未訪問のセットに残るノードが「終了」サブグラフのノードになるまで、アルゴリズムを通常どおり実行し続けます。距離を縮めることはできないため、この時点で停止しても安全です。 (負のエッジウェイトがある場合、これは適用されません。)

  • 「終了」サブグラフのすべてのノードを調べ、合計スコアが最も低いノードを選択します。これが終了ノードです。

  • 「開始」サブグラフのノードに到達するまで、保存された「前のノード」情報のパスをたどります。

1
Pops