第7章——狄克特斯拉算法

算法比較

  1. 相比於第6章的廣度優先算法計算的是無權圖中的最短路徑,狄克特斯拉算法計算的是加權圖中的最短路徑

算法流程

  1. 找出最便宜的節點,即可在最短時間內前往的節點。
  2. 對於該節點的鄰居,檢查是否有前往它們的更短路徑,如果有,就更新其開銷。
  3. 重複這個過程,直到對圖中的每個節點都這樣做了。
  4. 計算最終路徑

注意事項

  1. 迪傑斯特拉適用於有向無環圖,因爲無向或者有環,在該算法中,你會發現它會不斷的循環,因爲一直有鄰居。
  2. 該算法不適用於負權邊,負權邊的意思就是邊的權重爲負值。原因在於,算法本身考慮的是當前最小的cost的節點A,跳轉到A節點進行下一步,如果計算完A節點的所有鄰居後,根據cost的表選擇另外一個節點B,從B到A權重爲負值,也就意味着,A節點在cost中的值可以被更新,但是算法已經將節點A剔除。

代碼講解

 

上圖中,左圖是我們要解決的問題,首先我們需要用的是構建三個散列表,下面詳細看代碼

#author:ErenCoder


#構建圖
graph={}
graph["start"]={}
graph["start"]['a']=6
graph['start']['b']=2
graph['a']={}
graph['a']['fin']=1
graph['b']={}
graph['b']['a']=3
graph['b']['fin']=5
graph['fin']={}

#構建cost表
infinity=float('inf')
costs={}
costs['a']=6
costs['b']=2
costs['fin']=infinity

#構建parents表
parents={}
parent['a']='start'
parent['b']='start'
parent['fin']=None

#記錄處理過的節點
processed=[]

#在未處理的節點中找出開銷最小的節點
node=find_lowest_cost_node(costs)
#這個while循環在所有節點都被處理過後結束
while node is not None:
	cost=costs[node]
	neighbors=graph[node]
	#遍歷當前節點的所有鄰居
	for n in neighbors.keys():
		#更新節點n的cost值
		new_cost=cost+neighbors[n]
		#如果經當前節點前往該鄰居更近,就更新該鄰居的開銷
		if costs[n]>new_cost:
			costs[n]=new_cost
			#同時將該鄰居的父節點設置爲當前節點
			parents[n]=node
	#將當前節點標記爲處理過
	processed.append(node)
	找出接下來要處理的節點,並循環
	node=find_lowest_cost_node(costs)
def find_lowest_cost_node(costs):
	lowest_cost=float('inf')
	lowest_cost_node=None
	#遍歷所有的節點
	for node in costs:
		cost=costs[node]
		#如果當前節點的開銷更低且未處理過
		if cost<lowest_cost and node not in processed:
			lowest_cost=cost
			lowest_cost_node=node
	return lowest_cost_node

大家如果有不理解的歡迎隨時交流,freestyle

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章