【最短路径算法】一文掌握Dijkstra算法,详解与应用示例+代码

目录

1 Dijkstra算法

2 Dijkstra算法的步骤

3 Dijkstra算法python实现

4 Dijkstra算法应用示例详解


1 Dijkstra算法

        Dijkstra算法(迪杰斯特拉算法)是一种用于在加权图中查找从一个起始节点到所有其他节点的最短路径的算法。该算法最初由荷兰计算机科学家Edsger W. Dijkstra于1956年提出。Dijkstra算法适用于带有非负权重的有向图或无向图。

特点和限制:

  • Dijkstra算法仅适用于非负权重的图,因为它依赖于贪婪策略来选择当前最短路径。
  • 它可以找到从起始节点到所有其他节点的最短路径,因此适用于单源最短路径问题。
  • Dijkstra算法不会处理负权边,如果图中存在负权边,应该使用其他算法,如Bellman-Ford算法。
  • 算法的时间复杂度取决于数据结构的选择,一般情况下是O(V^2)或O(Vlog(V)),其中V是节点数。如果使用优先队列来优化,时间复杂度可以减小到O(Elog(V)),其中E是边数。

        Dijkstra算法在许多领域广泛应用,包括路线规划、网络路由、资源分配和许多其他需要找到最短路径的应用。

2 Dijkstra算法的步骤

  1. 创建一个空的最短路径字典,其中每个节点的距离设置为无穷大,起始节点的距离设置为0。

  2. 创建一个空的已访问节点集合。

  3. 从未访问的节点中选择距离起始节点最近的节点,标记为已访问。

  4. 对于已访问节点的所有邻居,计算通过已访问节点到达它们的距离,并更新最短路径字典。

  5. 重复步骤3和4,直到所有节点都被访问。

3 Dijkstra算法python实现

以下是Python中使用Dijkstra算法实现的示例代码,用于查找从起始节点到其他节点的最短路径:

import heapqdef dijkstra(graph, start):# 创建一个距离字典,用于存储每个节点到起始节点的距离distances = {node: float('inf') for node in graph}distances[start] = 0# 创建一个优先队列,以便选择下一个节点priority_queue = [(0, start)]while priority_queue:current_distance, current_node = heapq.heappop(priority_queue)# 如果当前距离大于已知距离,跳过if current_distance > distances[current_node]:continue# 遍历当前节点的邻居for neighbor, weight in graph[current_node].items():distance = current_distance + weight# 如果发现更短的路径,更新距离字典和优先队列if distance < distances[neighbor]:distances[neighbor] = distanceheapq.heappush(priority_queue, (distance, neighbor))return distances# 创建一个示例图
graph = {'A': {'B': 2, 'D': 1},'B': {'A': 2, 'C': 3, 'E': 2},'C': {},'D': {'E': 1},'E': {}
}# 起始节点
start_node = 'A'# 调用Dijkstra算法函数
shortest_distances = dijkstra(graph, start_node)# 打印最短路径和距离
for node, distance in shortest_distances.items():print(f'Shortest distance from {start_node} to {node} is {distance}')

运行: 

        这段代码定义了一个 dijkstra 函数,用于执行Dijkstra算法。它接受一个图的表示和起始节点作为参数,并返回一个包含从起始节点到其他节点的最短路径的字典。然后,我们创建一个示例图,并使用Dijkstra算法找到从节点 A 到其他节点的最短路径。

        请注意,你可以根据你的需求更改示例图和起始节点,以便应用Dijkstra算法到你的具体问题中。

4 Dijkstra算法应用示例详解

假设我们有以下有向图:

在这个示意图中,有向图包括节点 A、B、C、D 和 E,以及它们之间的带权重的边。边的数字表示权重或距离。我们的目标是找到从节点 A 到其他节点的最短路径。

Dijkstra算法的执行步骤:

  1. 初始化:开始时,我们选择节点 A 作为起始节点,并将其距离设置为 0。同时,将其他节点的距离初始化为无穷大,表示尚未知道到达它们的最短路径。

  2. 选择下一个节点:首先,我们选择节点 A 作为当前节点。它是起始节点,距离已知。

  3. 更新距离:我们计算从节点 A 到其邻居节点 B 和 C 的距离,并将这些距离记录下来。当前已知的最短距离是从 A 到 B 的距离为 4,从 A 到 C 的距离为 2。

  4. 选择下一个节点:现在,我们选择距离最短的节点 C 作为当前节点。

  5. 更新距离:我们计算从 A 经过 C 到达其邻居节点 B 和 D 的距离,并将这些距离记录下来。距离从 A 经过 C 到 B 的距离变为 4 + 5 = 9,从 A 经过 C 到 D 的距离变为 2 + 5 = 7。

  6. 选择下一个节点:然后,我们选择距离最短的节点 B 作为当前节点。

  7. 更新距离:我们计算从 A 经过 B 到达其邻居节点 D 的距离,并将这个距离记录下来。距离从 A 经过 B 到 D 的距离变为 4 + 5 + 3 = 12。

  8. 选择下一个节点:最后,我们选择距离最短的节点 D 作为当前节点。

  9. 更新距离:我们计算从 A 经过 D 到达其邻居节点 E 的距离,并将这个距离记录下来。距离从 A 经过 D 到 E 的距离变为 4 + 5 + 3 + 7 = 19。

  10. 完成:所有节点都已被访问,算法结束。

以上最短路径从节点 A 到其他节点的距离如下: 

  • A到A是 0
  • A到B是 9
  • A到C是 2
  • A到D是 12
  • A到E是 19

        这个示意图展示了Dijkstra算法是如何逐步找到最短路径,并在每一步中选择距离最短的节点。算法的关键思想是贪婪地选择当前最短路径,以逐步构建最短路径树。


以下是Python代码示例,演示如何使用Dijkstra算法找到从节点 A 到其他节点的最短路径:

import networkx as nx
import matplotlib.pyplot as plt# 创建一个有向图
G = nx.DiGraph()# 添加节点
nodes = ['A', 'B', 'C', 'D', 'E']
G.add_nodes_from(nodes)# 添加边和权重
edges = [('A', 'B', 4), ('A', 'C', 2), ('B', 'C', 5), ('B', 'D', 10), ('C', 'D', 3), ('D', 'E', 7), ('E', 'B', 8)]
G.add_weighted_edges_from(edges)# 定义起点
start_node = 'A'# 运行Dijkstra算法
shortest_paths = nx.single_source_dijkstra(G, source=start_node)# 提取最短路径信息
shortest_distances, shortest_path_predecessors = shortest_paths# 修正labels的格式
labels = {(edge[0], edge[1]): edge[2] for edge in G.edges(data='weight')}# 可视化图
pos = nx.spring_layout(G, seed=42)  # 布局算法,使图看起来更美观plt.figure(figsize=(10, 6))
nx.draw(G, pos, with_labels=True, node_size=800, node_color='lightblue', font_size=12, font_weight='bold')
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels, font_size=10)# 绘制最短路径
for node in nodes:if node != start_node:path = nx.shortest_path(G, source=start_node, target=node)path_edges = [(path[i], path[i + 1]) for i in range(len(path) - 1)]nx.draw_networkx_edges(G, pos, edgelist=path_edges, edge_color='red', width=2)plt.title("Dijkstra Algorithm - Shortest Paths")
plt.show()# 打印最短路径和距离
for node, distance in shortest_distances.items():if node != start_node:path = nx.shortest_path(G, source=start_node, target=node)print(f"Shortest path from {start_node} to {node}: {path}, Distance: {distance}")

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/114325.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

offsetof宏计算某变量相对于首地址的偏移量

宏&#xff1a;offsetof的使用 //offsetof (type,member) //type是结构体的类型名&#xff0c;member是结构体中的成员名。struct Student {char name[5]; // 姓名int age; // 年龄float score; // 成绩 };int main() {struct Student s;printf("%zd\n", off…

【转载】 Bytedance火山引擎智能拥塞控制算法 VICC

BytedanceTechBlog : 火山引擎实时、低延时拥塞控制算法的优化实践 火山引擎 网站如何利用播放器节省20%点播成本点击下面的链接进入原文:原创 翟强俊、唐辉 字节跳动技术团队 2023-10-18 11:59 发表于北京 一些专利摘要 火山引擎智能拥塞控制算法 VICC(Volcano Intelligent…

Android微信逆向--实现发朋友圈动态

Android微信逆向--实现发朋友圈动态 0x0 前言# 最近一直在研究Windows逆向的东西&#xff0c;想着快要把Android给遗忘了。所以就想利用工作之余来研究Android相关的技术&#xff0c;来保持对Android热情。调用微信代码来发送朋友圈动态一直是自己想实现的东西&#xff0c;研…

邻接表存储图或者树

大家好&#xff0c;我叫徐锦桐&#xff0c;个人博客地址为www.xujintong.com。平时记录一下学习计算机过程中获取的知识&#xff0c;还有日常折腾的经验&#xff0c;欢迎大家来访。 介绍 每个顶点都作为头节点&#xff0c;并且存在一个一维数组中h[N]。树就是相当于一种有向图…

redis哨兵模式详解

目录 前言&#xff1a; 手动干预主节点挂的情况 哨兵节点操作流程 哨兵重新选取主节点流程 主观下线 客观下线 哨兵节点选leader 挑选从节点作为主节点 前言&#xff1a; redis在主从模式下&#xff0c;主节点服务就显的尤为重要。为了保证redis集群的高可用&#xff0…

论文阅读-FCD-Net: 学习检测多类型同源深度伪造人脸图像

一、论文信息 论文题目&#xff1a;FCD-Net: Learning to Detect Multiple Types of Homologous Deepfake Face Images 作者团队&#xff1a;Ruidong Han , Xiaofeng Wang , Ningning Bai, Qin Wang, Zinian Liu, and Jianru Xue &#xff08;西安理工大学&#xff0c;西安交…

GB28181学习(十)——视音频文件下载

要求 SIP服务器接收到媒体接收者发送的视音频文件下载请求后向媒体流发送者发送媒体文件下载命令&#xff0c;媒体流发送者采用RTP将视频流传输给媒体流接收者&#xff0c;媒体流接收者直接将视频流保存为媒体文件&#xff1b;媒体流接收者或SIP服务器可通过配置查询等方式获取…

【Hello Algorithm】暴力递归到动态规划(五)

死亡概率问题 现在给定你三个参数 N M K 怪兽有 N 滴血 等着英雄来砍自己 英雄每一次打击会让怪兽流失 0 ~ M 滴血 概率相同 请求在K次之后 英雄把怪兽砍死的概率 递归版本 面对这个问题 我们首先来想递归函数怎么写 首先是返回值 我们无法直接返回一个概率给上层 所以我…

gRPC之gRPC转换HTTP

1、gRPC转换HTTP 我们通常把RPC用作内部通信&#xff0c;而使用Restful Api进行外部通信。为了避免写两套应用&#xff0c;我们使用grpc- gateway 把gRPC转成HTTP。服务接收到HTTP请求后&#xff0c;grpc-gateway把它转成gRPC进行处理&#xff0c;然后以JSON 形式返回数据。…

Go 语言的垃圾回收机制:自动化内存管理

在编程的世界中&#xff0c;内存管理一直是一个重要的问题。不正确的内存管理可能导致内存泄漏和程序崩溃。Go 语言以其高效的垃圾回收机制而闻名&#xff0c;使开发者从手动内存管理的烦恼中解脱出来。本文将深入探讨Go语言的垃圾回收机制&#xff0c;介绍它的工作原理以及如何…

消息队列 RocketMQ 消息重复消费问题(原因及解决)

目录 1.出现重复消费的原因 2.解决 2.1 数据库插入法 2.2 使用布隆过滤器 2.2.1 添加hutool的依赖 2.2.2 测试生产者 2.2.2 测试消费者 1.出现重复消费的原因 BROADCASTING(广播) 模式下&#xff0c;所有注册的消费者都会消费&#xff0c;而这些消费者通常是集群部署的…

ubuntu20.04下安装nc

前言 nc在网络渗透测试中非常好用&#xff0c;这里的主要记一下Ubuntu20.04中nc的安装 编译安装 第一种方式是自己编译安装&#xff0c;先下载安装包 nc.zip wget http://sourceforge.net/projects/netcat/files/netcat/0.7.1/netcat-0.7.1.tar.gz/download -O netcat-0.7.…

当你学会这项python数据提取神器时,请做好升职准备!

一、什么是 jsonpath ● JsonPath 是一种信息抽取类库&#xff0c;是从 JSON 文档中抽取指定信息的工具&#xff0c;提供多种语言实现版本&#xff0c;包括&#xff1a;JavaScript、Python、PHP 和 Java。 二、特点 ● 只能提取 JSON 格式的数据 ● 提取后的数据类型与原数据…

2023秋招笔试算法Python3题解

诸神缄默不语-个人CSDN博文目录 签两方了&#xff0c;感觉秋招已经结束了&#xff0c;所以发布一下之前写的笔试编程题题解。 不全。可能有些题我会继续补。 不保证能过。 后续依然有可能继续刷算法题&#xff0c;但是就另外专门写博文来解析了。 打码是因为原则上其实是不让公…

国密https访问

前言 现在的SSL的加密算法实际上主要是国际算法&#xff0c;包括JDK&#xff0c;Go等语言也仅支持国际算法加密&#xff08;毕竟是国外开源项目&#xff09;&#xff0c;hash。随着国密算法的普及&#xff0c;比如openssl就支持国密了&#xff0c;还要新版本的Linux内核也开始…

【Python第三方包】实现自动化(pyautogui包)

文章目录 前言一、如何安装pyautogui二、pyautogui鼠标操作2.1 鼠标移动2.2 鼠标点击2.3 拖动鼠标三、键盘操作3.1 按下和释放按键3.2 键盘输入四、截图和图像识别4.1 截图4.2 图像识别总结前言 自动化是现代计算机编程和软件开发中的一个重要概念。通过自动化,我们可以节省时…

解决因d3dx9_30.dll丢失程序无法运行,电脑缺失d3dx9_30.dll报错解决方案

我们的生活和工作都离不开电脑。然而&#xff0c;电脑作为一种复杂的工具&#xff0c;也会出现各种各样的问题。其中&#xff0c;丢失d3dx9_30.dll文件是一个常见的问题。d3dx9_30.dll是DirectX的动态链接库文件&#xff0c;如果丢失或损坏&#xff0c;可能会导致许多软件和游戏…

[论文笔记]GPT-1

引言 今天带来论文Improving Language Understanding by Generative Pre-Training的笔记,它的中文题目为:通过生成式预训练改进语言理解。其实就是GPT的论文。 自然语言理解可以应用于大量NLP任务上,比如文本蕴含、问答、语义相似和文档分类。虽然无标签文本语料是丰富的,…

Js使用ffmpeg在视频中添加png或gif

Js使用ffmpeg在视频中添加png或gif ffmpeg 使用场景是需要在web端对视频进行编辑 添加图片和gif。 注意: 以下所有的使用案例均基于vue3 setup。 同时由于ffmpeg版本不同会导致使用的api不同&#xff0c;使用案例前需要注意ffmpeg版本问题。 如果使用的是0.12需要使用新的…

通讯录和内存动态管理

目录 (通讯录)动态增长版 实现效果 找单身狗 题目 源码 思路 三个内存函数的模拟实现 模拟实现strncpy 模拟实现strncat 模拟实现atoi (通讯录)动态增长版 该版本通讯录在原版的基础上增加了检查容量函数&#xff0c;实现了通讯录的动态…