Bellman Ford演算法和SPFA演算法

2021-10-06 21:58:17 字數 1537 閱讀 3450

演算法介紹

dijkstra可以解決單源無負邊最短路徑問題。但是當遇到含有負邊的單源最短路徑問題就需要使用bellman-ford演算法來解決。bellman-ford演算法還可以檢測出負環。

演算法步驟

我們可以看到bellman-ford演算法的演算法結構是比較簡單的,複雜度是o(v

e)

o(ve)

o(ve

),比dijkstra演算法最好為o(e

+vlo

gv

)o(e+vlo**)

o(e+vl

o**)

大,但是可以處理負邊。

正確性證明

可以看到演算法的核心操作就是鬆弛。這就要用到另一篇部落格中介紹dijkstra演算法的時候的幾個關於鬆弛操作的引理,這裡就不再進行證明,如果想要看證明可以移步:傳送門。

設源點為s,d[u]表示源點到u的最短路徑,w[u,v]表示從點u到點v的一條有向邊的長度,δ(u

,v

)\delta(u,v)

δ(u,v)

表示u到v的最短路徑。

最優子結構:任意兩點之間的最短路徑的子路徑仍然是最短路徑

引理1:初始化以後∀v∈

v,d[

u]⩾δ

(s,v

)\forall v \in v,d[u]\geqslant\delta(s,v)

∀v∈v,d

[u]⩾

δ(s,

v)引理2:假設存在s到v的最短路徑:s->…->u->v,d[u

]=δ(

s,u)

d[u]=\delta(s,u)

d[u]=δ

(s,u

),那麼在對邊(u,v)進行鬆弛操作以後d[v

]=δ(

s,v)

d[v]=\delta(s,v)

d[v]=δ

(s,v

) 假設沒有負邊環,那麼:

因為如果d[s

]<

0d[s]<0

d[s]

<

0說明存在乙個環s->…->s的權值和為負,而假設沒有負邊環,所以不存在這樣的情況

如果第|v|次迴圈可以進行鬆弛操作,則由逆反命題,說明有負邊環。

證畢。演算法介紹

spfa演算法是對bellman-ford演算法的優化。因為bellman-ford演算法中會對已經確定最短路徑的點進行鬆弛判斷,但這實際上是不必要的。我們需要鬆弛的是被鬆弛的點可以到達的點。正是這種思想我們有了spfa演算法。

演算法步驟

正確性證明

同bellman-ford演算法,可以用歸納法進行證明。本質上spfa演算法提取出了bellman-ford演算法中有效的操作。

複雜度分析

可以構造圖使得演算法複雜度為o(v

e)

o(ve)

o(ve

),因此演算法的最壞複雜度為o(v

e)

o(ve)

o(ve

)。雖然spfa演算法是bellman-ford演算法的優化,但是對於一些特殊的圖可能因為有判斷操作和出隊入隊操作導致兩者複雜度相近。

Bellman Ford演算法 和 SPFA演算法

bellman ford演算法是求含負權圖 的單源最短路徑演算法,效率很低,但 很容易寫。即進行不停地鬆弛 relaxation 每次鬆弛把每條邊都更新一下,若n 1次鬆弛後還能更新,則說明圖中有負環 即負權迴路,本文最後有解釋 無法得出結果,否則就成功完成。bellman ford演算法有乙個小優...

Bellman Ford演算法和SPFA演算法

最短路徑是圖論中乙個很經典的問題 給定圖g v,e 求一條從起點到終點的路徑,使得這條路徑上經過的所有邊的邊權之和最小。對任意給出的圖g v,e 和起點s 終點t,如何求從s到t的最短路徑。解決最短路徑問題的常用演算法有dijkstra演算法 bellman ford演算法 spea演算法和floy...

Bellman Ford演算法和Dijkstra演算法

bellman ford演算法是通過relax邊來實現的,由於最短無負權迴路的路徑應該最多有v 1條邊,所以一共執行v 1次relax操作即可,而且注意,每次relax操作都只是基於上一次relax操作之後的圖,和這次relax中已經relax了的節點毫無關係 這個是重點!檢查負權迴路原理 若有負權...