赞
踩
关于单源、多源、权的解释,我的这篇文章有所介绍 :
本文仅讨论单源有权图,即给定起点,边带有权重的图。求单源有权图的最短路径,即求给定起点,到任意节点的最短路径。求这类图的常见算法就是Dijkstra算法。
Dijkstra算法
以下图为例:
步骤详解:
确认起点为V1,并更新dist[V1]=0。
根据结论2开始循环,每次从未收录的定点中选一个dist 最小的收录,这样顶点就是按照dist递增的顺序被收录到S中。
从dist中找出一个未收录的、最短路径的顶点:V1,并收录到S中,同时更新该顶点到其他未收录的邻接点的dist
从dist中找出一个未收录的、最短路径的顶点:V4,并收录到S中,同时更新该顶点到其他未收录的邻接点的dist
从dist中找出一个未收录的、最短路径的顶点:V2,并收录到S中,同时更新该顶点到其他未收录的邻接点的dist
从dist中找出一个未收录的、最短路径的顶点:V3,并收录到S中,同时更新该顶点到其他未收录的邻接点的dist
从dist中找出一个未收录的、最短路径的顶点:V5,并收录到S中,同时更新该顶点到其他未收录的邻接点的dist
从dist中找出一个未收录的、最短路径的顶点:V7,并收录到S中,同时更新该顶点到其他未收录的邻接点的dist
从dist中找出一个未收录的、最短路径的顶点:V6,并收录到S中,同时更新该顶点到其他未收录的邻接点的dist
最后,所有节点都已经被S收录,算法到这里就结束了。求得以V1为源点,到其他顶点V的距离为 dist [] = [0, 2, 3, 1, 3, 6, 5]
最后,我们用代码来实现一下:
- class DijkstraHeap(IVisitGraph):
- """
- dijkstra算法求最短路径
- min dist 用最小堆实现
- """
-
- INFINITY = 9999999
-
- def __init__(self):
- """
- 起点
- """
- super(DijkstraHeap, self).__init__()
- self.collected = []
- self.dist = []
- self.s = None # 起点
- self.g = None # 图
-
- def initVisted(self, g):
- super(DijkstraHeap, self).initVisted(g)
- # 初始化最短路径数组,所有顶点都是勿穷大
- self.dist = [self.INFINITY for i in range(g.nV)]
- # 初始化收录数组,所有顶点均未收录
- self.collected = [False for i in range(g.nV)]
-
- def visit(self, g, v: int):
- """
- dijkstra 算法,求图单源带权最短路
- g: 图,矩阵实现
- v: 起点
- """
- self.s = v # dijkstra算法是单源的,必须确认起点
- self.g = g # 图也是固定的
- self.dist[v] = 0 # 初始化顶点dist为0,自己到自己是0
-
- elements = [VNode(index=i, weight=weight) for i, weight in enumerate(self.dist)]
- minDistHeap = ElementMinHeap().buildHeap(elements=elements) # 建立dist最小堆
-
- while not minDistHeap.isEmpty():
-
- # 从dist中选出一个未访问的,路径最短的节点
- V = minDistHeap.deleteMin()
-
- # 加入集合中
- self.collected[V.index] = True
-
- # 更新其他邻接顶点的 dist
- for i, val in enumerate(g.G[V.index]):
- if g.G[V.index][i] == -1: # 没有边
- continue
- if self.collected[i]: # 已收录
- continue
-
- # 判断新收录顶点V是否影响其邻接节点的dist
- # dist[i] = min(dist[i], dist[V]+<V, i>权重)
- if self.dist[V.index]+g.G[V.index][i] < self.dist[i]:
- self.dist[i] = self.dist[V.index]+g.G[V.index][i]
- # 别忘了调整堆,堆是根据dist建的,dist变化了,堆也要调整
- minDistHeap.updateX(i, self.dist[i])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。