Dijkstra和动态规划
生活随笔
收集整理的這篇文章主要介紹了
Dijkstra和动态规划
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
有人說Dijkstra也是動態規劃。
它不是貪心嗎?怎么變成動態規劃了,是動態規劃的話,那么就有狀態,有狀態方程。
將圖中的頂點分成2個部分,已知最短路徑的頂點集合U,不知最短路徑的集合V-U
問題規模:就是U里面頂點個數
狀態:已知最短路徑長度:
狀態方程如下:
如果v 在 U中:cdis[v] = dis[v] 如果v和U中某點u直連:cdis[v] =min(dis(u) + w(u,v)) 其他情況:cdis[v] = inf但是這個狀態方程怎么去實現了,我們知道需要維護這個表cdis[v] ,這個就是備忘數組,遍歷的i就是U里面的頂點個數,i++就是U里面的頂點增長,U里面的頂點怎么得來了?
貪心算法來了,每次取cdis[v]里面最小的點
為了取最小的點我們引入了優先級隊列,不用優先級也可以,處理起來復雜一點,我們只把優于cdis里的結果放入優先級隊列
優先級隊列彈出的過程也就是U里面的頂點增長過程,于是i++就有了
貪心+動態規劃,應該都是這個框架,沒有直接的for循環了
代碼實現如下,仔細體會:
import heapq import numpy as npdef dijkstra(graph,start):pqueue = []heapq.heappush(pqueue,(0.0,start))#U:已知最短距離的集合visit = set()# 追蹤解parent = {start:None}# DP數組distance = {vertex:np.Inf for vertex in graph}distance[start] = 0.0while pqueue:pair = heapq.heappop(pqueue) dist = pair[0]vertex = pair[1]# 相當于以前的for循環visit.add(vertex)# 這里我們只考慮直連的邊,非直連的邊為inf肯定進不了候選集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))# 更新DP數組distance[v] = dist + graph[vertex][v]parent[v] = vertex return parent,distance #%%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 j{'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}總結
以上是生活随笔為你收集整理的Dijkstra和动态规划的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Bellman-Ford 算法 和 动态
- 下一篇: 回溯法解决01背包问题