详解Dijkstra算法-单源最短路径

Dijkstra算法是一种经典的单源最短路径算法,适用于加权图,即图中边的权重可以是任意非负数。该算法由荷兰计算机科学家Edsger W. Dijkstra在1956年提出,并于1959年正式发表。它的基本思想是通过贪心策略,不断扩展最短路径的集合,直到找到从源点到所有其他顶点的最短路径。

算法步骤

  1. 初始化
    • 将所有顶点的最短路径估计值设置为正无穷大,除了源点,源点的最短路径估计值设置为0。
    • 将所有顶点标记为未访问。
    • 创建一个空的已访问顶点集合。
  2. 选择当前未访问顶点中最短路径估计值最小的顶点
    • 从所有未访问顶点中选择一个最短路径估计值最小的顶点,记为u。
  3. 更新邻接顶点的最短路径估计值
    • 对于顶点u的每一个邻接顶点v,如果通过u到达v的路径比当前已知的到v的最短路径更短,则更新v的最短路径估计值。
  4. 标记顶点u为已访问
    • 将顶点u标记为已访问,并将其加入已访问顶点集合。
  5. 重复步骤2到步骤4
    • 直到所有顶点都被访问过,或从源点到所有未访问顶点的最短路径都已经确定。

伪代码

以下是Dijkstra算法的代码:

import heapq

def dijkstra(graph, start):
    # 初始化距离表,所有距离为无穷大
    distances = {vertex: float('infinity') for vertex in graph}
    # 起点的距离为0
    distances[start] = 0
    # 优先队列,存储(距离,顶点)
    priority_queue = [(0, start)]
    
    while priority_queue:
        # 获取距离最小的顶点
        current_distance, current_vertex = heapq.heappop(priority_queue)
        
        # 如果从优先队列中取出的距离大于当前距离,则跳过(这是因为我们已经找到更短的路径)
        if current_distance > distances[current_vertex]:
            continue
        
        # 更新相邻顶点的距离
        for neighbor, weight in graph[current_vertex].items():
            distance = current_distance + weight
            # 如果找到更短的路径,更新距离表并加入优先队列
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(priority_queue, (distance, neighbor))
    
    return distances

# 示例图,使用邻接表表示
graph = {
    'A': {'B': 1, 'C': 4},
    'B': {'A': 1, 'C': 2, 'D': 5},
    'C': {'A': 4, 'B': 2, 'D': 1},
    'D': {'B': 5, 'C': 1}
}

# 计算从顶点A到其他顶点的最短路径
start_vertex = 'A'
distances = dijkstra(graph, start_vertex)

print(f"从顶点 {start_vertex} 出发的最短路径距离:")
for vertex, distance in distances.items():
    print(f"到顶点 {vertex} 的距离为 {distance}")

复杂度

  • 时间复杂度:对于一个有n个顶点和m条边的图,使用二叉堆优化的Dijkstra算法的时间复杂度是O((n + m) log n)。
  • 空间复杂度:主要用于存储图的结构、距离数组和优先队列,因此空间复杂度是O(n + m)。

示例

假设我们有一个图如下:

    A
   / \\
  1   4
 /     \\
B---2---C
 \\     /
  5   1
   \\ /
    D

权重为边的长度。我们从A开始运行Dijkstra算法:

  1. 初始化:

    dist[A] = 0
    dist[B] = ∞
    dist[C] = ∞
    dist[D] = ∞
    
    
  2. 从A开始,更新B和C的距离:

    dist[B] = 1 (A -> B)
    dist[C] = 4 (A -> C)
    
    
  3. 选择B,更新D的距离:

    dist[D] = 6 (B -> D)
    
    
  4. 选择C,更新D的距离:

    dist[D] = 5 (C -> D)
    
    
  5. 选择D,算法结束。

最终的最短路径距离:

dist[A] = 0
dist[B] = 1
dist[C] = 4
dist[D] = 5

Dijkstra算法通过逐步扩展已确定最短路径的顶点集合,保证每次选取的顶点都是当前未访问顶点中距离源点最近的,从而有效地找到从源点到所有其他顶点的最短路径。

  • 20
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值