web-dev-qa-db-ja.com

負の重みを持つダイクストラのアルゴリズム

負の重みでダイクストラのアルゴリズムを使用できますか?

STOP!「笑って、2つのポイント間を無限に飛び回り、無限に安いパスを取得できる」と考える前に、私は一方通行のパスを考えています。

これのアプリケーションは、その上にポイントを持つ山岳地帯です。明らかに、高から低への移行はエネルギーを消費しません。実際、エネルギーを生成します(したがって、負のパスウェイト)。しかし、チャックノリスでない限り、再び戻ることはそのようには動作しません。

すべてのポイントの重みを負ではなくなるまで増やすことを考えていましたが、それが機能するかどうかはわかりません。

34
orlp

グラフに負のサイクル(エッジの重みが負の合計を持つ有向サイクル)が含まれていない限り、任意の2点間の最短パスがありますが、ダイクストラのアルゴリズムはそれらを見つけるように設計されていません。エッジの重みが負の有向グラフで単一ソースの最短パスを見つけるための最もよく知られているアルゴリズムは、 Bellman-Fordアルゴリズム です。ただし、これにはコストがかかります。Bellman-FordにはO(| V |・| E |)時間、 Dijkstra's にはO(| E | + | V | log | V |)時間、これは、スパースグラフ(EはO(| V |))とデンスグラフ(EはO(| V | ^ 2))の両方に対して漸近的に高速です。

山岳地帯の例では( 有向グラフ 。傾斜の上下に異なる重みがあるため)、負のサイクルの可能性はありません。これは、ポイントを離れてから戻ることを意味するためです。それに正味のエネルギー利得を与えます-これは 永久運動機械 の作成に使用できます。

すべての重みを一定の値だけ増やして負ではないようにすることはできません。これを見るために、AからBへの2つのパスがあるグラフを考えてみてください。1つは長さ2の単一のエッジを、もう1つは長さ1、1、および-2のエッジを通過します。 2番目のパスは短くなりますが、すべてのエッジウェイトを2増やすと、最初のパスの長さは4になり、2番目のパスの長さは6になり、最短パスが逆になります。この方法は、2つのポイント間のすべての可能なパスが同じ数のエッジを使用する場合にのみ機能します。

58
D Coetzee

最適性の証明を読んだ場合、行われた仮定の1つは、すべての重みが負でないことです。したがって、no。 Bartが推奨するように、グラフに負のサイクルがない場合は、Bellman-Fordを使用してください。

負のEdgeは単なる負の数ではないことを理解する必要があります---これは、パスのコストのreductionを意味します。パスに負のEdgeを追加すると、パスのコストがreduceedになります---このEdgeが重みになるように重みをインクリメントすると負ではないので、その減少特性はもうないので、これは異なるグラフです。

最適性の証明を読むことをお勧めします。既存のパスにEdgeを追加しても、パスのコストが増加する(または影響しない)だけであるという仮定が重要であることがわかります。

3
Jacob

実際には、ネガティブパス環境でダイクストラのアルゴリズムを使用するアルゴリズムがあります。これは、すべてのネガティブエッジを削除し、最初にグラフのバランスを取り直すことによって行われます。このアルゴリズムは「ジョンソンのアルゴリズム」と呼ばれます。

動作方法は、グラフ内の他のすべてのノードに移動するコストが0の新しいノード(Qとする)を追加することです。次に、ポイントQからグラフでBellman-Fordを実行し、Qに関して各ノードのコストを取得します。q[x]を呼び出します。これは、0または負の数(負のパスの1つを使用するため) )。

例えば。 a-> -3-> b。したがって、これらすべてのノードにコストが0のノードQを追加すると、q [a] = 0、q [b] = -3になります。

次に、次の式を使用してエッジのバランスを再調整します:weight + q [source]-q [destination]。したがって、a-> bの新しい重みは-3 + 0-(-3)= 0です。グラフのエッジを削除してから、Qとその出力エッジを削除します。これで、ダイクストラを実行できる負のエッジのない再バランスされたグラフができました!

実行時間はO(nm) [bellman-ford] + nx O(m log n)[n Dijkstra's] + O(n ^ 2)[重量計算] = O(nm log n)時間

詳細: http://joonki-jeong.blogspot.co.uk/2013/01/johnsons-algorithm.html

負の重み付きグラフでダイクストラを使用できますが、最初に各頂点の適切なオフセットを見つける必要があります。それは基本的にジョンソンのアルゴリズムが行うことです。しかし、Johnson'sはBellman-Fordを使用してウェイトオフセットを見つけるため、これはやり過ぎです。 Johnson'sは、頂点のペア間のすべての最短パスに合わせて設計されています。

http://en.wikipedia.org/wiki/Johnson%27s_algorithm

1
Justin

実際、エッジの重みを変更することはうまくいくと思います。オフセットではなく係数を使用します。距離を測定する代わりに、ポイントAからBに必要な時間を測定すると仮定します。

重量=時間=距離/速度

傾斜に応じて速度を調整して、実際の山や車/自転車の場合は物理的な速度を使用することもできます。

0
Karussell

はい、あなたは最後に1つのステップを追加することでそれを行うことができます。

            If v ∈ Q, Then Decrease-Key(Q, v, v.d)
            Else Insert(Q, v) and S = S \ {v}.
0
sa_nyc