天天看点

dijkstra算法_最短路径问题—Dijkstra算法+堆优化

宇智波一打七今天学习了一个新算法,迫不及待和大家分享一下 。假装是自己敲的

dijkstra算法_最短路径问题—Dijkstra算法+堆优化

(直接从一打七的博客截图过来,溜)

dijkstra算法_最短路径问题—Dijkstra算法+堆优化

优美的代码来了

import heapqclass graph:    def __init__(self,num,ma):        self.edge={}        self.dic=[ma]*(num+1)    def add(self,u,v,w):        if u in self.edge:            self.edge[u].append((v,w))        else:            self.edge[u]=[(v,w)]    def dijkstra(self,start):        dis=self.dic        dis[start]=0        heap=[]        visit=[0 for i in range(len(dis))]        for i in self.edge[start]:            dis[i[0]]=i[1]            heapq.heappush(heap,(i[1],i[0]))# i[1]为该边权值,i[0]为该点,从start点到其余点的边入堆        while heap!=[]:            vic=heapq.heappop(heap)# 弹出最小边            if visit[vic[1]]==1:# 如果该点已经弹出过,则不再松弛                continue            visit[vic[1]] = 1# 记录弹出点            if vic[1] not in self.edge:# 防止有向图中出度为0的点                continue            for i in self.edge[vic[1]]:                if dis[i[0]]>dis[vic[1]]+i[1]:# 判断是否松弛                    dis[i[0]]=dis[vic[1]]+i[1]# 松弛边                    heapq.heappush(heap,(i[1],i[0]))# 松弛过边则把新边权值入堆        self.dic=dis    def printf(self):        print(self.dic[1:])if __name__ == "__main__":    n,m=6,8    nums = [[1,3,10],[1,5,30],[1,6,100],[2,3,5],[3,4,50],[4,6,10],[5,6,60],[5,4,20]]    g=graph(n,1000000000000)    for i in nums:        g.add(i[0],i[1],i[2])    g.dijkstra(1)    g.printf()
           

我们在算法第二步求最小的点时可用堆做优化。在python中有模块heapq,这里我们直接使用该模块的最小堆即可。

注意:dijkstra算法不能求解有负权边的图(思考一下为什么?)。

才不告诉你一打七是为了练习python的面向对象。

继续阅读