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.mzph.cn/news/607782.shtml

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

相关文章

安卓adb

目录 如何开启 ADB 注意事项 如何使用 ADB ADB 能干什么 ADB&#xff08;Android Debug Bridge&#xff09;是一个多功能命令工具&#xff0c;它可以允许你与 Android 设备进行通信。它提供了多种设备权限&#xff0c;包括安装和调试应用&#xff0c;以及访问设备上未通过…

HarmonyOS应用开发者基础认证考试

判断题 1.Ability是系统调度应用的最小单元,是能够完成一个独立功能的组件。一个应用可以包含一个或多个Ability。 正确(True) 2.所有使用Component修饰的自定义组件都支持onPageShow,onBackPress和onPageHide生命周期函数。 错误(False) 3.每调用一次router.pushUrl()方法,…

Cocos Creator 3.8 开发2D水面波纹Shader

使用cocos Creator 3.8做了一个游戏开中常用的2D的波浪水面,把技术点给记录一下&#xff0c;并提供完整的Shader代码。先上效果: 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 2D 波浪的基本技术原理 2D 水面波纹的主要原理就是给定一个正选波的边界&…

基于 SpringBoot + magic-api + Vue3 + Element Plus + amis3.0 快速开发管理系统

Tansci-Boot 基于 SpringBoot2 magic-api Vue3 Element Plus amis3.0 快速开发管理系统 Tansci-Boot 是一个前后端分离后台管理系统&#xff0c; 前端集成 amis 低代码前端框架&#xff0c;后端集成 magic-api 的接口快速开发框架。包含基础权限、安全认证、以及常用的一…

2020年认证杯SPSSPRO杯数学建模D题(第二阶段)让电脑桌面飞起来全过程文档及程序

2020年认证杯SPSSPRO杯数学建模 D题 让电脑桌面飞起来 原题再现&#xff1a; 对于一些必须每天使用电脑工作的白领来说&#xff0c;电脑桌面有着非常特殊的意义&#xff0c;通常一些频繁使用或者比较重要的图标会一直保留在桌面上&#xff0c;但是随着时间的推移&#xff0c;…

搭建LNMP网站平台并部署Web应用

本章主要介绍&#xff1a; 安装Nginx安装MySQL安装PHP在LNMP平台中部署 Web 应用 构建LNMP网站平台就像构建LAMP平台一样&#xff0c;构建LNMP平台也需要Linux服务器&#xff0c;MySQL数据库&#xff0c;PHP解析环境&#xff0c;区别主要在Nginx 与 PHP的协作配置上&#xff0…

Spring 应用上下文探秘:生命周期解析与最佳实践

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Spring 应用上下文探秘&#xff1a;生命周期解析与最佳实践 前言应用上下文的初始化过程1. 应用上下文的初始化过程&#xff1a;2. 不同类型的 ApplicationContext 初始化流程&#xff1a;2.1 Annotat…

湖南大学-数据库系统-2018期末考试解析

【写在前面】 这是2018年的卷子&#xff0c;复习备考的时候做了并与同学校对了答案。答案仅供参考。这张难度不大&#xff0c;同样的&#xff0c;跟前几张差不了太多。但是从这一年开始&#xff0c;选择题变成了15道&#xff0c;越来越贴切近几年的考试了。 一、单选题&#xf…

HTML JavaScript 康威生命游戏

<!DOCTYPE html> <html> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>康威生命游戏</title><style>body {font-family: Arial, sa…

JS-基础语法(一)

JavaScript简单介绍 变量 常量 数据类型 类型转换 案例 1.JavaScript简单介绍 JavaScript 是什么&#xff1f; 是一种运行在客户端&#xff08;浏览器&#xff09;的编程语言&#xff0c;可以实现人机交互效果。 JS的作用 JavaScript的组成 JSECMAScript( 基础语法 )…

每日算法打卡:分巧克力 day 9

文章目录 原题链接题目描述输入格式输出格式数据范围输入样例&#xff1a;输出样例&#xff1a; 题目分析示例代码 原题链接 1227. 分巧克力 题目难度&#xff1a;简单 题目来源&#xff1a;第八届蓝桥杯省赛C A/B组,第八届蓝桥杯省赛Java A/B/C组 题目描述 儿童节那天有 …

流程挖掘在优化核心业务、增强可见性和提升自动化方面的三重效应

在过去二十年里&#xff0c;流程挖掘技术已由最初的学术理念演变成一种成熟的软件基础工具&#xff0c;它致力于流程的可视化、深度分析及其优化。传统的手动流程改进方法往往会受到主观偏见和误差的干扰&#xff0c;而流程挖掘技术则通过结合流程建模与数据挖掘手段&#xff0…

mysql 优化工具 EXPLAIN详解

EXPLAIN 是 MySQL 中用于查看查询执行计划的关键字&#xff0c;通过 EXPLAIN 可以了解 MySQL 优化器是如何选择执行查询的。EXPLAIN 的输出信息包括了许多字段&#xff0c;其中一些关键的字段和类别如下&#xff1a; id&#xff1a; 查询的标识符&#xff0c;用于标识查询执行计…

【2024系统架构设计】 系统架构设计师第二版-嵌入式系统架构设计理论与实践

目录 一 嵌入式系统软件架构的原理 二 嵌入式系统软件架构的设计方法 三 案例分析 一 嵌入式系统软件架构的原理 🚀嵌入式系统的典型架构可以分为

java.lang.ClassNotFoundException: jakarta.servlet.Servlet

联系servlet的使用时&#xff0c;编写了servlet的处理器&#xff0c;但是浏览器报500错误&#xff0c;有时候是404错误 WebServlet("/mayikt") public class Servlet1 implements Servlet {Overridepublic void init(ServletConfig servletConfig) throws ServletExc…

MySQL5.7 InnoDB 磁盘结构之索引Index

官网地址&#xff1a;MySQL :: MySQL 5.7 Reference Manual :: 14.6.2.1 Clustered and Secondary Indexes 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. MySQL 5.7 参考手册 / ... / 聚集索引和二级索引 14…

C++实现简单贪吃蛇游戏

文章目录 1 开发历程2 开发思路3 使用介绍4 源文件代码5 游戏截图6 小结 1 开发历程 游戏使用C语言开发&#xff0c;是博主某个下午心血来潮的结果&#xff0c;后面又花了点时间加了计分&#xff0c;记录历史得分的功能。 2 开发思路 其实贪吃蛇主要难在蛇身的移动上&#x…

AWS IoT Core 实战指南

Amazon Web Services (AWS) 提供了全球范围内的托管服务,其中包括 AWS IoT Core,专为连接和管理物联网设备而设计。这个实战指南将带你一步步了解如何使用 AWS IoT Core 来注册设备、提高安全性、进行通信以及利用设备影子功能。 设备注册 1. 创建 Thing(设备) 在 AWS I…

cocos creator 如何绑定参数到编辑器

很多cocos creator同学不知道如何绑定组件属性到编辑器上&#xff0c;今天我们来教大家如何绑定 1: 基本数据属性绑定到编辑器 这个非常简单&#xff0c;模板是属性名字: 默认的值; Is_debug: false, speed: 100, 2: 系统组件类型与节点绑定到编辑器 属性名字: { type: 组件…

App更换图标

App更换图标 京东淘宝的每到618或者双十一的时候&#xff0c;app图标都会贴合相关主题更换一下&#xff0c;但是那个时间段app也没有升级&#xff0c;所以说肯定是有一个配置能够更改app的图标。 查了一些文档&#xff0c;发现了如下的方法。 准备图片 准备120x120和180x18…