【数据结构与算法】迪杰斯特拉算法
迪杰斯特拉算法
介绍
迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。
算法过程
设置出发顶点为 v,顶点集合 V{v1,v2,v3…vi},v 到 V 中各顶点的距离构成距离集合 Dis,Dis{d1,d2,d3…di},Dis 集合记录着 v 到图中各顶点的距离(到自身可以看做 0,v 到 vi 举例对应为 di)
- 从 Dis 中选择值最小的 di 并移出 Dis 集合,同时移出 V 集合中对应的顶点 vi,此时的 v 到 vi 即为最短路径
- 更新 Dis 集合,更新规则为:比较 v 到 V 结合中顶点的距离值,与 v 通过 vi 到 V 集合中顶点的距离值,保留值最小的一个(同时也应该更新顶点的前驱节点为 vi,表明是通过 vi 到达的)
- 重复执行两步骤,直到最短路径顶点为目标顶点即可结束
迪杰斯特拉算法最佳应用 - 最短路径

- 战争时期,胜利乡有 7 个村庄(A,B,C,D,E,F,G),现在有六个邮差,从 G 点出发,需要分别把邮件分别送到 A,B,C,D,E,F 六个村庄
- 各个村庄的距离用边线表示(权),比如 A - B 距离 5 公里
- 问:如何计算出 G 村庄到其他各个村庄的最短距离?
- 如果从其他点出发到各个点的最短距离又是多少?
代码实现
public class DijkstraAlgorithm {public static void main(String[] args) {char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};// 邻接矩阵int[][] matrix = new int[vertex.length][vertex.length];final int N = 65535; // 表示不可连接matrix[0] = new int[]{N, 5, 7, N, N, N, 2};matrix[1] = new int[]{5, N, N, 9, N, N, 3};matrix[2] = new int[]{7, N, N, N, 8, N, N};matrix[3] = new int[]{N, 9, N, N, N, 4, N};matrix[4] = new int[]{N, N, 8, N, N, 5, 4};matrix[5] = new int[]{N, N, N, 4, 5, N, 6};matrix[6] = new int[]{2, 3, N, N, 4, 6, N};// 创建图Graph graph = new Graph(vertex, matrix);graph.showGraph();graph.dsj(6);graph.showDijkstra();}
}class Graph {private char[] vertex; // 顶点数组private int[][] matrix; // 邻接矩阵private VisitedVertex vv; // 已经访问的顶点的集合public Graph(char[] vertex, int[][] matrix) {this.vertex = vertex;this.matrix = matrix;}/*** 显示结果*/public void showDijkstra() {vv.show();}/*** 显示图*/public void showGraph() {for (int[] link : matrix) {System.out.println(Arrays.toString(link));}}/*** 迪杰斯特拉算法** @param index 表示出发顶点对应的下标*/public void dsj(int index) {vv = new VisitedVertex(vertex.length, index);update(index); // 更新 index 顶点到周围顶点的距离和前驱顶点for (int j = 1; j < vertex.length; j++) {index = vv.updateArr(); // 选择并返回新的访问节点update(index); // 更新 index 顶点到周围顶点的距离和前驱顶点}}/*** 更新 index 下标顶点到周围顶点的距离和周围定额点的前驱顶点** @param index*/private void update(int index) {int len = 0;// 根据遍历我们的邻接矩阵的 matrix[index] 行for (int j = 0; j < matrix[index].length; j++) {// len 含义是:出发顶点到 index 顶点的距离 + 从 index 顶点到 j 顶点的距离的和len = vv.getDis(index) + matrix[index][j];// 如果 j 顶点没有被访问过,并且 len 小于出发顶点到 j 顶点的距离,就需要更新if (!vv.in(j) && len < vv.getDis(j)) {vv.updatePre(j, index); // 更新 j 顶点的前驱为 index 顶点vv.updateDis(j, len); // 更新出发顶点到 j 顶点的距离}}}
}// 已访问顶点集合
class VisitedVertex {// 记录各个顶点是否访问过 1 表示访问过,0 表示未访问,会动态更新private int[] already_arr;// 每个下标对应的值为前一个顶点下标,会动态更新private int[] pre_visited;// 记录出发顶点到其他所有顶点的距离,比如 G 为出发顶点,就会记录 G 到其他顶点的距离,会动态更新,求的最短距离就会存放到 disprivate int[] dis;/*** 构造器初始化** @param length 表示顶点的个数* @param index 出发顶点对应的下标*/public VisitedVertex(int length, int index) {this.already_arr = new int[length];this.pre_visited = new int[length];this.dis = new int[length];// 初始化 disArrays.fill(dis, 65535);this.already_arr[index] = 1; // 设置出发顶点被访问过this.dis[index] = 0; // 设置出发顶点的访问距离为 0}/*** 判断 index 顶点是否被访问过** @param index 顶点下标* @return 如果访问过,就返回 true,否则 返回 false*/public boolean in(int index) {return already_arr[index] == 1;}/*** 更新出发顶点得到 index 顶点的距离** @param index 顶点下标* @param len 长度(距离)*/public void updateDis(int index, int len) {dis[index] = len;}/*** 更新 pre 顶点的前驱顶点为 index 顶点** @param pre 要更新的顶点* @param index 跟新顶点*/public void updatePre(int pre, int index) {pre_visited[pre] = index;}/*** 返回出发顶点到 index 顶点的距离** @param index 顶点*/public int getDis(int index) {return dis[index];}/*** 继续选择并返回新的访问顶点** @return*/public int updateArr() {int min = 65535, index = 0;for (int i = 0; i < already_arr.length; i++) {if (already_arr[i] == 0 && dis[i] < min) {min = dis[i];index = i;}}// 更新 index 顶点被访问过already_arr[index] = 1;return index;}/*** 显示最后的结果* 即将三个数组的情况输出*/public void show() {System.out.println("=======================================");// 输出 already_arrfor (int i : already_arr) {System.out.print(i + " ");}System.out.println();// 输出 pre_visitedfor (int i : pre_visited) {System.out.print(i + " ");}System.out.println();// 输出 disfor (int i : dis) {System.out.print(i + " ");}System.out.println();char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};int count = 0;for (int i : dis) {if (i != 65535) {System.out.print(vertex[count] + "(" + i + ") ");} else {System.out.println("N ");}count++;}}
}
相关文章:
【数据结构与算法】迪杰斯特拉算法
迪杰斯特拉算法 介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。 算法过程 设置…...
python爬虫-网页数据提取
import requests #headers 网页右键->Network->最下面的User-Agent复制。 headers {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"} #你想要的网址 url &q…...
ZigBee的Many-to-One和Source Routing
1. Many-to-One Routing Many-to-One Routing,是一种简单的路由机制,使得整个网络中的路由设备拥有回到中心节点的路由。 在这种机制下,中心节点周期性发送Many-to-One route discovery广播(协议栈默认设置为60s,可以…...
七夕节 Chinese Valentine‘s Day 的由来
农历七月初七是七夕节。Qixi Festival falls on the seventh day of the seventh lunar month. 以前有一个牛郎,和他的哥哥和嫂子住在一起。他放的一头牛曾经是天庭的一个神仙,但他违反天庭的戒律,变成牛放到了人间。As the story goes,once …...
掌握JDK21全新结构化并发编程,轻松提升开发效率!
1 概要 通过引入结构化并发编程的API,简化并发编程。结构化并发将在不同线程中运行的相关任务组视为单个工作单元,从而简化错误处理和取消操作,提高可靠性,并增强可观察性。这是一个预览版的API。 2 历史 结构化并发是由JEP 42…...
【SA8295P 源码分析】00 - 系列文章链接汇总 - 持续更新中
【SA8295P 源码分析】00 - 系列文章链接汇总 - 持续更新中 一、分区、下载、GPIO等杂项相关二、开机启动流程代码分析二、OpenWFD 显示屏模块三、Touch Panel 触摸屏模块四、QUPv3 及 QNX Host透传配置五、Camera 摄像头模块(当前正在更新中...)六、网络…...
TCP拥塞控制详解 | 6. 主动队列管理
网络传输问题本质上是对网络资源的共享和复用问题,因此拥塞控制是网络工程领域的核心问题之一,并且随着互联网和数据中心流量的爆炸式增长,相关算法和机制出现了很多创新,本系列是免费电子书《TCP Congestion Control: A Systems …...
前端学习清单
顺序不分先后。 技术名称技术描述技术链接HTML5HTML5是下一代的HTML标准,是一种用于结构化内容的标记语言。MDN|HTMLCSS3CSS3是CSS技术的升级版本,它的最大好处就是可以让网页设计师更加方便的为网页添加各种各样的样式,而不用再局限于文字、…...
go atomic原子操作详细解读
文章目录 概要1、基本知识1.1 原子操作是什么1.2 CPU怎么实现原子操作的? 2、atomic包2.1、 Add函数2.2、CompareAndSwap函数2.3、Swap函数2.4、Load函数2.5、Store函数 3、atomic.Value值 概要 atomic包是golang通过对底层系统支持的原子操作进行封装,…...
Vue用JSEncrypt对长文本json加密以及发现解密失败
哈喽 大家好啊,最近发现进行加密后 超长文本后端解密失败,经过看其他博主修改 JSEncrypt原生代码如下: // 分段加密,支持中文JSEncrypt.prototype.encryptUnicodeLong function (string) {var k this.getKey();//根据key所能编…...
Excel/PowerPoint折线图从Y轴开始(两侧不留空隙)
默认Excel/PowerPoint折线图是这个样子的: 左右两侧都留了大块空白,很难看 解决方案 点击横坐标,双击,然后按下图顺序点击 效果...
C++的类成员对齐
这是个小语法点,之前我们的对齐方式都是使用#pragma pack,这个方式实际是依赖编译器,且粒度粗(如果#pragma pack(1)之后没有#pragma pack(),那就作用整个进程了)。在C11之后引入关键字alignas,以此来实现对齐更加便利,…...
敏感挂载userhelper容器逃逸复现
目录 前言 分析 实验 前言 分析 实验 # Creates a payload cat "#!/bin/sh" > /evil-helper cat "ps > /output" >> /evil-helper chmod x /evil-helper # Finds path of OverlayFS mount for container # Unless the configuration ex…...
深度解读Promise.prototype.finally
由一个问题引发的血案: 手写源码实现Promise.prototype.finally。 我们知道,对于promise来讲,当状态敲定,无论状态兑现或拒绝时都需要调用的函数,可以使用Promise.prototype.finally的回调来实现。那么如何手写实现Pro…...
如何实现24/7客户服务自动化?建设智能客服知识库
客户自助服务是指用户通过企业或者第三方建立的网络平台或者终端,实现相关的自定义处理。实现客户服务自动化,对提高客户满意度、维持客户关系至关重要。客户服务自动化可以帮助企业以更快的速度和更高的效率来满足客户的售后服务要求,以进一…...
和鲸 ModelWhale 与中科可控多款服务器完成适配认证,赋能中国云生态
当前世界正处于新一轮技术革命及传统产业数字化转型的关键期,云计算作为重要的技术底座,其产业发展与产业规模对我国数字经济的高质量运行有着不可取代的推动作用。而随着我国数字上云、企业上云加快进入常规化阶段,云计算承载的业务应用越来…...
selenium +Jmeter 的性能测试
通过Jmeter快速将已有的Selenium 代码以性能测试的方式组织起来,并使用JMeter 丰富的报表展示测试结果 from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By driver …...
探索高效的HTTP异步接口测试方法:从轮询等待到自动化方案
本文将深入探讨HTTP异步接口测试的多个方面,包括轮询等待、性能测试以及自动化方案。通过详细的解释和实际案例,帮助您了解如何有效地测试异步接口,确保系统的稳定性和性能。 在现代软件开发中,HTTP异步接口扮演着至关重要的角色&…...
Android资深工程书之LiveData核心组件原理剖析
LiveData是Android架构组件库中的一个类,用于在应用程序组件之间共享数据。它是一种可观察的数据持有者,可以感知应用程序组件的生命周期,并在数据发生变化时通知观察者。 使用LiveData 在Android应用程序中使用LiveData,你可以…...
Vue的五种方法实现加减乘除运算
五种方法的详细说明: 计算属性(Computed Properties): 计算属性是Vue.js提供的一种便捷的属性,它根据依赖的数据动态计算出一个新的值。计算属性的值会被缓存,只有当依赖的数据发生变化时,才会…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
