最短路问题

最短路问题

本题调用heapq库来实现Dijkstra算法来解决最短路问题

Dijkstra算法

Dijkstra算法的本质是贪心算法,每次从未标记的节点中选择距离出发点最近的节点,标记,收录到最优路径集合中,计算刚加入节点A的邻近节点B的距离(不包含标记的距离),若(节点A的距离+节点A到节点B 的距离)< 节点B的距离,就更新节点B的距离和前驱节点。

题目:如下图所示,G 是一个无向图,其中蓝色边的长度是 1,橘色边的长度是 2,绿色边的长度是 3.
在这里插入图片描述
代码如下

import os
import sys
import heapq

def dijkstra(graph, start):
  """最短路径算法"""

  dist = {node: float("inf") for node in graph}  # 最优路径字典
  dist[start] = 0  # 设置起始点
  prev = {node: None for node in graph}  # 前驱节点字典

  # 使用堆来储存未处理的节点
  heap = [(dist[node], node) for node in graph]
  heapq.heapify(heap)

  while heap:
    # 弹出最小元素的节点
    current_dist, current_node = heapq.heappop(heap)

    # 若此时节点的长度大于之前的计算的长度则忽略
    if current_dist > dist[current_node]:
      continue
    else:
      for neighbor, height in graph[current_node].items():
        new_dist = dist[current_node] + height
        if dist[neighbor] > new_dist:
          dist[neighbor] = new_dist
          prev[neighbor] = neighbor
          heapq.heappush(heap, (new_dist, neighbor))
  # 返回最短路径字典和前驱节点字典
  return dist, prev


g = {'A': {'B': 2, 'C': 1, 'D': 1, 'E': 1}, 
     'B': {'A': 2, 'G': 1, 'J': 2}, 
     'C': {'A': 1, 'D': 3, 'F': 3, 'G': 3}, 
     'D': {'A': 1, 'C': 3, 'G': 2, 'H': 1, 'I': 2, 'E': 1}, 
     'E': {'A': 1, 'H': 1, 'I': 3, 'D': 1}, 
     'F': {'C': 3, 'G': 1, 'J': 1}, 
     'G': {'B': 1, 'C': 3, 'D': 2, 'F': 1, 'I': 3, 'K': 2}, 
     'H': {'D': 1, 'E': 1, 'I': 1, 'L': 2}, 
     'I': {'D': 2, 'E': 3, 'G': 3, 'H': 1, 'M': 3}, 
     'J': {'B': 2, 'F': 1, 'S': 2}, 
     'K': {'G': 2, 'L': 3, 'N': 1, 'P': 2}, 
     'L': {'H': 2, 'K': 3, 'M': 1, 'R': 1}, 
     'N': {'K': 1, 'M': 2, 'P': 1}, 
     'M': {'I': 3, 'L': 1, 'N': 2, 'Q': 1, 'S': 1}, 
     'O': {'P': 1, 'Q': 1, 'R': 3}, 
     'P': {'N': 1, 'O': 1, 'K': 2}, 
     'Q': {'M': 1, 'O': 1}, 
     'R': {'L': 1, 'O': 3, 'S': 1}, 
     'S':{'J': 2, 'M': 1, 'R': 1}
}
dist, prev = dijkstra(g,'A')
print(dist['S'])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值