Dijkstra算法Python实现

 指定某两点之间求最短路

class Dijkstra:
    def __init__(self, graph, start, goal):
        self.graph = graph      # 邻接表
        self.start = start      # 起点
        self.goal = goal        # 终点

        self.temporary = {}     # temporary 节点集合
        self.permanent = {}   # permanent 节点集合

        self.temporary[start] = 0.0     # 将起点放入 temporary 中

        self.parent = {start: None}     # 存储节点的父子关系。键为子节点,值为父节点。方便做最后路径的回溯
        self.min_dis = None             # 最短路径的长度

    def shortest_path(self):

        while True:
            if self.temporary is None:
                print('搜索失败, 结束!')
                break
            distance, min_node = min(zip(self.temporary.values(), self.temporary.keys()))      # 取出距离最小的节点
            self.temporary.pop(min_node)                                                       # 将其从 temporary 中去除

            self.permanent[min_node] = distance                  # 将节点加入 permanent 中

            if min_node == self.goal:                              # 如果节点为终点
                self.min_dis = distance
                shortest_path = [self.goal]                        # 记录从终点回溯的路径
                father_node = self.parent[self.goal]
                while father_node != self.start:
                    shortest_path.append(father_node)
                    father_node = self.parent[father_node]
                shortest_path.append(self.start)
                print(shortest_path[::-1])                         # 逆序
                print('最短路径的长度为:{}'.format(self.min_dis))
                print('找到最短路径, 结束!')
                return shortest_path[::-1], self.min_dis			# 返回最短路径和最短路径长度

            for node in self.graph[min_node].keys():               # 遍历当前节点的邻接节点
                if node not in self.permanent.keys():            # 邻接节点不在 permanent 中
                    if node in self.temporary.keys():              # 如果节点在 temporary 中
                        if self.graph[min_node][node] + distance < self.temporary[node]:
                            self.temporary[node] = distance + self.graph[min_node][node]         # 更新节点的值
                            self.parent[node] = min_node           # 更新继承关系
                    else:                                          # 如果节点不在 temporary 中
                        self.temporary[node] = distance + self.graph[min_node][node]             # 计算节点的值,并加入 temporary 中
                        self.parent[node] = min_node               # 更新继承关系


if __name__ == '__main__':
    g = {'1': {'2': 2, '3': 8, '4': 1}, # 无向图 每个节点的相邻节点都要输入 
         '2': {'1': 2, '3': 6, '5': 1},
         '3': {'1': 8, '2': 6, '4': 7, '5': 5, '6': 1, '7': 2},
         '4': {'1': 1, '3': 7, '7': 9},
         '5': {'2': 1, '3': 5, '6': 3, '8': 2, '9': 9},
         '6': {'3': 1, '5': 3, '7': 4, '9': 6},
         '7': {'3': 2, '4': 9, '6': 4, '9': 3, '10': 1},
         '8': {'5': 2, '9': 7, '11': 9},
         '9': {'5': 9, '6': 6, '7': 3, '10': 1, '11': 2},
         '10': {'7': 1, '9': 1, '11': 4},
         '11': {'8': 9, '9': 2, '10': 4}
         } 
    
    start = '1' # 指定起点
    goal = '11' # 指定终点
    dijk = Dijkstra(g, start, goal)
    dijk.shortest_path()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值