【数据结构与算法】java有向带权图最短路径算法-Dijkstra算法(通俗易懂)

目录

  • 一、什么是Dijkstra算法
  • 二、算法基本步骤
  • 三、java代码
  • 四、拓展(无向图的Dijkstra算法)

一、什么是Dijkstra算法

Dijkstra算法的核心思想是通过逐步逼近的方式,找出从起点到图中其他所有节点的最短路径。算法的基本步骤如下:

举个例子:

在这里插入图片描述

如图所示的V1-V6六个点及他们的有向权重连线,现在我们假设从V1点出发,画出从顶点V1到其余各点最短路径的过程:

首先,我们将V1拿出来,V1能通向V2和V3,V1到V1的距离我们可以看成0,V1到V2的距离是10,V1到V3的距离是12,V1不能直接到达V4,V5,V6,我们可以看成是无穷大,那么V1的上一个结点是V1,V2和V3的上一个结点也是V1。V4,V5,V6此是没有连接结点记为-1,得到如下表格

在这里插入图片描述

然后根据距离数组{0,10,12,∞,∞,∞},找出数组中距离最小的值,即V2的10,我们将V2拿出来放到数组S中,则数组V中还剩余{V3,V4,V5,V6},现在我们取出了V1,V2;V1到V1和V2的位置还是没有变,取出V2后,V1到V3没有新的通路,所以距离还是12,所以V3的上一个点还是V1;V4和V5是可以根据V2进行跟新的,V4=10+16=26,V5=10=25=35,我们取出了V1,V2,到V6还是没有路线可以走,所以更新之后的表格如下:

在这里插入图片描述

我们距离数组{0,10,12,26,35,∞}中,选取最小值,即12的V3结点加入数组S中,数组V为{V4,V5,V6},现在加入的结点为V1、V2、V3,现在V1到V2的路线多出来V1-V3-V2,但是总长度是15比原本的10要大啊,所以不做变化,V1到V3的距离还是12,V1-V4有两条路(V1-V2-V4)和(V1-V3-V4)跟新后的V1-V3-V4距离是24比原来的26更短,所以替换之,然后V4上一个点的坐标就变成了V3,我们再看一下V1-V5,(V1-V2-V5)和(V1-V3-V2-V5)显然还是原本的35是最短距离;V1-V6的路径是(V1-V3-V6)距离是20,更新表格:

在这里插入图片描述

我们在数组{0,10,12,24,35,20}可以看出在去掉V1、V2、V3之后最小的点是V6的20,所以我们将V6加入到数组S中,V1到V1、V2、V3的距离保持不变;V1到V4的,因为增加了V6,所以多出来一条V1-V3-V6-V4,距离是22,比之前的24小,进行更新,所以V4的上一个结点变成V6;然后V1到V5,多增加路线V1-V3-V6-V5,总体距离变成30,比之前的35要小,更新表格,V5的上一个结点变成V6,跟新后的表格:

在这里插入图片描述

从数组V中取出距离最短的值V4放入数组S中,此时,V1到V1、V2、V3、V4的距离保持不变,V1-V5的距离多了一条V1-V3-V6-V4-V5,路径从29比以前的30要短,更新表格,所以V5的上一个结点的V4,V1-V6保持不变,更新后表格如下:

在这里插入图片描述
将最后一个点V5添加到数组S中,V5没有到其他点的新路径,所以dist[]和path[]数组不变。

如果想要知道V1到V6的距离:

先看path[],V6的上一个结点时V3,V3的上一个结点是V1,所以V1到V6的路径是V1-V3-V6;由dist[]数组得知距离权重是20;

如果想要知道V1到V5的距离:

先看path[],V5的上一个结点时V4,V4的上一个结点时V6,V6的上一个结点时V3,V3的上一个结点是V1,所以V1到V5的路径是V1-V3-V6-V4-V5;由dist[]数组得知距离权重是29;

其他的以此类推;

二、算法基本步骤

  1. 初始化:
  • 创建一个最短路径信息数组shortPath[x][3],每一个一维数组含义为当前结点、该节点到此节点的最短路径、起始节点。
  • 初始化shortPath数组,shortPath[x][0]当前节点编号、shortPath[x][1]最短路径、shortPath[x][2]起始结点编号
  • 初始化优先队列,将起始节点的所有邻接点加入到优先队列中,结点信息使用Ownership类,属性值{time、nodeIndex、weight}。
  • 创建优先队列,优先队列按照结点的权重值优先出队 PriorityQueue。
  • 创建优先队列的比较器OwnershipCustomerComparator类,通过weight大小进行优先出队。
  1. 流程:
  • 优先队列为空则退出
  • 遍历优先队列,将队列中time版本对应的结点信息值写入shortPath中。每次拿到最新路径长度newWeight=matrix[up - 1][ownership.nodeIndex] + shortPath[up - 1][1](起始节点最短路径+起始节点到当前节点一条边的权重),如果当前结点未被初始化则直接将newWeight写入shortPath数组中,如果当前节点已经被写过最短路径,则直接略过当前newWeight即可,这里有一个dtx变量,记录当前优先队列中结点是否被写如果shortPath,用于time(版本)。
  • 遍历优先队列(需要出队),将权重最小的结点出队,将该节点下的所有邻接点拿出做以下操作步骤:
    • 需要是出对节点的邻接点
    • 邻接点在shortPath表中的最短路径未被初始化(还是无穷大),将结点信息写入,最短路径为出对节点权重+出对节点到达该邻接点的权重
    • 查看该邻接点是否出现在优先队列中。在优先队列中则更新shortPath数组以及优先队列中该结点的权重以及起始节点的信息。
    • 优先队列中没有,Math.min(newWeight, shortPath[i][1]),取最优路径写入

三、java代码

代码地址:GitHub

算法代码:

public class Dijkstra {private Queue visited;int[] distance;public Dijkstra(int len) {// TODO Auto-generated constructor stubvisited = new LinkedList();distance = new int[len];}private int getIndex(Queue q, int[] dis) {int k = -1;int min_num = Integer.MAX_VALUE;for (int i = 0; i < dis.length; i++) {if (!q.contains(i)) {if (dis[i] < min_num) {min_num = dis[i];k = i;}}}return k;}public void dijkstra(int[][] weight, Object[] str, int v) {HashMap path;path = new HashMap();for (int i = 0; i < str.length; i++)path.put(i, "");//初始化路径长度数组distancefor (int i = 0; i < str.length; i++) {path.put(i, path.get(i) + "" + str[v]);if (i == v)distance[i] = 0;else if (weight[v][i] != -1) {distance[i] = weight[v][i];path.put(i, path.get(i) + "-->" + str[i]);} elsedistance[i] = Integer.MAX_VALUE;}visited.add(v);while (visited.size() < str.length) {int k = getIndex(visited, distance);//获取未访问点中距离源点最近的点visited.add(k);if (k != -1) {for (int j = 0; j < str.length; j++) {//判断k点能够直接到达的点if (weight[k][j] != -1) {//通过遍历各点,比较是否有比当前更短的路径,有的话,则更新distance,并更新path。if (distance[j] > distance[k] + weight[k][j]) {distance[j] = distance[k] + weight[k][j];path.put(j, path.get(k) + "-->" + str[j]);}}}}}for (int h = 0; h < str.length; h++) {System.out.printf(str[v] + "-->" + str[h] + ":" + distance[h] + " ");if (distance[h] == Integer.MAX_VALUE)System.out.print(str[v] + "-->" + str[h] + "之间没有可通行路径");elseSystem.out.print(str[v] + "-" + str[h] + "之间有最短路径,具体路径为:" + path.get(h).toString());System.out.println();}visited.clear();}
}

测试代码:

public static void main(String[] args) {// TODO Auto-generated method stubint[][] weight = {{0, 10, 12, -1, -1, -1},{-1, 0, -1, 16, 25, -1},{4, 3, 0, 12, -1, 8},{-1, -1, -1, 0, 7, -1},{-1, -1, -1, -1, 0, -1},{-1, -1, -1, 2, -1, 0}};String[] str = {"V1", "V2", "V3", "V4", "V5", "V6"};int len = str.length;Dijkstra dijkstra = new Dijkstra(len);//依次让各点当源点,并调用dijkstra函数for (int i = 0; i < str.length; i++) {dijkstra.dijkstra(weight, str, i);}}

测试结果:
在这里插入图片描述

四、拓展(无向图的Dijkstra算法)

有向图问题解决了,无向图道理和有向图类似,例如如下的无向图,找出V1到其他个点的最短路径

在这里插入图片描述
我们只需要在Test类中定义一个无向图数组

int[][] undirected_weight = {{0,3,-1,7,-1},{3,0,4,2,-1},{-1,4,0,5,4},{7,2,5,0,6},{-1,-1,4,6,0}};
String[] str = {"V1", "V2", "V3", "V4", "V5"};

最后运行结果:

在这里插入图片描述

觉得有用的话还请多多点赞、收藏、评论!!!

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

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

相关文章

应用层协议 - HTTP

文章目录 目录 文章目录 前言 1 . 应用层概要 2. WWW 2.1 互联网的蓬勃发展 2.2 WWW基本概念 2.3 URI 3 . HTTP 3.1 工作过程 3.2 HTTP协议格式 3.3 HTTP请求 3.3.1 URL基本格式 3.3.2 认识方法 get方法 post方法 其他方法 3.3.2 认识请求报头 3.3.3 认识请…

MyBatis是纸老虎吗?(七)

在上篇文章中&#xff0c;我们对照手动编写jdbc的开发流程&#xff0c;对MyBatis进行了梳理。通过这次梳理我们发现了一些之前文章中从未见过的新知识&#xff0c;譬如BoundSql等。本节我想继续MyBatis这个主题&#xff0c;并探索一下MyBatis中的缓存机制。在正式开始梳理前&am…

如何解决kafka rebalance导致的暂时性不能消费数据问题

文章目录 背景思考答案排它故障转移共享 背景 之前在review同组其它业务的时候&#xff0c;发现竟然把kafka去掉了&#xff0c;问了下原因&#xff0c;有一个单独的服务&#xff0c;我们可以把它称为agent&#xff0c;就是这个服务是动态扩缩容的&#xff0c;会采集一些指标&a…

使用C++实现一个简单的日志功能

日志对于一些大一些的项目来说&#xff0c;可以在项目运行出现问题时更好的帮助 项目的维护人员快速的定位到问题出现的地方并且知道出现问题的原因&#xff0c; 并且日志也可以帮助程序员很好的进行项目的Debug&#xff0c;那么今天我就来实 现一个C编写的一个简单的日志功能。…

深度学习中常用计算距离的几种算法对比与python实现

前言 距离度量在许多机器学习算法中扮演着至关重要的角色&#xff0c;无论是监督学习还是无监督学习。选择适当的距离度量可以显著影响模型的性能。 在高维数据集中&#xff0c;欧几里得距离可能会受到所谓的“维度诅咒”的影响&#xff0c;因为随着维度的增加&#xff0c;数…

海外媒体软文发稿:谷歌关键词优化细分人群成功案例,突破海外市场!

海外媒体软文发稿&#xff1a;谷歌关键词优化细分人群成功案例&#xff0c;突破海外市场&#xff01; 引言 在全球化的时代&#xff0c;海外市场对于企业的发展至关重要。而在海外市场中&#xff0c;互联网媒体的作用不可忽视。本篇教程将介绍如何通过谷歌关键词优化细分人群…

Spring设计模式-实战篇之单例模式

实现案例&#xff0c;饿汉式 Double-Check机制 synchronized锁 /*** 以饿汉式为例* 使用Double-Check保证线程安全*/ public class Singleton {// 使用volatile保证多线程同一属性的可见性和指令重排序private static volatile Singleton instance;public static Singleton …

Learn OpenGL 30 SSAO

SSAO 我们已经在前面的基础教程中简单介绍到了这部分内容&#xff1a;环境光照(Ambient Lighting)。环境光照是我们加入场景总体光照中的一个固定光照常量&#xff0c;它被用来模拟光的散射(Scattering)。在现实中&#xff0c;光线会以任意方向散射&#xff0c;它的强度是会一…

C++ STL - 优先级队列及其模拟实现

目录 0. 引言 1. priority_queue 介绍 1.1 构造函数 1.2 priority_queue 接口函数使用 1.3 仿函数 1.4 题目练习 2. priority_queue 模拟实现 2.1基本框架&#xff1a; 2.2 默认构造函数 2.3 基本函数 2.4 堆的向上以及向下调整 0. 引言 优先队列 (priority_queu…

【剑指offr--C/C++】JZ22 链表中倒数最后k个结点

一、题目 二、思路及代码 遍历链表并存入vector容器&#xff0c;通过下标取出对应位置元素或者返回空 /*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) : val(x), next(nullptr) {}* };*/ #include <cstddef> #include <iterator> #…

【微服务】接口幂等性常用解决方案

一、前言 在微服务开发中&#xff0c;接口幂等性问题是一个常见却容易被忽视的问题&#xff0c;同时对于微服务架构设计来讲&#xff0c;好的幂等性设计方案可以让程序更好的应对一些高并发场景下的数据一致性问题。 二、幂等性介绍 2.1 什么是幂等性 通常我们说的幂等性&…

【Entity Framework】 EF三种开发模式

【Entity Framework】 EF三种开发模式 文章目录 【Entity Framework】 EF三种开发模式一、概述二、DataBase First2.1 DataBase First简介2.2 DataBase First应用步骤2.3 DataBase First总结 三、Model First3.1 Model First简介3.2 Model First实现步骤 四、Code First4.1 Cod…

全市场都忽视了!大摩:数据中心算力成本正在迅速下降

随着AI技术迈入普及与应用的新纪元&#xff0c;其算力需求蓬勃增长的同时&#xff0c;算力成本随技术进步呈现下降趋势。 摩根士丹利在3月24日的AI报告中指出&#xff0c;随着GPU技术的不断进步&#xff0c;例如英伟达从Hopper发展到Blackwell GPU架构&#xff0c;GAI的算力成…

ChatGPT 对 ELT的理解

本文主要内容来自 ChatGPT 4.0 到底什么是 ETL&#xff1f;在数据库内部&#xff0c;把数据从 ODS 层加工成 DWD&#xff0c;再加工成 DWS&#xff0c;这个过程和 ETL 的关系是什么&#xff1f;带着这些问题&#xff0c;我问了一下 ChatGPT&#xff0c;总结如下。 数据在两个数…

AWS EC2设置root登录

在使用亚马逊的服务器时&#xff0c;官方默认是使用密钥登录&#xff0c;跟国内的云服务器差别较大&#xff0c;本文记录下&#xff0c;如何开放AWS EC2的root登录。 一、通过网页版或者XShell登录服务器 这里略过 二、设置root账户密码 # 切换 root sudo -i # 设置或修改密…

静态住宅IP VS 动态住宅IP,怎么选择?

在进行海外 IP 代理时&#xff0c;了解动态住宅 IP 和静态住宅 IP 的区别以及如何选择合适的类型非常重要。本文将介绍精态住宅 IP 特点和&#xff0c;并提供选择建议&#xff0c;帮助您根据需求做出明智的决策。 静态住宅 IP 的特点 静态住宅 IP 是指 IP 地址在一段时间内保…

故障诊断 | 一文解决,CNN-BiLSTM卷积神经网络-双向长短期记忆神经网络组合模型的故障诊断(Matlab)

效果一览 文章概述 故障诊断 | 一文解决,CNN-BiLSTM卷积神经网络-双向长短期记忆神经网络组合模型的故障诊断(Matlab) 模型描述 CNN-BiLSTM卷积神经网络-双向长短期记忆神经网络组合模型是一种深度学习模型,结合了卷积神经网络(CNN)和双向长短期记忆网络(BiLSTM)的优点…

CBLUEbenchmark代码跑通

CBLUEbenchmark 跑通 github源地址 1.配置 数据下载 新建文件夹CLBUEDatasets,将数据放在该文件夹下模型下载到github源地址中选择一个模型来下载: 将下载好的模型放在一个专门放模型的文件夹下&#xff0c;我这里是bert 文件如下所示放置&#xff1a; 2.训练模型&#xff…

宁德时代与特斯拉合作;钟睒睒连续四次中国首富丨 RTE 开发者日报 Vol.171

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、…

全自动引流,每日500+粉丝的秘诀

在如今竞争激烈的市场环境下&#xff0c;如何有效地吸引和保持精准粉丝成为了每个企业主或网红必须面对的问题。然而&#xff0c;许多人可能误以为全自动引流就意味着无人参与&#xff0c;实际上&#xff0c;它更多的是借助一些自动化工具和策略来提升我们的工作效率。今天&…