日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Bellman-Ford算法和SPFA算法

發布時間:2023/11/30 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Bellman-Ford算法和SPFA算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Belloman-Ford算法

算法介紹

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

算法步驟

  • 源點s,數組d[u]d[u]d[u]表示s到u的最短距離
  • 初始化:d[s]=0d[s]=0d[s]=0,?v∈V?{s},d[v]=∞\forall v \in V-\{s\},d[v]=\infin?vV?{s},d[v]=
  • 循環∣V∣?1|V|-1V?1次,每次對每條邊進行松弛操作:對于有向邊(u,v)(u,v)(u,v),如果d[u]+w[u,v]<d[v]d[u]+w[u,v]<d[v]d[u]+w[u,v]<d[v],則d[v]=d[u]+w[u,v]d[v]=d[u]+w[u,v]d[v]=d[u]+w[u,v]
  • 對每條邊進行松弛操作,如果操作成功,說明有負環。否則最后的d[i]d[i]d[i]就是源點s到i的最短路徑長度

我們可以看到Bellman-Ford算法的算法結構是比較簡單的,復雜度是O(VE)O(VE)O(VE),比Dijkstra算法最好為O(E+VlogV)O(E+VlogV)O(E+VlogV)大,但是可以處理負邊。

正確性證明

可以看到算法的核心操作就是松弛。這就要用到另一篇博客中介紹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)?vV,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]=0=δ(s,s)d[s]=0=\delta(s,s)d[s]=0=δ(s,s)

因為如果d[s]<0d[s]<0d[s]<0說明存在一個環s->…->s的權值和為負,而假設沒有負邊環,所以不存在這樣的情況

  • 假設對于最短路徑經過邊數為k的點u在第k次循環d[u]=δ(s,u)d[u]=\delta(s,u)d[u]=δ(s,u),那么由引理2,所有最短路徑經過邊數為k+1的點v在第k+1次循環后,d[v]=δ(s,v)d[v]=\delta(s,v)d[v]=δ(s,v)
  • 因為一個節點數目為∣V∣|V|V的圖的簡單路徑最長為∣V∣?1|V|-1V?1,所以∣V∣?1|V|-1V?1次循環以后?v∈V,d[v]=δ(s,v)\forall v \in V,d[v]=\delta(s,v)?vV,d[v]=δ(s,v)
  • 第|V|次循環應該無法進行松弛操作。

如果第|V|次循環可以進行松弛操作,則由逆反命題,說明有負邊環。

證畢。

SPFA算法

算法介紹

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

算法步驟

  • 源點s,數組d[u]d[u]d[u]表示s到u的最短距離,隊列Q表示需要操作進行松弛操作的點的集合
  • 初始化:d[s]=0,?v∈V?{s},d[v]=∞d[s]=0,\forall v \in V-\{s\},d[v]=\infind[s]=0,?vV?{s},d[v]=,將點s加入Q中
  • 從Q中取出一個點,對它可以到達的點進行松弛操作,并將成功進行松弛操作的點加入Q中
  • 重復上述步驟直到Q為空
  • 如果某個點被松弛了|V|次,說明有負邊環

正確性證明

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

復雜度分析

可以構造圖使得算法復雜度為O(VE)O(VE)O(VE),因此算法的最壞復雜度為O(VE)O(VE)O(VE)。雖然SPFA算法是Bellman-Ford算法的優化,但是對于一些特殊的圖可能因為有判斷操作和出隊入隊操作導致兩者復雜度相近。

總結

以上是生活随笔為你收集整理的Bellman-Ford算法和SPFA算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。