dijkstra算法

导入sys模块

import sys
class Graph():
def init(self):
self.vertices = {} #vertice顶点
self.edges = []
def addEdge(self, start, end, dist, biDirectFlag=True): #biDirectFlag双向边
if biDirectFlag: # 双向边````
self.edges.extend([[start, end, dist], [end, start, dist]])
else:
self.edges.append([start, end, dist])

# 输出节点合集
def getVertices(self):
    return set(sum(([edge[0], edge[1]] for edge in self.edges), []))

# 输出v节点的最短路径
def getPath(self, predecessor, v):#predecessor前身
    pred = predecessor[v]
    path = []
    path.append(v)
    while (pred != None):
        path.append(pred)
        pred = predecessor[pred]
    return(path)
#返回vertice节点的相邻节点集

def getNeighbours (self,vertice):
    neighbours = []
    for edge in self.edges:
        if edge[0] == vertice:
            neighbours.append([edge[1], edge[2]])  # 节点,距离
    return (neighbours)

# 输出tempVertices中距离值最小的非固定节点
def getCurrentV(self, tempVertices, dist):
    if len(tempVertices) == 0: return None
    return (min(tempVertices, key=lambda v: dist[v]))

# 输出图中是否有权重为负的边,没有返回False
def checkForNegativeWeights(self):
    for edge in self.edges:
        if edge[2] < 0:return True
    return False

# 最短路径算法,输出从src起始的,到所有节点的最短路线
def dijkstra(self, src):
    if (self.checkForNegativeWeights()):
        print("权重不能为负")
        return
    self.src = src  # 来源节点
    self.vertices = self.getVertices()  # 节点集合
    dist = {v: sys.maxsize for v in self.vertices}  # 初始距离值为最大数
    dist[src] = 0
    predecessor = {v: None for v in self.vertices} # 初始前任节点为None
    tempVertices = self.vertices.copy() # 未固定节点集合,初始为所有节点
    currentV = src
    while len(tempVertices) > 0: # 循环至所有节点都被固定
        neighbours = self.getNeighbours(currentV)
        for n in neighbours: # 松弛
            if n[0] in tempVertices and dist[currentV] + n[1] < dist[n[0]]:
                dist[n[0]] = dist[currentV] + n[1]
                predecessor[n[0]] = currentV
        tempVertices.remove(currentV)# 固定当前节点
        currentV = self.getCurrentV(tempVertices, dist) # 更新当前节点
    self.printSolution(dist, predecessor)# 输出结果以上为算法代码,以下为实现例图:

# 输出所有节点的最短路径和路径距离
def printSolution(self, dist, predecessor):#predecessor前身
    for v in self.vertices:
        path = self.getPath(predecessor, v)
        print(self.src, "to ", v, " - Distance: ", dist[v], " Path :", path)

graph = Graph()# 创建对象
graph.addEdge("a", "b", 2, False) # 单向边
graph.addEdge("a", "c", 1, True) # 双向边
graph.addEdge("b", "d", 3, False)
graph.addEdge("d", "f", 1, True)
graph.addEdge("f", "e", 2, False)
graph.addEdge("c", "e", 4, False)
graph.addEdge("b", "c", 2, False)
graph.addEdge("e", "b", 4, False)
graph.addEdge("d", "e", 1, False)
graph.addEdge("c", "d", 2, False)
graph.dijkstra("a")# 来源节点是a

posted on 2023-05-21 23:26  上山打老虎下山采蘑菇  阅读(8)  评论(1编辑  收藏  举报

导航