回答:
ダイクストラのアルゴリズムでは、頂点が「クローズ」としてマークされた(そしてオープンセットから外れた)ことを思い出してください-アルゴリズムはその最短パスを検出し、このノードを再度開発する必要はありません-これまでに作成されたパスを想定しますパスは最短です。
しかし、負の重みでは-それは本当ではないかもしれません。例えば:
A
/ \
/ \
/ \
5 2
/ \
B--(-10)-->C
V={A,B,C} ; E = {(A,C,2), (A,B,5), (B,C,-10)}
Aのダイクストラは最初にCを開発し、後で見つけられない A->B->C
もう少し深い説明を編集してください:
これは重要であることに注意してください。各緩和ステップで、アルゴリズムは「閉じた」ノードへの「コスト」が実際に最小であることを前提としているため、次に選択されるノードも最小です。
アイデアは次のとおりです。頂点に開いた頂点があり、そのコストが最小になる場合- 任意の頂点に任意の正の数を追加することにより-最小性は決して変更されません。
正の数に対する制約なし-上記の仮定は当てはまりません。
「閉じられた」各頂点は最小限に「知っている」ので、「振り返る」ことなく、安全にリラックスステップを実行できます。「振り返る」必要がある場合-Bellman-Fordは、そうすることの再帰的な(DP)ソリューションを提供します。
A->B
に5とA->C
2になります。次ににB->C
なり-5
ます。したがって、の値はベルマンフォードC
と-5
同じになります。これが正しい答えを与えていないのはなぜですか?
A
値0のノードを「閉じます」。次に、最小値のノードでB
ある5とC
2 を探します。最小値はC
なのでC
、値2で閉じ、決して後戻りしません。後でB
閉じられると、C
はすでに「閉じられている」ため、の値を変更できません。
A -> B -> C
ですか?最初にC
の距離を2に更新し、次にB
の距離を5に更新します。グラフにからの発信エッジがないと仮定すると、C
訪問時に何もしませんC
(その距離は2のままです)。次にD
、の隣接ノードにアクセスします。隣接ノードはのみC
で、新しい距離は-5です。ダイクストラ法では、我々はまた、我々が到達する親のトラック(および更新)ノード、およびからそれをやっておくことを注意C
、あなたが親を取得しますB
、その後、A
正しい結果が得られ、。何が欠けていますか?
私の説明でダイクストラのアルゴリズムを参照するときは、以下に実装されているダイクストラのアルゴリズムについて話します。
したがって、最初に各頂点に割り当てられた値(ソースから頂点までの距離)を開始すると、
最初にQ = [A、B、C]の頂点を抽出します。これは最小値、つまりAを持ち、その後Q = [B、C]になります。注AにはBとCへの有向エッジがあり、どちらもQにあるため、これらの値の両方を更新します。
次に、Cを(2 <5)として抽出し、Q = [B]にします。Cは何にも接続されていないため、line16
ループは実行されないことに注意してください。
最後にBを抽出します。注BにはCへの有向エッジがありますが、CはQに存在しないため、再びforループに入ることはありませんline16
。
したがって、距離は次のようになります。
AからCへの最短距離は5 + -10 = -5なので、これが間違っていることに注意してください。
したがって、このグラフの場合、ダイクストラのアルゴリズムはAからCまでの距離を誤って計算します。
これは、ダイクストラのアルゴリズムがすでにQから抽出された頂点への短いパスを見つけようとしないために発生します。
どのようなline16
ループがやっていることは、頂点に取っているのuをして言ってちょっと我々が行くことができるようになります」Vを介してソースからのu任意のより良い電流よりも、その(ALTまたは代替)で距離distの[V]ので、更新をすることができます場合は、私たちは?ですdist [v] "
line16
それらの中で、まだQにあるuのすべての隣接v(つまり、有向枝がuからvに存在する)をチェックすることに注意してください。であれば、彼らはQ. soから訪れたノートを削除し、xがの訪問隣人であるuは、パスがされても、考えられていないソースからの可能な短い方法として、V。line14
上記の例では、CはBの訪問済みネイバーであるため、パスは考慮されず、現在の最短パスは変更されません。
これは、エッジの重みがすべて正の数である場合に実際に役立ちます。これは、短くできないパスを考慮して時間を無駄にしないためです。
したがって、このアルゴリズムを実行するときに、xがyの前にQから抽出された場合、パスを見つけることができません。これを例で説明しましょう。
yは単に抽出され、xは、次いでそれ自体の前に抽出されたDIST [Y]> DIST [X]を、さもなければので、yは前に抽出されていたX。(line 13
最初の最小距離)
また、エッジの重みは正、つまりlength(x、y)> 0であるとすでに仮定しました。したがって、yを介した代替距離(alt)は常に大きくなります。つまり、dist [y] + length(x、y)> dist [x]です。したがって、yがxへのパスと見なされたとしても、dist [x]の値は更新されなかったため、まだQにあるyの近傍のみを考慮することは理にかなっていると結論付けます(のコメントに注意)line16
しかし、これは、正のエッジ長の仮定に依存します。length (u、v)<0の場合、そのエッジがどれだけ負であるかに応じて、での比較後にdist [x]を置き換えることができline18
ます。
したがって、xがすべての頂点v(xがそれらを接続する負のエッジを持つvの近傍であるなど)の前に削除される場合、私たちが行うdist [x]計算は正しくなくなります。
これらのv頂点はそれぞれ、ソースからxへの潜在的な「より良い」パスの最後から2番目の頂点であるため、ダイクストラのアルゴリズムによって破棄されます。
したがって、上記の例では、Bが削除される前にCが削除されたことが原因でした。そのCはBのネガティブエッジを持つ隣人でした!
明確にするために、BとCはAの隣人です。Bには単一のネイバーCがあり、Cにはネイバーがありません。length(a、b)は、頂点aとbの間のエッジの長さです。
ダイクストラのアルゴリズムの正確性:
アルゴリズムの任意のステップに2セットの頂点があります。セットAは、最短パスを計算した頂点から構成されます。セットBは残りの頂点で構成されます。
帰納的仮説:各ステップで、以前のすべての反復が正しいと仮定します。
帰納的ステップ:頂点VをセットAに追加し、距離をdist [V]に設定する場合、この距離が最適であることを証明する必要があります。これが最適でない場合は、頂点Vへのパスが他より短い必要があります。
この別のパスが頂点Xを通過するとします。
ここで、dist [V] <= dist [X]であるため、グラフに負のエッジ長がない限り、Vへのその他のパスは少なくともdist [V]の長さになります。
したがって、ダイクストラのアルゴリズムが機能するには、エッジの重みが負でない必要があります。
次のグラフでダイクストラのアルゴリズムを試して、A
何が起こっているかを確認します。
A->B
意志1
とA->C
意志100
。その後しB->D
ます2
。その後しC->D
ます-4900
。したがって、の値はベルマンフォードD
と-4900
同じになります。これが正しい答えを与えていないのはなぜですか?
A->B
はに1
なりA->C
ます100
。次にB
探索され、に設定さB->D
れ2
ます。次に、ソースに戻る最短パスがあるため、Dが探索されますか?もしそうなら、最初に探索されたのだろうと私B->D
は言っても正しいでしょうか?私はあなた以外の人々が与える他のすべての例を理解しています。100
C
これまでの他の回答は、ダイクストラのアルゴリズムがパスの負の重みを処理できない理由をかなりよく示しています。
しかし、問題自体はおそらくパスの重みの誤った理解に基づいています。パスの負の重みが一般にパスファインディングアルゴリズムで許可される場合、停止しない永続的なループが発生します。
このことを考慮:
A <- 5 -> B <- (-1) -> C <- 5 -> D
AとDの間の最適な経路は何ですか?
すべてのパスファインディングアルゴリズムは、BとCの間で継続的にループする必要があります。これを行うと、パス全体の重みが減少するためです。したがって、接続に負の重みを許可すると、各接続が1回だけ使用されるように制限する場合を除いて、任意のpathfindigアルゴリズムが無効になります。
負のサイクルを含まない負のエッジでダイクストラのアルゴリズムを使用できますが、頂点に複数回アクセスできるようにする必要があり、そのバージョンでは高速な時間の複雑さが失われます。
その場合、実際には、通常のキューを持ち、ネガティブエッジを処理できるSPFAアルゴリズムを使用する方がよいことを確認しました。