根據演算法導論上的說明:該演算法可以說很簡單,對每個節點維護兩個資訊,乙個是源節點到該節點的距離,另乙個是到該節點的前乙個節點。也即前驅。假設當前用距離表a來儲存所有點的這兩個資訊。假設有n個節點
演算法分為三步步走。
第一步初始化a,a中所有距離均為無窮大,且前驅為空
第二步,計算距離。對圖中的每條邊(u,v,w)都進行relax操作。其意義是,測試是否可以對從源節點s到v的最短路徑進行改善。方法是:利用a中維護從源節點到任意節點v的距離,若從節點u到v的距離比a中的小,則更新a中的距離為這個更小的值,且a中v節點的前驅也更新為u。這裡在更新a中的節點v時,邊(u,v)應該是節點v的一條弧(無向圖中為以v為一端短點的邊,有向圖中則為以v為尾 的弧)。
第三步,檢查是否存在權值為負的邊,若存在,則不存在解決方案。
最後根據a中的資訊構建路徑。
最後自己硬著頭皮寫了一上午,調各種錯誤,之後調出正確結果之後才算有了一些自己的理解。
這個演算法可以說
採用的思想是遍歷比較。
對圖中的每乙個節點進行如下操作:
遍歷與該節點u相鄰的每一條邊(u,v),若從源點經由u到v比從源點到v的距離短,則用這個短的距離來更新距離值,並且設定節點v的前驅為節點u。
當對所有的節點都進行了如上述所說的操作之後,最後得到的距離表和前驅表即可構建路徑和距離資訊。
下面是我用python寫的乙個**示例,寫的很粗糙。
import numpy as np
dist=np.array([[0,1,1,0.5,0,0],[1,0,0,1,1,0],[1,0,0,1,1,1],[0.5,1,1,0,1,0],[0,1,1,1,0,1],[0,0,1,0,1,0]])
def bf(adjacent_array,source):
weight = adjacent_array
node_num = len(adjacent_array[0])
path = list(range(node_num))
distance = [float("inf") for i in range(node_num)]
distance[source-1] = 0
i = 0
while i < node_num:
j = i
while j < node_num:
if weight[i][j]:
if distance[i]+weight[i][j]distance[j] = distance[i]+weight[i][j]
path[j] = i
j += 1
i += 1
i = 0
while i < node_num:
path_to = [i+1]
j = i
while j != source-1:
path_to.insert(0,path[j]+1)
j = path[j]
print("the path to %d is:"%(i+1))
print(path_to)
i += 1
print(distance)
bf(dist,1)
<< 執行結果如下
the path to 1 is:
[1]the path to 2 is:
[1, 2]
the path to 3 is:
[1, 3]
the path to 4 is:
[1, 4]
the path to 5 is:
[1, 4, 5]
the path to 6 is:
[1, 3, 6]
[0, 1.0, 1.0, 0.5, 1.5, 2.0]
最短路徑(Bellman Ford演算法)
主要思想 遍歷m條邊,看是否能讓從給定點直接到v點縮短為從給定點到u點再到v點。因為任意兩點之間的最短路徑最多包含n 1條邊,所以把這些邊遍歷n 1次就好。include intmain if check 0 如果有一次遍歷中沒有對任何頂點進行鬆弛,則表明所有點都為最短路徑了 break flag ...
bellman ford最短路徑演算法
1.1 這個演算法適用於圖中有負權值的邊的最短路徑的計算 2.2 這個演算法可以用來判斷圖中是否有總權值為負的環存在 2.1演算法是對圖中的邊集進行操作的,這和dijkstra演算法不同 2.2演算法是從源節點來進行廣度搜尋並完成最短路徑的建立的 2.3演算法需要執行 v 1次的大迴圈,以此來確保找...
Bellman Ford最短路徑演算法
bellman ford最短路徑演算法 單源最短路徑 給定乙個圖,和乙個源頂點src,找到從src到其它所有所有頂點的最短路徑,圖中可能含有負權值的邊。dijksra的演算法是乙個貪婪演算法,時間複雜度是o vlo 使用最小堆 但是迪傑斯特拉演算法在有負權值邊的圖中不適用,bellman ford適...