算法学习笔记(7.7)-贪心算法(Dijkstra算法-最短路径问题)

目录

1.最短路径问题

 2.Dijkstra算法介绍

 3.Dijkstra算法演示

4.Dijkstra算法的代码示例


1.最短路径问题

图论中的一个经典问题,通常是指在一个加权图中找到从一个起始顶点到目标顶点的最短路径。

  1. 单源最短路径问题:给定一个加权图和一个起始顶点,要找到从该起始顶点到图中所有其他顶点的最短路径。

    • Dijkstra算法:适用于没有负权边的图,能够找到单源最短路径。

    • Bellman-Ford算法:适用于存在负权边的图,能够找到单源最短路径。

  2. 全源最短路径问题:给定一个加权图,要找到图中任意两个顶点之间的最短路径。

    • Floyd-Warshall算法:适用于有向图或无向图,能够找到所有顶点之间的最短路径。
  3. 最短路径问题的应用

    • 在网络路由中,确定数据包的最佳路径。

    • 在地图应用程序中,找到两个地点之间的最短驾驶路径。

    • 在交通规划中,优化公交线路或货运路径。

    • 在电路设计中,找到电路中信号传输的最短路径。

  4. 解决最短路径问题的算法

    • Dijkstra算法:适用于非负权重的图,能够找到单源最短路径。

    • Bellman-Ford算法:适用于存在负权重的图,能够找到单源最短路径。

    • A*算法:一种启发式搜索算法,用于寻找从起点到目标点的最短路径。

    • Bellman-Ford算法:适用于有向图或无向图,能够找到所有顶点之间的最短路径。

 2.Dijkstra算法介绍

1.Dijkstra算法特点:

迪科斯彻算法使用了广度优先搜索解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树。该算法常用于路由算法或者作为其他图算法的一个子模块。

2.Dijkstra算法的步骤:

2.1 初始化:创建一个空的集合用于存储已经找到最短路径的顶点,以及一个数组用于存储从起始顶点到每个顶点的最短距离。将起始顶点的最短距离设置为0,其他顶点的最短距离设置为无穷大。

2.2 选取起始顶点:将起始顶点加入集合,更新起始顶点到相邻顶点的最短距离。

2.3 重复步骤:重复以下步骤,直到所有顶点都被加入集合为止:
   2.3.1 从未加入集合的顶点中选取与起始顶点距离最短的顶点加入集合。
   2.3.2 更新该顶点到相邻顶点的最短距离,如果经过该顶点到相邻顶点的距禒小于已知的最短距离,则更新最短距离。

2.4 最终结果:当所有顶点都被加入集合后,最短路径就被找到了。

3. Dijkstra算法的特点和适用性:

3.1 Dijkstra算法适用于带权重的有向图或无向图。
3.2 该算法保证找到的路径是最短的,但前提是图中不能有负权重的边
3.3 时间复杂度取决于具体实现,通常在稠密图上的时间复杂度为O(V^2),在稀疏图上的时间复杂度为O(E * log V)。
3.4 Dijkstra算法常用于路由算法、网络分析、地图应用等领域。

4. Dijkstra核心算法思想:

迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止

 3.Dijkstra算法演示

1.用一个 dist 数组保存源点到其余各个节点的距离,dist[i] 表示源点到节点 i 的距离。初始时,dist 数组的各个元素为无穷大。用一个状态数组 state 记录是否找到了源点到该节点的最短距离,state[i] 如果为真,则表示找到了源点到节点 i 的最短距离,state[i] 如果为假,则表示源点到节点 i 的最短距离还没有找到。初始时,state 各个元素为假。

2.源点到源点的距离为 0。即dist[1] = 0。

3.遍历 dist 数组,找到一个节点,这个节点是:没有确定最短路径的节点中距离源点最近的点。假设该节点编号为 i。此时就找到了源点到该节点的最短距离,state[i] 置为 1。

4.遍历 i 所有可以到达的节点 j,如果 dist[j] 大于 dist[i] 加上 i -> j 的距离,即 dist[j] > dist[i] + w[i][j](w[i][j] 为 i -> j 的距离) ,则更新 dist[j] = dist[i] + w[i][j]。

5.重复 3 4 步骤,直到所有节点的状态都被置为 1。


6.此时 dist 数组中,就保存了源点到其余各个节点的最短距离。

4.Dijkstra算法的代码示例

//c++代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;const int N = 510, M = 100010, INF = 0x3f3f3f3f;int h[N], e[M], ne[M], w[M], idx;
//h数组用来储存每个边链表的头部
//e数组用来存储每条边指向的节点编号
//w用来存储每条边的权重
//ne数组用来实现邻接表中的链表结构 
int dist[N]; //state 记录是否找到了源节点到该节点的最短距离
bool state[N]; //dist 数组保存源点到其余各个节点的距离
int n, m; //图的节点个数和边数
int adjMatrix[N][N];  // 邻接矩阵void add(int a, int b, int c) 
{e[idx] = b ; //将当前边的目标节点b存储在,e[idx]中 w[idx] = c ; //将该条边的权重存储在,w[idx]中 ne[idx] = h[a] ; //更新ha将之前节点a的第一条边的索引存储在ne数组,使其一直处于更新状态指向最新的一条边 h[a] = idx++ ;	
}// 打印邻接表
void printAdjList() {for (int i = 1; i <= n; ++i) {cout << "Vertex " << i << ":";for (int j = h[i]; j != -1; j = ne[j]) {cout << "-> (" << e[j] << ", " << w[j] << ")";}cout << endl;}
}// 创建并打印邻接矩阵
void printAdjMatrix() {// 初始化邻接矩阵for (int i = 1; i <= n; ++i) {for (int j = 1; j <= n; ++j) {if (i == j) adjMatrix[i][j] = 0;else adjMatrix[i][j] = INF;}}// 填充邻接矩阵for (int i = 1; i <= n; ++i) {for (int j = h[i]; j != -1; j = ne[j]) {int to = e[j];adjMatrix[i][to] = min(adjMatrix[i][to], w[j]);  // 如果有重边,保留权重最小的一条}}// 打印邻接矩阵for (int i = 1; i <= n; ++i) {for (int j = 1; j <= n; ++j) {if (adjMatrix[i][j] == INF) cout << "INF ";else cout << adjMatrix[i][j] << " ";}cout << endl;}
}void Dijkstra()
{memset(dist, 0x3f, sizeof(dist)) ; //dist 初始化数组中的元素为最大值dist[1] = 0 ;for (int i = 0 ; i < n ; i++){int t = -1 ;for (int j = 1 ; j <= n ; j++){//遍历 dist 数组,找到没有确定最短路径的节点 if (!state[j] && (t == -1 || dist[j] < dist[t])){t = j ;	}}state[t] = 1 ; //将该位置置为访问for (int j = h[t]; j != -1 ; j = ne[j]) //遍历 t 所有可以到达的节点i {int i = e[j] ;dist[i] = min(dist[i], dist[t] + w[j]) ; //更新dist[j] }	} 
}int main()
{memset(h, -1, sizeof(h)) ;cin >> n >> m ;while (m--){int a, b, w ;cin >> a >> b >> w ;add(a, b, w) ;}Dijkstra() ;if (dist[n] != 0x3f3f3f3f){cout << dist[n] ;}else{cout << "-1" ;}// 打印邻接表printAdjList();// 创建并打印邻接矩阵printAdjMatrix();return 0 ;
}

#python代码示例# 简单的Dijkstra算法
import heapqdef dijkstra(graph, start) :# 初始化距离字典,将所有节点的距离设置为无穷大distances = {node : float('inf') for node in graph}# 源节点到自身的距离设置为0distances[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))print(f"更新节点: {neighbor} 的最短路径为: {distance}")return distancesgraph = {
'A': {'B': 1, 'C': 3},
'B': {'A': 1, 'C': 1, 'D': 4},
'C': {'A': 3, 'B': 2, 'D': 1},
'D': {'B': 4, 'C': 1}
}
start = 'A'
# print(dijkstra(graph, start))  # {'A': 0, 'B': 1, 'C': 3, 'D': 4}shortest_paths = dijkstra(graph, start)
print("\n从节点 {} 到图中其他节点的最短路径:".format(start))
for node, distance in shortest_paths.items():print(f"到节点 {node} 的最短距离是: {distance}")

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

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

相关文章

Python易错点总结

目录 多分支选择结构 嵌套选择 用match模式识别 match与if的对比 案例&#xff1a;闰年判断 三角形的判断 用whlie循环 高斯求和 死循环 用for循环 ​编辑continue​编辑 whlie与else结合 pass 序列 列表&#xff08;有序&#xff09; 元组&#xff08;有序&…

在虚拟机上搭建 Docker Kafka 宿主机器程序无法访问解决方法

1、问题描述 在虚拟机CentOS-7上搭建的Docker Kafka ,docker内部可以创建Topic、可以生产者数据、可以消费数据&#xff0c;而在宿主机开发程序无法消费Docker Kafka的数据。 1.1、运行情况 [dockerlocalhost ~]$ docker ps -a CONTAINER ID IMAGE COMMAND…

区块链的基本原理和优势

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

使用亮数据代理IP爬取PubMed文章链接和邮箱地址

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

Redis页面优化

文章目录 1.Redis页面缓存1.思路分析2.首先记录一下目前访问商品列表页的QPS1.线程组配置10000次请求2.请求配置3.开始压测1.压测第一次 平均QPS为6122.压测第二次 平均QPS为6153.压测第三次 平均QPS为617 3.然后记录一下访问商品详情页的QPS1.线程组配置10000次请求2.请求配置…

【人工智能】第三部分:ChatGPT的应用场景和挑战

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

Pyinstaller安装与使用

一、Pyinstaller简介 PyInstaller将Python应用程序冻结(打包)独立可执行文件中。它可以构建较小的可执行文件,它是完全多平台的,并且使用OS支持来加载动态库,从而确保完全兼容。 二、Pyinstaller安装 1、下载安装 首先安装“pip install pywin32” 其次“pip install …

亿发软件:信息化与数字化,相互交织的科技双引擎

在现代科技发展的浪潮中&#xff0c;信息化和数字化是两个频繁被提及的关键词。尽管它们在很多情况下被视为同义词&#xff0c;但其实两者有着本质的区别和相互影响的关系。究竟是信息化推动了数字化&#xff0c;还是数字化引领了信息化的进程&#xff1f;本文将深入探讨信息化…

C++第二十五弹---从零开始模拟STL中的list(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、函数补充 2、迭代器完善 3、const迭代器 总结 1、函数补充 拷贝构造 思路&#xff1a; 先构造一个头结点&#xff0c;然后将 lt 类中的元…

10.dockerfile自动构建镜像

dockerfile自动构建镜像 类似ansible剧本&#xff0c;大小几kb 手动做镜像&#xff1a;大小几百M 首先创建一个dockerfile的路径&#xff0c;便于在路径下存在多个路径每个路径下都是dockerfile命名的脚本 注释&#xff1a;文件必须为&#xff1a;dockerfile或者Dockerfile …

基于深度学习的中文标点预测模型-中文标点重建(Transformer模型)【已开源】

基于深度学习的中文标点预测模型-中文标点重建&#xff08;Transformer模型&#xff09;提供模型代码和训练好的模型 前言 目前关于使用深度学习对文本自动添加标点符号的研究并不多见&#xff0c;已知的开源项目也较少&#xff0c;而对该领域的详细介绍更是稀缺。然而&#x…

【vscode-快捷键 一键JSON格式化】

网上有很多JSON格式化工具&#xff0c;也有很多好用的在线json格式化工具。但是其实Vscode里面的可以直接格式化JSON&#xff0c;这里分享一个我常用的小插件 Prettify JSON 未格式化的JSON数据 召唤出命令行&#xff0c;输入prettify JSON 即可! ✿✿ヽ(▽)ノ✿

OpenAI模型规范概览

这是OpenAI对外分享的模型规范文档&#xff08;Model Spec&#xff09;&#xff0c;它定义了OpenAI希望在API接口和ChatGPT&#xff08;含GPT系列产品&#xff09;中模型的行为方式&#xff0c;这也是OpenAI超级对齐团队奉行的行为准则&#xff0c;希望能对国内做RLHF的同学有帮…

力扣爆刷第148天之贪心算法五连刷(区间合并)

力扣爆刷第148天之贪心算法五连刷&#xff08;区间合并&#xff09; 文章目录 力扣爆刷第148天之贪心算法五连刷&#xff08;区间合并&#xff09;一、406. 根据身高重建队列二、452. 用最少数量的箭引爆气球三、435. 无重叠区间四、763. 划分字母区间五、56. 合并区间六、738.…

安卓约束性布局学习

据说这个布局是为了解决各种布局过度前套导致代码复杂的问题的。 我想按照自己想实现的各种效果来逐步学习&#xff0c;那么直接拿微信主页来练手&#xff0c;用约束性布局实现微信首页吧。 先上图 先实现顶部搜索框加号按钮 先实现 在布局中添加一个组件&#xff0c;然后摆放…

【java】速度搭建一个springboot项目

使用软件&#xff1a;IDEA&#xff0c;mysql 使用框架&#xff1a;springboot mybatis-plus druid 坑点 使用IDEA搭建一个springboot项目的时候&#xff0c;需要考虑一下IDEA版本支持的JDK版本以及maven版本。否则再构建项目&#xff0c;引入pom的时候就会报错。 需要检查…

PostgreSQL基础(十):PostgreSQL的并发问题

文章目录 PostgreSQL的并发问题 一、事务的隔离级别 二、MVCC PostgreSQL的并发问题 一、事务的隔离级别 在不考虑隔离性的前提下&#xff0c;事务的并发可能会出现的问题&#xff1a; 脏读&#xff1a;读到了其他事务未提交的数据。&#xff08;必须避免这种情况&#xf…

docker命令 docker ps -l (latest)命令在 Docker 中用于列出最近一次创建的容器

文章目录 12345 1 docker ps -l 命令在 Docker 中用于列出最近一次创建的容器。具体来说&#xff1a; docker ps&#xff1a;这个命令用于列出当前正在运行的容器。-l 或 --latest&#xff1a;这个选项告诉 docker ps 命令只显示最近一次创建的容器&#xff0c;不论该容器当前…

OpenAI发表研究论文 介绍了一种逆向工程AI模型工作原理的方法

ChatGPT 开发商 OpenAI 构建人工智能的方法本周遭到了前员工的抨击&#xff0c;他们指责该公司利用可能有害的技术冒不必要的风险。今天&#xff0c;OpenAI 发布了一篇新的研究论文&#xff0c;目的显然是为了表明它在通过提高模型的可解释性来应对人工智能风险方面的认真态度。…