Dijkstra的理解和实现
生活随笔
收集整理的這篇文章主要介紹了
Dijkstra的理解和实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Dijkstra理解:
1、單點按照距離遞增輻射出去; 2、輻射到的點會被放進優先級隊列,距離遠的點可能會先放到隊列里; 3、距離近的,可能會后放進隊列,但是肯定會先出去; 4、每一個放進優先級隊列的點,需要記錄:自己,自己的前繼節點,自己到起點的距離,會被用到的。容易的誤解不是簡單的每次走最近的點,是逐步(按照已確定的點不斷傳染輻射方式,保證最近的點一定在候選區)添加點到候選區,選出距離起點最近的點,再次輻射
優化:
把鄰居放進候選區,沒必要把全部鄰居都放進去,需要有2個條件:
1、鄰居不在已確定最近的點集合里面,也就是不在visited里面; 2、鄰居通過當前點到起點距離要小于之前記錄的距離,也就是這個鄰居前一次進入備選區時的距離,要不然進去了,也會被自己比下去;代碼實現
import heapq import numpy as npdef dijkstra(graph,start):pqueue = []heapq.heappush(pqueue,(0.0,start))visit = set()parent = {start:None}distance = {vertex:np.Inf for vertex in graph}distance[start] = 0.0while pqueue:pair = heapq.heappop(pqueue) dist = pair[0]vertex = pair[1]visit.add(vertex)edges = graph[vertex]for v in edges:if v not in visit:if dist + graph[vertex][v] < distance[v]:heapq.heappush(pqueue,(dist + graph[vertex][v],v))distance[v] = dist + graph[vertex][v]parent[v] = vertex return parent,distance另外一種代碼實現,這里的循環條件while count < vnum and,非常體現功力:
def dijkstra2(graph,start):vnum = len(graph)pqueue = []heapq.heappush(pqueue,(0.0,None,start))paths = {vertex : None for vertex in graph}count = 0while count < vnum and pqueue:pair = heapq.heappop(pqueue)distance = pair[0]parent = pair[1]vertex = pair[2]if paths[vertex]:continuepaths[vertex] = (parent,distance)edges = graph[vertex]for v in edges:if paths[v] is None:heapq.heappush(pqueue,(distance + graph[vertex][v],vertex,v))count += 1return paths運行結果:
#%%g = {'A':{'B':1,'C':2},'B':{'A':1,'C':3,'D':4},'C':{'A':2,'B':3,'D':5,'E':6},'D':{'B':4,'C':5,'E':7,'F':8},'E':{'C':6,'D':7,'G':9},'F':{'D':8},'G':{'E':9}}i,j=dijkstra(g,'A')print iprint jt=dijkstra2(g,'A')print t{'A': None, 'C': 'A', 'B': 'A', 'E': 'C', 'D': 'B', 'G': 'E', 'F': 'D'} {'A': 0.0, 'C': 2.0, 'B': 1.0, 'E': 8.0, 'D': 5.0, 'G': 17.0, 'F': 13.0} {'A': (None, 0.0), 'C': ('A', 2.0), 'B': ('A', 1.0), 'E': ('C', 8.0), 'D': ('B', 5.0), 'G': ('E', 17.0), 'F': ('D', 13.0)}總結
以上是生活随笔為你收集整理的Dijkstra的理解和实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在AWS搭建服务器控制服务器
- 下一篇: Prim和Dijkstra居然写起来一模