算法学习笔记(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.mzph.cn/diannao/24601.shtml

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

相关文章

【传知代码】Noise2Noise图像去噪(论文复现)

前言&#xff1a;在数字时代&#xff0c;图像已成为我们记录生活、传达信息、探索世界的重要媒介。然而&#xff0c;随着摄影技术的飞速发展&#xff0c;图像噪声——这一影响图像质量的顽疾&#xff0c;始终困扰着我们。Noise2Noise图像去噪技术为我们提供了一种全新的解决方案…

第二十七章HTML.CSS综合案例

1.产品介绍 效果图如下&#xff1a; 代码部分如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

Elastic Search (ES)Java 入门实操(1)下载安装、概念

实现数据查询代码&#xff1a;Elastic Search&#xff08;ES&#xff09;Java 入门实操&#xff08;2&#xff09;搜索代码-CSDN博客 Elastic Search&#xff08;ES&#xff09;Java 入门实操&#xff08;3&#xff09;数据同步-CSDN博客 Elastic Search 官方描述&#xff0c…

Python下载库

注&#xff1a;本文一律使用windows讲解。 一、使用cmd下载 先用快捷键win R打开"运行"窗口&#xff0c;如下图。 在输入框中输入cmd并按回车Enter或点确定键&#xff0c;随后会出现这个画面&#xff1a; 输入pip install 你想下载的库名&#xff0c;并按回车&…

贰[2],VisionMaster/.NetCore的WPF应用程序调用控件

1&#xff0c;环境 VisionMaster4.2 VisualStudio2022 WPF/.Net6.0 2&#xff0c;记录原因 .NetFrameWork的WPF应用程序调用添加例程.NetFrameWork的Winform应用程序相应的库&#xff0c;不会出现报错&#xff0c;界面也能正常显示操作&#xff0c;但是.NetCore的程序却总是…

JavaScript入门宝典:核心知识全攻略(下)

文章目录 前言一、获取标签元素二、操作标签元素属性1. 属性的操作2. innerHTML 三、数组及操作方法1. 数组的定义2. 数组的操作 四、循环语句五、字符串拼接六、定时器1. 定时器的使用3. 清除定时器 七、ajax1. ajax的介绍2. ajax的使用 前言 JavaScript是前端开发不可或缺的技…

Typescript 中 tsconfig.json 无法写入文件,因为它会覆盖输入文件

先来看看问题 在开发ts项目的时候&#xff0c;包错提示无法写入文件 tsconfig.json无法写入文件"url"因为它会覆盖输入文件 这是tsconfig.json文件配置问题&#xff0c;需要加入下面的配置就好了&#xff1a; {"compilerOptions": {"outDir": …

【MySQL数据库】:MySQL索引特性

目录 索引的概念 磁盘 磁盘的基本特征 MySQL与磁盘交互的基本单位 索引的理解 建立测试表 理解单个Page 理解多个Page 页目录 单页情况 多页情况 索引的数据结构 聚簇索引 VS 非聚簇索引 索引操作 创建主键索引 创建唯一索引 创建普通索引 创建全文索引 查询…

海宁代理记账公司-专业的会计服务

随着中国经济的飞速发展&#xff0c;企业的规模和数量日益扩大&#xff0c;在这个过程中&#xff0c;如何保证企业的财务活动合规、准确无误地进行&#xff0c;成为了每个企业面临的重要问题&#xff0c;专业、可靠的代理记账公司应运而生。 海宁代理记账公司的主要职责就是为各…

Prism 入门06,发布订阅(入门完结)

本章节介绍使用 Prism 框架的消息聚合器 IEventAggregator ,实现如何进行消息发布,订阅,取消订阅的功能 继续使用上一章节使用的 Prism WPF 空模板项目 BlankApp1 1.首先,在使用 Prism 框架当中,进行事件消息的发布和订阅之前,需要定义发布事件的事件消息模型。如下所示:…

端午节景区视频监控方案:智慧景区EasyCVR视频监控系统构建与运用

端午节&#xff0c;作为中国传统节日之一&#xff0c;每年吸引着大量游客前往各地景区参观游览&#xff0c;感受浓厚的文化氛围。然而&#xff0c;随着游客数量的增多&#xff0c;景区管理也面临着越来越多的挑战&#xff0c;其中安全问题尤为突出。因此&#xff0c;实施端午节…

使用 ESPCN 模型进行超分辨率图像处理

前言 使用 ESPCN (Efficient Sub-Pixel CNN) 模型对低分辨率的图像&#xff0c;进行超分辨率处理。 效果展示 lowres 表示低分辨率图像&#xff0c;highres 表示高分辨率图像&#xff0c;prediction 表示模型预测的高分辨率图像&#xff0c;可以看出模型在生成高分辨率图像过…

力扣hot100:155. 最小栈(栈,辅助栈存储相关信息)

LeetCode&#xff1a;155. 最小栈 1、尝试单调栈 看到这题说&#xff0c;要常数时间内检索最小元素的栈&#xff0c;想到了单调栈&#xff0c;递增单调栈确实能维护最小值&#xff0c;但是这个最小值是存在一定意义的&#xff0c;即如果后面出现了最小值&#xff0c;那么前面…

光电管道液位传感器与电容式液位开关相比

如今&#xff0c;随着检测液位技术的不断发展&#xff0c;检测液位的方法也越来越多&#xff0c;比如浮球开关、电容式液位传感器、管道式液位传感器等等&#xff0c;那么光电管道液位传感器与电容式液位开关相比&#xff0c;有哪些优势&#xff1f; 光电管道液位传感器采用先…

论文高级图表绘制(Python语言,局部放大图)

本文将通过一个具体的示例,展示如何使用Python语言和Matplotlib库来绘制高级图表,包括局部放大图的制作。适用于多条曲线绘制在同一个图表中,但由于数据量过大,导致曲线的细节看不清,需要对细节进行局部放大。如下图: 环境准备 首先,确保你的Python环境中已经安装了以…

基于SSM+Jsp的高校信息资源共享平台

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

基于STM32开发的智能家居监控系统

目录 引言环境准备智能家居监控系统基础代码实现&#xff1a;实现智能家居监控系统 4.1 传感器数据读取4.2 电器设备控制4.3 实时数据监控与分析4.4 用户界面与数据可视化应用场景&#xff1a;家庭安全监控与管理问题解决方案与优化收尾与总结 1. 引言 随着智能家居技术的发…

FM151A,FM171B和利时工控

FM151A,FM171B和利时工控&#xff0c;DCS系统应该具备以下特点&#xff1a;1.系统具备开放的体系结构&#xff0c;可以提供多层的开放数据接口&#xff1b;FM151A,FM171B和利时工控。2.系统应具备强大的处理功能&#xff0c;中型分布式控制系统大型数据采集监控系统功能。FM151…

[数据集][目标检测]室内积水检测数据集VOC+YOLO格式761张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;761 标注数量(xml文件个数)&#xff1a;761 标注数量(txt文件个数)&#xff1a;761 标注类别…

使用小黄鸟(HttpCanary)、VMOS Pro虚拟机对手机APP进行抓包(附带软件)

老规矩先看&#xff0c;效果图&#xff1a; 文章很详细&#xff0c;希望可以耐心看完&#xff0c;保证可以学会抓包&#xff0c;不再走冤枉路&#xff0c;小编在之前看过太多类似文章&#xff0c;折腾了太久才搞懂的&#xff0c;写这篇文章就是不想希望你们像小编一样再花时间…