Dijkstra算法

Dijkstra算法是由荷兰计算机科学家艾兹格·迪科斯彻(Edsger W. Dijkstra)于1959年提出的,是一种解决带权图中单源最短路径问题的经典算法。该算法主要用于寻找图中从给定的源点(起点)到所有其他顶点的最短路径。在有向图或无向图中,只要边的权重非负,Dijkstra算法都能准确地找出从源点到每个顶点的最短路径。对于存在负权边的图,Dijkstra算法不再适用,此时应使用其他算法,如Bellman-Ford算法或Johnson's algorithm。

主要特点

  1. 贪心策略:Dijkstra算法采用贪心策略,每次选择当前已知距离源点最近且未确定最短路径的顶点进行扩展。这种策略保证了在每一步选择中,总是朝着全局最优方向推进。

  2. 优先队列优化:虽然基础版本的Dijkstra算法可以用普通队列实现,但为了提高效率,通常会使用优先队列(如二叉堆)来存储未访问节点,这样每次都能直接获取距离源点最近的未访问节点。

  3. 松弛操作:在算法过程中,通过“松弛”操作不断更新顶点间的最短路径估计值。每当发现一条更短的路径到达某个顶点时,就更新该顶点的最短路径估计值及其前驱节点信息。

基本步骤

  1. 初始化

    • 将源点的距离设为0,其余顶点的距离设为无穷大(或一个非常大的值)。
    • 使用一个数据结构(如优先队列)按距离排序未访问节点,初始时源点排在首位。
    • 初始化一个数据结构(如数组或映射)来存储每个顶点的前驱节点,用于回溯构建最短路径。
  2. 循环处理

    • 从优先队列中取出距离最小的未访问节点(称为当前节点)。
    • 对当前节点的每个未访问邻居节点:
      • 计算从源点经由当前节点到该邻居节点的路径长度。
      • 如果这个路径长度比已知的邻居节点距离源点的路径长度更短,则:
        • 更新邻居节点到源点的最短距离。
        • 将当前节点设置为邻居节点的前驱节点(用于路径重建)。
    • 标记当前节点为已访问。
  3. 结束条件:当优先队列为空或者已访问了目标节点(若指定的话)时,算法结束。

应用实例

Dijkstra算法广泛应用于各种需要计算最短路径的场景,例如:

  • 路径规划(如地图导航系统中的路线计算)。
  • 网络路由(如互联网协议中的路由选择)。
  • 社交网络中的朋友关系链分析。
  • 电路设计中的布线优化。

以下是Dijkstra算法的Python实现示例(以邻接列表表示带权图,并使用内置的heapq模块实现优先队列):

 

Python

1import heapq
2
3def dijkstra(graph, source):
4    distances = {node: float('inf') for node in graph}
5    distances[source] = 0
6    priority_queue = [(0, source)]  # (distance, node)
7
8    while priority_queue:
9        current_distance, current_node = heapq.heappop(priority_queue)
10
11        if current_distance > distances[current_node]:
12            continue  # Skip nodes that were already updated by a shorter path.
13
14        for neighbor, weight in graph[current_node].items():
15            distance_through_current = current_distance + weight
16            if distance_through_current < distances[neighbor]:
17                distances[neighbor] = distance_through_current
18                heapq.heappush(priority_queue, (distance_through_current, neighbor))
19
20    return distances
21
22# 示例
23graph = {
24    'A': {'B': 1, 'C': 4},
25    'B': {'A': 1, 'D': 2, 'E': 5},
26    'C': {'A': 4, 'F': 8},
27    'D': {'B': 2, 'E': 1},
28    'E': {'B': 5, 'D': 1, 'F': 3},
29    'F': {'C': 8, 'E': 3}
30}
31
32shortest_distances = dijkstra(graph, 'A')
33print("Shortest distances from A:", shortest_distances)

实现了Dijkstra算法的核心逻辑,使用字典distances存储每个顶点到源点的最短距离,优先队列priority_queue则按距离排序待访问节点。遍历结束后,返回一个字典,其中包含了从源点到每个顶点的最短距离。

收起

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无极921

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值