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 np

def 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.0
   
    while 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 i
    print 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算法
    原文地址: https://blog.csdn.net/weixin_40759186/article/details/84325509
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞