Dijkstra算法——邻接矩阵实现+路径记录

本文是在下面这篇文章的基础上做了一些补充,增加了路径记录的功能。具体Dijkstra的实现过程可以参考下面的这篇文章。
[jarvan:Dijkstra算法详解 通俗易懂](Dijkstra算法详解 通俗易懂 - jarvan的文章 - 知乎
https://zhuanlan.zhihu.com/p/338414118)

创建 GraphAdjMat 类
GraphAdjMat 类用来实现图的邻接矩阵,方便后续的测试,具体代码如下:

package algorithm.graph;import java.util.ArrayList;
import java.util.List;public class GraphAdjMat {private List<Integer> vertices;private List<List<Integer>> adjMat;/*** 构造函数* @param vertices 顶点列表* @param edges 边*/public GraphAdjMat(int[]vertices, int[][]edges) {this.vertices = new ArrayList<>();this.adjMat = new ArrayList<>();for(int v : vertices) {addVertex(v);}for(int[]e : edges) {addEdge(e[0],e[1],e[2]);}//设置顶点自己到自己的权重为0for(int i=0; i<vertices.length; i++) {this.adjMat.get(i).set(i, 0);}}public List<List<Integer>> getAdjMat() {return this.adjMat;}/*** 添加顶点*/public void addVertex(int val) {int n = vertices.size();vertices.add(val);List<Integer> newRow = new ArrayList<>();for(int i=0; i<n; i++) {newRow.add(-1);}adjMat.add(newRow);for(List<Integer> row : adjMat) {row.add(-1);}}/*** 移除顶点*/public void removeVertex(int index) {if(index < 0 || index >= vertices.size()) {throw new IndexOutOfBoundsException();}vertices.remove(index);adjMat.remove(index);for(List<Integer> row : adjMat) {row.remove(index);}}/*** 添加边* @param i 顶点1* @param j 顶点2* @param weight 边权重*/public void addEdge(int i, int j, int weight) {if(i<0||j<0||i>=vertices.size()||j>=vertices.size()||i==j) {throw new IndexOutOfBoundsException();}adjMat.get(i).set(j, weight);adjMat.get(j).set(i, weight);}/*** 移除边*/public void removeEdge(int i, int j) {if(i<0||j<0||i>=vertices.size()||j>=vertices.size()||i==j) {throw new IndexOutOfBoundsException();}adjMat.get(i).set(j, -1);adjMat.get(j).set(i, -1);}public void print() {System.out.println("adj mat:");for(List<Integer> row : adjMat) {for(int v : row) {System.out.printf("%3d", v);}System.out.println();}}}

GraphAdjMat 类中提供了增加顶点、移除顶点、增加边和移除边的操作。
创建 DijkstraAlg 类
该类用于实现 Dijkstra 算法,并打印指定点到所有点的最短距离和路径信息

package algorithm.graph;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** Dijkstra 算法*/
public class DijkstraAlg {public static void main(String[]args) {char[]vertexNames = {'A','B','C','D'};int[]vertices = {1,2,3,4};int[][]edges = {{0,1,1},{0,3,6},{1,2,4},{1,3,1},{2,3,1}};//构建邻接矩阵GraphAdjMat adjMat = new GraphAdjMat(vertices, edges);adjMat.print();int startVertex = 0;List<ShortestPath> result = dijkstra(adjMat.getAdjMat(),startVertex);System.out.println("dijkstra result: ");for(int i=0; i<vertexNames.length; i++) {System.out.printf("%3s -> %s distence : %d ; ",vertexNames[startVertex], vertexNames[i], result.get(i).distence);List<Integer> path = result.get(i).path;System.out.print("A -> ");for(int j=0; j<path.size(); j++) {if(j < path.size()-1) {					System.out.printf("%s -> ",vertexNames[path.get(j)]);}else {System.out.printf("%s\n", vertexNames[path.get(j)]);}}}}public static List<ShortestPath> dijkstra(List<List<Integer>> graph, int startVertex) {int len = graph.size();List<ShortestPath> result = new ArrayList<>(len);int[]notFound = new int[len];//初始化 resultfor(int i=0; i<len; i++) {ShortestPath shortestPath = new ShortestPath();shortestPath.distence = -1;shortestPath.path = new ArrayList<>();result.add(i, shortestPath);}ShortestPath startVertexPath = new ShortestPath();startVertexPath.distence = 0;startVertexPath.path = new ArrayList<>(0);result.set(startVertex,startVertexPath);//初始化 notFoundfor(int i=0; i<len; i++) {notFound[i] = graph.get(startVertex).get(i);}notFound[startVertex] = -1;//开始 Dijkstra 算法Map<Integer,List<Integer>> recordPathMap = new HashMap<>();for(int i=1; i<len; i++) {int min = Integer.MAX_VALUE;int minIndex = 0;for(int j=0; j<len; j++) {if(notFound[j] > 0 && notFound[j] < min) {min = notFound[j];minIndex = j;}}result.get(minIndex).distence = min;notFound[minIndex] = -1;//刷新 notFoundfor(int j=0; j<len; j++) {//graph.get(minIndex).get(j) > 0 用来确保 minIndex 顶点有边,result[j] == -1 用来确保 j 点没有在结果集中if(graph.get(minIndex).get(j) > 0 && result.get(j).distence == -1) {int newDistence = result.get(minIndex).distence + graph.get(minIndex).get(j);//计算合并距离如果小于直接到j点的距离,或者无法到达j点事将新距离刷新到notFound中if(newDistence < notFound[j] || notFound[j] == -1) {notFound[j] = newDistence;if(!recordPathMap.containsKey(j)) {List<Integer> tempList = new ArrayList<>(1);tempList.add(minIndex);recordPathMap.put(j, tempList);}else {							recordPathMap.get(j).add(minIndex);}}}}}System.out.println(recordPathMap);//推到路径for(int i=0; i<len; i++) {result.get(i).path.addAll(recordPathMap.getOrDefault(i, new ArrayList<>()));result.get(i).path.add(i);}return result;}public static void printArr(int[]arr, String arrName) {System.out.print(arrName);for(int i : arr) {System.out.printf("%3d", i);}System.out.println();}static class ShortestPath {public int distence;public List<Integer> path;}
}

代码在原文代码的基础上通过增加 recordPathMap 来记录最短路径,最终打印最短路径距离和对应路劲信息。
在这里插入图片描述

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

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

相关文章

谷歌提出「边界注意力」模型,实现超越像素级检测精度!微弱边界也逃不过

有些情况下&#xff0c;当面临分辨率较低的图像时&#xff0c;可能会在进行诸如目标检测和图像分割等任务时遇到一些挑战和阻碍。这是因为低分辨率图像可能丢失了细节信息&#xff0c;使得计算机视觉系统难以准确捕捉和理解图像中的关键特征。在这种背景下&#xff0c;传统的方…

教程:Centos6迁移旧虚拟机文件后的网络配置教程,完美解决虚拟机移动后的网络ip变化问题

博主在工作后,想整整之前大学的虚拟机集群,因此特意从之前的旧电脑把虚拟机文件给拷贝了过来,在导入到vm-workstation,顺便能启动虚拟机后,发现之前的静态ip已经跟现在的宿主机网络不一样。想着重新配置,但觉得太麻烦,故想到了修改网卡的mac地址+网卡重配置方法,完美解…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -后端架构搭建

锋哥原创的uniapp微信小程序投票系统实战&#xff1a; uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

普中STM32-PZ6806L开发板(有点悲伤的故事续-人灯还未了)

简介 继上篇 普中STM32-PZ6806L开发板(有点悲伤的故事) 说到 关于 普中STM32-PZ6806L开发板的LED流水灯也被烧坏掉了&#xff0c;再也无法玩流水灯, 内心充满了只会流水灯的不甘, 流水灯就是单片机的Hello World&#xff0c;怎么能没有呢&#xff1f; 事情发展 好巧不巧想起最近…

报错解决:RuntimeError: Error building extension ‘bias_act_plugin‘

系统&#xff1a; Ubuntu22.04&#xff0c; nvcc -V&#xff1a;11.8 &#xff0c; torch&#xff1a;2.0.0cu118 一&#xff1a;BUG内容 运行stylegan项目的train.py时遇到报错&#x1f447; Setting up PyTorch plugin "bias_act_plugin"... Failed! /home/m…

【linux】tcpdump 使用

tcpdump 是一个强大的网络分析工具&#xff0c;可以在 UNIX 和类 UNIX 系统上使用&#xff0c;用于捕获和分析网络流量。它允许用户截取和显示发送或接收过网络的 TCP/IP 和其他数据包。 一、安装 tcpdump 通常是默认安装在大多数 Linux 发行版中的。如果未安装&#xff0c;可…

每天刷两道题——第十天

1.1和为k的子数组 给你一个整数数组 n u m s nums nums 和一个整数 k k k &#xff0c;请你统计并返回 该数组中和为 k k k 的子数组的个数 。子数组是数组中元素的连续非空序列。 输入&#xff1a;nums [1,2,3], k 3 输出&#xff1a;2 前缀和 1.2如何使用 前缀和的…

Jmeter扩展函数?年薪50W+的测试大佬教你怎么玩

很多同学&#xff0c;都问我&#xff1a;“老师&#xff0c;我的 jmeter 里面&#xff0c;怎么没有 MD5 函数&#xff0c;base64 函数也没有&#xff0c;我是不是用了假的 jmeter&#xff1f;” 前言 哈哈哈&#xff0c;不是的。jmeter 的函数&#xff0c;有自带函数和扩展函数…

pycharm调整漂亮的颜色主题

主题样式&#xff1a; 一、设置主题为白色 二、pycharm 如何设置字体颜色 打开pycharm编辑器&#xff0c;file > settings > editor > color scheme > python > 你也可以直接用我资源中的配置好的文件

汽车中的ECU、VCU、MCU、HCU

一、ECU是汽车电脑&#xff0c;刷汽车电脑可以提高动力&#xff0c;也可以减低动力&#xff0c;看需求。 简单原理如下。 1.汽车发动机运转由汽车电脑&#xff08;即ECU&#xff09;控制。 2.ECU控制发动机的进气量&#xff0c;喷油量&#xff0c;点火时间等&#xff0c;从而…

基础数据结构第九期 堆(数组+STL)

前言 堆是一种重要的数据结构&#xff0c;因此应该熟练掌握。 一、堆的基本概念 堆的基本&#xff1a; 堆的结构实际上是一棵完全二叉树&#xff0c;堆可以分为大根堆和小根堆 大根堆&#xff1a; 小根堆&#xff1a; 堆的储存&#xff1a; 若节点小标为i&#xff0c;则左子…

竞赛保研 基于深度学习的人脸性别年龄识别 - 图像识别 opencv

文章目录 0 前言1 课题描述2 实现效果3 算法实现原理3.1 数据集3.2 深度学习识别算法3.3 特征提取主干网络3.4 总体实现流程 4 具体实现4.1 预训练数据格式4.2 部分实现代码 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 毕业设计…

list容器

list容器 文章目录 list容器一、头文件二、基本概念三、构造函数四、赋值和交换五、大小操作六、插入和删除七、存取操作八、反转和排序 一、头文件 #include <list>二、基本概念 功能: 将数据进行链式存储 链表(list) 是一种物理存储单元上非连续的存储结构,数据元素的…

Python 简单爬虫程序及其工作原理

前言 网络中包含大量的数据&#xff0c;这些数据对于我们来说是非常有价值的&#xff0c;因此编写一个爬虫程序&#xff0c;自动从网页中获取所需的数据&#xff0c;对于信息收集和分析是非常有帮助的。Python 是一种高效而灵活的编程语言&#xff0c;它提供了强大的库和框架来…

Redis(三)持久化

文章目录 RDB&#xff08;Redis Database&#xff09;自动触发保存频率修改dump文件保存路径修改文件保存名称dump恢复 手动触发save![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a56fdff44aee4efa96c2ce3615b69dc1.png)bgsave 优劣优点缺点 检查修复dump文件会触…

25 心形按钮

效果演示 实现了一个心形的心形图案&#xff0c;当用户点击图案时&#xff0c;图案会旋转并缩小&#xff0c;同时背景颜色会变成白色。 Code <div class"love"><input id"switch" type"checkbox"><label class"love-heart&…

Pytorch种torch.cat与torch.stack的区别

torch.cat 和 torch.stack 是 PyTorch 中用于拼接张量的两个不同的函数&#xff0c;它们的主要区别在于拼接的方式和创建的维度。 torch.cat&#xff1a; 拼接方式&#xff1a; torch.cat 是按照给定的维度&#xff08;dim 参数&#xff09;将多个张量沿着该维度拼接。在拼接的…

Django Web框架

1、创建PyCharm项目 2、安装框架 pip install django4.2.0 3、查看安装的包列表 4、使用命令创建django项目 django-admin startproject web 5、目录结构 6、运行 cd web python manage.py runserver7、初始化后台登录的用户名密码 执行数据库迁移生成数据表 python man…

代码随想录刷题题Day29

刷题的第二十九天&#xff0c;希望自己能够不断坚持下去&#xff0c;迎来蜕变。&#x1f600;&#x1f600;&#x1f600; 刷题语言&#xff1a;C Day29 任务 ● 01背包问题&#xff0c;你该了解这些&#xff01; ● 01背包问题&#xff0c;你该了解这些&#xff01; 滚动数组 …