当前位置: 首页 > news >正文

迪杰斯特拉算法

1. 算法概述

迪杰斯特拉(Dijkstra)算法是一种用于求解带权有向图或无向图中单个源节点到其他所有节点的最短路径的贪心算法。该算法要求图中所有边的权值非负,其核心思想是从源节点开始,逐步扩展到距离源节点最近的节点,并更新这些节点到源节点的最短距离,直到所有可达节点的最短距离都被确定。

2. 算法步骤

2.1 初始化
  • 距离数组:创建一个数组 dist,用于存储源节点到图中每个节点的最短距离。初始时,将源节点的距离设为 0,其他节点的距离设为无穷大(通常用一个很大的数表示)。
  • 访问标记数组:创建一个布尔型数组 visited,用于标记每个节点是否已经被访问过。初始时,所有节点的标记都为 False
  • 优先队列(可选):可以使用优先队列(最小堆)来优化算法的时间复杂度。优先队列中存储的元素是节点及其到源节点的当前最短距离,按照距离从小到大排序。
2.2 迭代过程
  • 选择未访问节点:从 dist 数组中选择距离源节点最近且未被访问过的节点 u。在使用优先队列的情况下,直接从队列中取出距离最小的节点。
  • 标记节点:将节点 u 标记为已访问,即 visited[u] = True
  • 更新邻接节点距离:遍历节点 u 的所有邻接节点 v,如果通过节点 u 到达节点 v 的距离比当前记录的 dist[v] 更小,则更新 dist[v] 的值。具体来说,若 dist[u] + weight(u, v) < dist[v],则 dist[v] = dist[u] + weight(u, v),其中 weight(u, v) 是边 (u, v) 的权值。
2.3 终止条件

当所有可达节点都被访问过或者优先队列为空时,算法结束。此时,dist 数组中存储的就是源节点到每个节点的最短距离。

3. 代码实现(Python)

import heapq
from collections import defaultdictdef dijkstra(graph, start):# dist 字典用于记录从源节点到图中每个节点的当前最短距离。# 初始化这个字典dist = {node: float('inf') for node in graph}dist[start] = 0# 初始化优先队列# 使用列表并借助 heapq 模块来模拟最小堆实现优先队列# 主要用于高效地选择距离源节点最近且未被访问过的节点,从而优化算法的时间复杂度pq = [(0, start)]while pq:# 从优先队列中取出距离最小的节点current_dist, current_node = heapq.heappop(pq)# 如果节点已经被访问过,跳过if current_dist > dist[current_node]:continue# 遍历当前节点的邻接节点for neighbor, weight in graph[current_node].items():distance = current_dist + weight# 如果通过当前节点到达邻接节点的距离更短,更新距离if distance < dist[neighbor]:dist[neighbor] = distanceheapq.heappush(pq, (distance, neighbor))return dist# 示例图的邻接表表示
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}
}start_node = 'A'
shortest_distances = dijkstra(graph, start_node)
print(f"从节点 {start_node} 到其他节点的最短距离: {shortest_distances}")

4. 复杂度分析

  • 时间复杂度:使用优先队列(最小堆)实现时,时间复杂度为 O((V+E)log⁡V)O((V + E) \log V)O((V+E)logV),其中 VVV 是图中节点的数量,EEE 是图中边的数量。每次从优先队列中取出最小元素的时间复杂度为 O(log⁡V)O(\log V)O(logV),总共需要进行 VVV 次操作;对于每条边,最多需要进行一次入队操作,时间复杂度为 O(log⁡V)O(\log V)O(logV),总共需要进行 EEE 次操作。
  • 空间复杂度:主要用于存储距离数组、优先队列和图的邻接表,空间复杂度为 O(V+E)O(V + E)O(V+E)

5. 注意事项

  • 迪杰斯特拉算法要求图中所有边的权值非负。如果图中存在负权边,该算法可能无法得到正确的最短路径,此时可以使用贝尔曼 - 福特(Bellman - Ford)算法。
  • 该算法适用于求解单个源节点到其他所有节点的最短路径。如果需要求解所有节点对之间的最短路径,可以使用弗洛伊德(Floyd)算法。

6. 其他

6.1 为什么使用优先队列?

在迪杰斯特拉算法中,优先队列(这里使用的是一个列表并借助 heapq 模块来模拟最小堆实现优先队列)主要用于高效地选择距离源节点最近且未被访问过的节点,从而优化算法的时间复杂度。下面为你详细解释其作用。

迪杰斯特拉算法核心需求

迪杰斯特拉算法的核心步骤之一是在每一轮迭代中,从所有未确定最短路径的节点里,选出距离源节点最近的节点。若不使用优先队列,就需要遍历所有未访问节点的距离数组,找出最小距离对应的节点,这个操作的时间复杂度是 O(V)O(V)O(V),其中 VVV 是图中节点的数量。在每一轮迭代都进行这样的操作,会使算法的整体时间复杂度较高。

优先队列的作用
  • 高效选择最小距离节点:优先队列可以按照节点到源节点的距离进行排序,每次从队列中取出距离最小的节点,时间复杂度为 O(log⁡V)O(\log V)O(logV)。在 Python 里,heapq 模块提供了堆操作的功能,能将列表当作最小堆来使用。在初始化优先队列时,pq = [(0, start)] 把源节点及其到自身的距离(为 0)加入队列。
  • 动态更新节点距离:当通过某个已访问节点更新了其邻接节点的距离时,如果新的距离比之前记录的距离更小,就把更新后的距离和对应的节点加入优先队列。优先队列会自动调整元素顺序,保证队首元素始终是距离源节点最近的节点。

代码示例解释

import heapq
from collections import defaultdictdef dijkstra(graph, start):# 初始化距离数组dist = {node: float('inf') for node in graph}dist[start] = 0# 初始化优先队列pq = [(0, start)]while pq:# 从优先队列中取出距离最小的节点current_dist, current_node = heapq.heappop(pq)# 如果节点已经被访问过,跳过if current_dist > dist[current_node]:continue# 遍历当前节点的邻接节点for neighbor, weight in graph[current_node].items():distance = current_dist + weight# 如果通过当前节点到达邻接节点的距离更短,更新距离if distance < dist[neighbor]:dist[neighbor] = distanceheapq.heappush(pq, (distance, neighbor))return dist
  • 初始化优先队列pq = [(0, start)] 把源节点及其到自身的距离(0)作为一个元组加入优先队列。
  • 取出最小距离节点current_dist, current_node = heapq.heappop(pq) 从优先队列中取出距离最小的节点及其距离。
  • 更新邻接节点距离:当发现通过当前节点到达邻接节点的距离更短时,使用 heapq.heappush(pq, (distance, neighbor)) 把更新后的距离和邻接节点加入优先队列。

复杂度分析

使用优先队列后,迪杰斯特拉算法的时间复杂度从 O(V2)O(V^2)O(V2) 优化到了 O((V+E)log⁡V)O((V + E) \log V)O((V+E)logV),其中 VVV 是节点数量,EEE 是边的数量。优先队列在取出最小元素和插入新元素时的时间复杂度都是 O(log⁡V)O(\log V)O(logV),而对于每条边最多进行一次插入操作,所以总的时间复杂度得到了优化。

http://www.dtcms.com/a/435565.html

相关文章:

  • 网站租用服务器价格个人主页网页设计模板
  • 【开题答辩实录分享】以《基于协调过滤算法的插画分享与社交网络平台的设计与实现》为例进行答辩实录分享
  • c语言定义数组
  • 网站运营问题wordpress主题报错
  • 做个网站需要多少钱?有没有旧装修要拆wordpress ck
  • 安卓基础组件024-fagment
  • Python 列表操作速查:增删改查与切片技巧
  • 泰州网站制作工具手机访问自动跳转到wap网站的代码
  • 家居企业网站建设讯息产品介绍彩页模板
  • Spring 基础核心 - SpringMVC 入门与请求流程
  • 【小沐学GIS】基于C++瓦片地图下载工具(高德/天地图/谷歌/必应/OSM/MapBox/ArcGIS)第十三期
  • 东方建设集团有限公司网站外国公司做网站
  • 微信里面如何做网站WordPress discuz 仿站
  • 【RabbitMq】七种工作模式
  • 官方网站下载cad建设部监理协会网站
  • 万方智能体投票火热进行中~
  • 不可见系统(Invisibility)
  • 建设读书网站的意义黄冈网站推广平台
  • SpringAI-Alibaba 快速开始
  • 网站制作费用一览表自己怎么设计公主房
  • 西安网站建设缑阳建中文搜索引擎排名
  • 五种IO模型,同步IO和异步IO
  • 网站开发环境安装程序nodejs wordpress
  • wordpress跨站脚本攻击漏洞网站风格的表现形式
  • html个人网站怎么做搜狗推广管家
  • 【读书笔记】《Linux内核设计与实现》(第1章-第5章)
  • C++中继承的理解与应用
  • 深圳有哪些网站是做餐饮沙龙的如何进行网站制作
  • Linux基本使用(Ubuntu)
  • 张家港网站制作公司专业建网站 成都