標籤:擷取 ide class play des cos closed one heap
本章內容:
- 加權圖-提高或者降低某些邊的權重
- 狄克斯特拉演算法,能找出加權圖中前往x的最短路徑
- 圖中的環,它導致狄克斯特拉算不管用
7.1狄克斯特拉演算法
4個步驟:
- 找出最便宜的節點,即最短時間內前往的節點
- 對於該節點的鄰居,檢查是否有前往他們的最短路徑,如果有,就更新其開銷
- 重複這個過程,知道對圖中的每個節點都這樣做了
- 計算最終路徑
7.3負邊權
狄克斯特拉演算法不支援包含負邊權的圖,因為,狄克斯特拉演算法這樣假設:對於處理過的海報節點,沒有前往該節點的更短的路徑。包含負邊權的圖,可使用貝爾曼-福德演算法(bellman-Ford algorithm)。
7.4實現
1 # the graph 2 graph = {} 3 graph["start"] = {} 4 graph["start"]["a"] = 6 5 graph["start"]["b"] = 2 6 7 graph["a"] = {} 8 graph["a"]["fin"] = 1 9 10 graph["b"] = {}11 graph["b"]["a"] = 312 graph["b"]["fin"] = 513 14 graph["fin"] = {}15 16 # the costs table17 infinity = float("inf")18 costs = {}19 costs["a"] = 620 costs["b"] = 221 costs["fin"] = infinity22 23 # the parents table24 parents = {}25 parents["a"] = "start"26 parents["b"] = "start"27 parents["fin"] = None28 29 processed = []30 31 def find_lowest_cost_node(costs):32 lowest_cost = float("inf")33 lowest_cost_node = None34 # Go through each node.35 for node in costs:36 cost = costs[node]37 # If it‘s the lowest cost so far and hasn‘t been processed yet...38 if cost < lowest_cost and node not in processed:39 # ... set it as the new lowest-cost node.40 lowest_cost = cost41 lowest_cost_node = node42 return lowest_cost_node43 44 # Find the lowest-cost node that you haven‘t processed yet.45 node = find_lowest_cost_node(costs)46 # If you‘ve processed all the nodes, this while loop is done.47 while node is not None:48 cost = costs[node]49 # Go through all the neighbors of this node.50 neighbors = graph[node]51 for n in neighbors.keys():52 new_cost = cost + neighbors[n]53 # If it‘s cheaper to get to this neighbor by going through this node...54 if costs[n] > new_cost:55 # ... update the cost for this node.56 costs[n] = new_cost57 # This node becomes the new parent for this neighbor.58 parents[n] = node59 # Mark the node as processed.60 processed.append(node)61 # Find the next node to process, and loop.62 node = find_lowest_cost_node(costs)63 64 print "Cost from the start to each node:"65 print costsdijkstras_algorithm.py
字典graph描述了一個圖,如下所示:
costs描述了每個節點的開銷;
parents描述了一個父節點散列表。
演算法邏輯簡述如下:
- 尋找開銷最低的節點,擷取該節點開銷和鄰居,即以此節點為起始點的權值和路徑,這裡是B節點。
- 計算通過B節點到達其鄰居的開銷,並與從起點到達B鄰居的開銷對比。到達A節點新開銷較小,更新到達A節點的散列表開銷值,並把A的父節點改為B;比較B節點到終點的路徑2+5<無窮大,故將終點的路徑由無窮大改為7,父節點改為B。
- 將B節點標記為處理過。
- 重複步驟1,尋找出開銷最低的節點即A;此時A的開銷是5,終點的開銷是7。
- 重複步驟2,A只有一個鄰居節點即終點,對比通過A到達終點的開銷和已有的資料(7),更新到達終點的開銷為6,並更新終點的父節點為A。
- 所有的節點都尋找過後,演算法結束。通過父節點散列表可以得到最優路徑;通過開銷散列表可得到最少到達終點的開銷。
7.6小結
- 廣度優先搜尋用於非加權圖中從尋找最短路徑
- 狄克斯特拉演算法用於加權圖中尋找最短路徑
- 僅當權重為正時,狄克斯特拉演算法才管用
- 如果圖中包含負權邊,請使用貝爾曼-福德演算法
演算法圖解-狄克斯特拉演算法