Prim和Dijkstra居然写起来一模一样
一句話概括Prim和Dijkstra:
Dijkstra:依次找距離起點從近到遠的點;
Prim:從起點開始找距離最近的點,且不形成環。
這樣表述還看不出來什么
我們先對比二者的代碼:
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 #%% def prim(graph,start): vnum = len(graph)pqueue = []heapq.heappush(pqueue,(0.0,None,start))mst = {vertex : None for vertex in graph}count = 0 while count < vnum and pqueue:pair = heapq.heappop(pqueue)dist = pair[0]parent = pair[1]vertex = pair[2]if mst[vertex]:continuemst[vertex]=(parent,dist)edges = graph[vertex]for v in edges:if mst[v] is None:heapq.heappush(pqueue,(graph[vertex][v],vertex,v))count += 1return mstAMAZING,看到了沒有,簡直一模一樣!!!!!
只不過壓堆時,一個壓的是邊的距離,一個壓的是到起點的距離。
所以我們還要繼續思考:Prim和Dijkstra
從起點VertexstartVertex_{start}Vertexstart?,到距離這個點最遠的點VertexendVertex_{end}Vertexend?, 之間的路徑我們暫且叫PATHPATHPATH。
Dijkstra實際上是在找這個PATHPATHPATH的最小值,不止最遠的點找了,其他點也都找了;
Prim一直再找最近的點,也就是邊最短的點,直到找了n-1條邊,實際上是在約束條件下(不成環)找走過邊和最短的PATHPATHPATH,實際上最短PATHPATHPATH也是不可能有環的,加入有環肯定是繞路了(從這里可以看得出算法的基礎是數學,好的算法和數學關系很大);
Dijkstra實際上是在找最遠點PATHPATHPATH的最小值,等價于,從起始點,約束條件下不斷加最短邊,直到加n-1條邊。
也就是他們在解決同一個問題。
但是這個還是沒有反映出他們的代碼為何一模一樣,簡直是兄弟?
1、圖類問題的遍歷都是借助于鄰居輻射,一傳十,十傳百,根本就不怕擴算亂了,因為已經做了標記處理了,所以框架都差不多;
2、都是基于貪心的處理,用了堆數據結構,基于的標準不一樣(這個不一樣成了他們的唯一不一樣了);
3、為了記錄路徑,都用到(parent,node, weight),這也是路徑的一般處理方式;
4、他們算法都太簡單了(懂了的情況下),沒幾行,所以就沒啥差異了啊。
總結
以上是生活随笔為你收集整理的Prim和Dijkstra居然写起来一模一样的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dijkstra的理解和实现
- 下一篇: Kruskal实现最小生成树