7、迪杰斯特拉算法
迪杰斯特拉算法
1、狄克斯特拉算法
步骤:
(1) 找出最便宜的节点,即可在最短时间内前往的节点。
(2) 对于该节点的邻居,检查是否有前往它们的更短路径,如果有,就更新其开销。
(3) 重复这个过程,直到对图中的每个节点都这样做了。
(4) 计算最终路径。
要计算非加权图中的最短路径,可使用广度优先搜索。要计算加权图中的最短路径,可使用狄克斯特拉算法。
狄克斯特拉算法只适用于有向无环图( directed acyclicgraph, DAG)。 如果有负权边,就不能使用狄克斯特拉算法。因为负权边会导致这种算法不管用。
2、代码示例
from prettytable import PrettyTable # 模拟地杰斯特拉求解最短路径 def seachShortestPath(G,startPoint,inf): # 初始距离表,都先置为无穷大 distanceGraph = dict((i,inf) for i in G.keys()) # 起点 currentPoint = startPoint distanceGraph[startPoint] = 0 # 记录访问的点 visitedPoint = [] # 记录每次遍历后的当前最短路径 currentPathTable = dict((i,[]) for i in G.keys()) # 起点指向自己 currentPathTable[currentPoint] = str(currentPoint) while len(visitedPoint) < len(G): visitedPoint.append(currentPoint) # 遍历当前点的所有邻近点(默认遍历keys) for item in G[currentPoint]: # 如果当前点到邻近点的距离小于初始距离表的距离,更新此距离到初始距离表中 if distanceGraph[currentPoint] + G[currentPoint][item] < distanceGraph[item]: distanceGraph[item] = distanceGraph[currentPoint] + G[currentPoint][item] # 连接路径 currentPathTable[item] = "-".join((str(currentPathTable[currentPoint]),str(item))) tempDistance = inf # 求经过一次计算后,当前距离表的最短路径,并选取当前最短路径的点下次为起始点 for item in distanceGraph.keys(): # 已访问的点直接continue if item in visitedPoint:continue if distanceGraph[item] < tempDistance: tempDistance = distanceGraph[item] currentPoint = item return distanceGraph,currentPathTable if __name__ == '__main__': G = { 1:{1:0,2:1,3:12}, 2: {2: 0, 3: 9, 4: 3}, 3: {3: 0, 5: 5}, 4: {3: 4, 4: 0, 5: 13, 6: 15}, 5: {5: 0, 6: 4}, 6: {6: 0} } Infinity = float("inf") distanceGraph,currentPathGraph = seachShortestPath(G,1,Infinity) table = PrettyTable() print("\033[34;1m模拟地杰斯特拉算法求单源最短路径\033[0m") # table.= ["\033[34;1m模拟地杰斯特拉算法求单源最短路径\033[0m"] table.field_names = ["\033[1m顶点","路径","长度\033[0m"] for point,path,distance in zip(list(currentPathGraph.keys()),list(currentPathGraph.values()),list(distanceGraph.values())): table.add_row([point,path,distance]) print(table)
3、小结
广度优先搜索用于在非加权图中查找最短路径。
狄克斯特拉算法用于在加权图中查找最短路径。
仅当权重为正时狄克斯特拉算法才管用。
如果图中包含负权边,可采用Floyd算法。
4、应用场景
求单源最短距离

浙公网安备 33010602011771号