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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

最短路径算法----Floyd-warshall(十字交叉算法证明)

發布時間:2023/12/18 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最短路径算法----Floyd-warshall(十字交叉算法证明) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Floyd不同于Dijkstra,可以得到所有點對的最短路徑。使用的是DP

Floyd可以處理有負權重邊的情況

遞推公式:w(i, j) = min{w(i, j), w(i, k) + w(k, j)},含義是i到j的最短距離】=【i到k的最短距離+k到j的最短距離】與【i到j的最短距離】中較小的那一個

看起來很簡單,但是具體怎么計算呢?


依舊使用這個例子,圖的表示方式為:

[[0, 7, 9, max, max, 14],[7, 0, 10, 15, max, max],[9, 10, 0, 11, max, 2],[max, 15, 11, 0, 6, max],[max, max, max, 6, 0, 9],[14,max, 2, max, 9, 0]] 可以看出,w(i, i) = 0。這就是突破口了。

當k=0時,w(0, j)=min{w(0,0)+w(0,j), w(0,j)};w(i,0)=min{w(i,0)+w(0,0), w(i,0)},是不用更新的。當然,k不為0的時候,需要更新w(0,j)和w(i,0)

類似的,可以得到w(k,j)和w(i,k)不用更新。也就是說,和k相同行、列不用更新

用圖做個例子:求圖中藍色的值w(4,2)


w(4,2) = min{w(4,2) + 紅色兩個格子的和+綠色兩個格子的和+紫色兩個格子的和+薄荷色兩個格子的和}

1. 可以看出k=2和k=4的時候,更新時沒有意義的。

2. 可以看出,計算過程其實就是畫一個(k,k)-(4,2)的方框,比較w(4,2)和方框的另外兩個頂點w(4,k)+w(k,2)的大小。當然,這個時候w(4,k)和w(k,2)應該也是最優的解。

所以明顯不能以i,j,k的loop順序遍歷。


那么試一下以k,i,j的loop順序遍歷呢?

這里有個很取巧的點:

1. 當k=0的時候,第一行、第一列已經是k=0的最優解了(還記得前面的結論嗎)

2. 當k=0的時候,其他的行、列只用取第一行、第一列的數據

也就是說,當k=0的時候,遍歷完整張圖,能得到k=0的情況下dp算法的最優解:當且僅當中間節點編號<=0的時候,點i到點j的最近值

繼續證明k=x的情況下最優解已經得到,k=x+1時繼續遍歷,能否得到k=x+1的最優解?

1. k=x+1的時候,第x+1行、第x+1列已經是k<=x+1的最優解了(k=x+1時,不用更新第x行、第x列)

2. k=x+1的時候,其他的行、列只會讀取第x+1行、第x+1列的數據

因此當k=x+1時,遍歷完整張圖,能得到k=x+1的情況下dp算法的最優解

證明完畢


以上的證明過程也就是“十字交叉算法”的原理了。

感興趣的同學可以網上搜一下,瞬間即懂

def floyd(graph):# graph:n*n matrix# find min distance from start_node to end_nodelength = len(graph)for k in xrange(0, length):for i in xrange(0, length):for j in xrange(0, length):graph[i][j] = min(graph[i][k] + graph[k][j], graph[i][j])return graph

時間復雜度O(n^3)

驅動

graph = [[0, 7, 9, max_int, max_int, 14],[7, 0, 10, 15, max_int, max_int],[9, 10, 0, 11, max_int, 2],[max_int, 15, 11, 0, 6, max_int],[max_int, max_int, max_int, 6, 0, 9],[14, max_int, 2, max_int, 9, 0]] print floyd(graph)

附錄:

打印出最短路徑

def floyd(graph):# graph:n*n matrix# find min distance from start_node to end_nodelength = len(graph)pre_node = [[-1 for i in xrange(0, length)] for j in xrange(0, length)]for k in xrange(0, length):for i in xrange(0, length):for j in xrange(0, length):dist = graph[i][k] + graph[k][j]if dist < graph[i][j]:graph[i][j] = distpre_node[i][j] = kprint "pre_node", pre_nodereturn graph


總結

以上是生活随笔為你收集整理的最短路径算法----Floyd-warshall(十字交叉算法证明)的全部內容,希望文章能夠幫你解決所遇到的問題。

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