Dijkstra算法-(迪杰斯特拉)算法的迭代实现与优先队列实现 图解算法过程

2023-10-27

Dijkstra算法-(迪杰斯特拉)算法之迭代实现 Dijkstra算法-(迪杰斯特拉)算法之优先队列实现


该算法的核心原理,很简单,如下图所示:



先说说Dijkstra算法-(迪杰斯特拉)算法之迭代实现,如下图为详细步骤,



代码如下,两种实现方法都有,用优先队列实现的算法更优秀。

package com.collonn.algorithm;

import java.util.PriorityQueue;

/**
 * 带权有向图的单源最短路径<br/>
 * Dijkstra算法-(迪杰斯特拉)算法<br/>
 */
public class GrfDijkstra {
	// 为了矩阵的输出更直观好看一些,本例中约定,路径权值取值范围为:[1,10],权值为999表示无连通
	// 并假设所有权值的和小于999
	private final int MAX = 999;
	// 顶点总数
	private int total;
	// 顶点信息
	private String[] nodes;
	// 顶点矩阵
	private int[][] matirx;
	// 源点到各顶点的距离
	private int[] dis;
	// 顶点是否已标记
	private int[] mark;

	public GrfDijkstra(int total, String[] nodes) {
		this.total = total;
		this.nodes = nodes;
		this.matirx = new int[total][total];
		this.dis = new int[total];
		this.mark = new int[total];
	}

	private void printMatrix() {
		System.out.println("--------- weighted directed matrix ---------");
		System.out.println("---0---1---2---3---4---5---6---7---8---");
		System.out.println("---A---B---C---D---E---F---G---H---I---");
		for (int i = 0; i < this.total; i++) {
			System.out.print("-" + this.nodes[i] + "|");
			for (int j = 0; j < this.total; j++) {
				System.out.print(String.format("%03d", this.matirx[i][j]) + "-");
			}
			System.out.print("\n");
		}
		System.out.println("--------- weighted directed matrix ---------");
	}

	/**
	 * Dijkstra算法-(迪杰斯特拉)算法之迭代实现
	 * 
	 * @param s
	 *            源点(起点)
	 */
	public void dijkstra(int s) {
		// 初始化
		for (int i = 0; i < this.total; i++) {
			// 初始化都未标记
			this.mark[i] = 0;
			// 给源点的直接邻接点加上初始权值
			this.dis[i] = this.matirx[s][i];
		}

		// 将源点s加入已标记
		this.mark[s] = 1;
		// 顶点到自身的距离为0
		this.dis[s] = 0;
		// 临时最短距离
		int min = -1;
		// 临时最短距离的顶点
		int k = -1;

		this.printDis(0, "屌", "初始化");

		// 除去源点s到自身的距离为0外,还要不断的进行距离修正(源点s到其它顶点(共total-1个)的最短距离)
		for (int i = 1; i < this.total; i++) {
			// 从当前最新的,源点到其它各顶点的距离信息数组dis[]中,找到一个没有标记过的,
			// 并且距离(从源点到该某顶点)最短的顶点
			min = MAX;
			for (int j = 0; j < this.total; j++) {
				if (this.mark[j] == 0 && this.dis[j] < min) {
					min = this.dis[j];
					k = j;
				}
			}

			// 标记该顶点
			this.mark[k] = 1;

			/**
			 * 距离校正<br/>
			 */
			for (int j = 0; j < this.total; j++) {
				if (this.mark[j] == 0 && (this.matirx[k][j] + this.dis[k]) < this.dis[j]) {
					this.dis[j] = this.matirx[k][j] + this.dis[k];
				}
			}

			this.printDis(i, this.nodes[k], "进行中");
		}
	}

	/**
	 * Dijkstra算法-(迪杰斯特拉)算法之优先队列实现
	 */
	public void dijkstraPQ() {
		// Item是PriorityQueue中元素,实现了Comparable接口,优先队列用此接口进行排序
		class Item implements Comparable<Item> {
			// 节点在数组的下标
			public int idx;
			// 到改节点的临时最小权值和
			public int weight;

			public Item(int idx, int weight) {
				this.idx = idx;
				this.weight = weight;
			}

			@Override
			public int compareTo(Item item) {
				if (this.weight == item.weight) {
					return 0;
				} else if (this.weight < item.weight) {
					return -1;
				} else {
					return 1;
				}
			}
		}

		// 值较小的元素总是在优先队列的头部,值较大的元素总是在优先队列的尾部
		PriorityQueue<Item> pq = new PriorityQueue<Item>();

		// 将源点(即起点)加入到优先队列
		pq.offer(new Item(0, 0));

		Item itm = null;
		while (!pq.isEmpty()) {
			itm = pq.poll();

			// 图中某节点下标
			int idx = itm.idx;
			// 到某节点的临时最小权值和
			int weight = itm.weight;

			// 如果该元素还未标记,则更新最小权值各
			if (this.mark[idx] == 0) {
				this.dis[idx] = weight;
			}

			// 找出该元素(假设A)的所有未标记的邻接点(假设B)
			// 则,源点到B的距离可表示为:(源点到A的距离) + (A到B的距离)
			// 将源点到B的距离加入到优先队列中
			for (int i = 0; i < this.total; i++) {
				if (this.mark[i] == 0) {
					pq.offer(new Item(i, this.dis[idx] + this.matirx[idx][i]));
				}
			}
		}
	}

	private void printDis(int i, String node, String pre) {
		System.out.print("\n" + pre + "," + node + "," + i + "--->");
		for (int t = 0; t < this.dis.length; t++) {
			System.out.print(t + ",");
		}
		System.out.print("\n" + pre + i + "--->");
		for (int t : this.dis) {
			System.out.print(t + ",");
		}
		System.out.print("\n");
	}

	// 初始化图数据
	// 0---1---2---3---4---5---6---7---8---
	// A---B---C---D---E---F---G---H---I---
	private void initGrf() {
		// 初始化矩阵为最大值(各节点都不连通)
		for (int i = 0; i < this.total; i++) {
			for (int j = 0; j < this.total; j++) {
				if (i == j) {
					this.matirx[i][j] = 0;
				} else {
					this.matirx[i][j] = MAX;
				}
			}
		}

		// 手动设置有向路径
		// A->B, A->E, A->D
		this.matirx[0][1] = 2;
		this.matirx[0][4] = 3;
		this.matirx[0][3] = 1;
		// B->C
		this.matirx[1][2] = 2;
		// C->F
		this.matirx[2][5] = 1;
		// D->E, D->G
		this.matirx[3][4] = 5;
		this.matirx[3][6] = 2;
		// E->F, E->H
		this.matirx[4][5] = 6;
		this.matirx[4][7] = 1;
		// F->I
		this.matirx[5][8] = 3;
		// G->H
		this.matirx[6][7] = 4;
		// H->F, H->I
		this.matirx[7][5] = 1;
		this.matirx[7][8] = 2;
	}

	public static void main(String[] args) {
		String[] nodes = new String[] { "A", "B", "C", "D", "E", "F", "G", "H", "I" };
		GrfDijkstra grf = new GrfDijkstra(nodes.length, nodes);
		grf.initGrf();
		grf.printMatrix();

		System.out.println();
		System.out.println("------ Dijkstra算法-(迪杰斯特拉)算法之迭代开始 ------");
		grf.dijkstra(0);
		grf.printDis(0, "屌", "最终值");
		System.out.print("\n");
		System.out.println("------ Dijkstra算法-(迪杰斯特拉)算法之迭代结束 ------");

		System.out.println();
		System.out.println("------ Dijkstra算法-(迪杰斯特拉)算法之优先队列开始 ------");
		grf.dijkstraPQ();
		grf.printDis(0, "屌", "最终值");
		System.out.print("\n");
		System.out.println("------ Dijkstra算法-(迪杰斯特拉)算法之优先队列结束 ------");
	}
}


原创博文,转载请注明出处。

右键,查看图片,看大图。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dijkstra算法-(迪杰斯特拉)算法的迭代实现与优先队列实现 图解算法过程 的相关文章

  • 最短路径算法(Dijkstra)

    一 前言 最短路径算法 xff0c 顾名思义就是求解某点到某点的最短的距离 消耗 费用等等 xff0c 有各种各样的描述 xff0c 在地图上看 xff0c 可以说是图上一个地点到达另外一个地点的最短的距离 比方说 xff0c 我们把地图上
  • Dijkstra算法-(迪杰斯特拉)算法的迭代实现与优先队列实现 图解算法过程

    Dijkstra算法 迪杰斯特拉 算法之迭代实现 Dijkstra算法 迪杰斯特拉 算法之优先队列实现 该算法的核心原理 很简单 如下图所示 先说说Dijkstra算法 迪杰斯特拉 算法之迭代实现 如下图为详细步骤 代码如下 两种实现方法都
  • Python 中 Iterator和Iterable的区别

    Python中 list truple str dict这些都可以被迭代 但他们并不是迭代器 为什么 因为和迭代器相比有一个很大的不同 list truple map dict这些数据的大小是确定的 也就是说有多少事可知的 但迭代器不是 迭
  • 深入分析 (迪杰斯特拉算法) Dijkstra 算法实现原理

    迪杰斯特拉 Dijkstra 算法是典型最短路径算法 用于计算一个节点到其他节点的最短路径 它的主要特点是以起始点为中心向外层层扩展 广度优先搜索思想 直到扩展到终点为止 基本思想 通过Dijkstra计算图G中的最短路径时 需要指定起点s
  • 最短路径A*算法原理及java代码实现(看不懂是我的失败)

    算法只要懂原理了 代码都是小问题 先看下面理论 尤其是红色标注的 要源码请留下邮箱 有测试用例 直接运行即可 A 算法 百度上的解释 A 1 A Star 算法是一种静态路网中求解最短路最有效的直接搜索方法 公式表示为 f n g n h
  • 图论:Dijkstra算法——最详细的分析,图文并茂,一次看懂!

    文章目录 1 Dijkstra算法简介 2 算法实现范例 3 邻接矩阵 4 Dijkstra 算法的 C 描述 5 Dijkstra 算法的 Matlab 描述 6 温故知新 1 Dijkstra算法简介 背景 迪杰斯特拉算法 Dijkst
  • 最短路径——Dijkstra算法(C语言实现)

    最短路径 Dijkstra算法 基本概念 1 最短路径 非带权图 边数最少的路径 带权图 边上的权值之和最少的路径 基本思想 1 v 源点 S 已经生成最短路径的终点 w
  • 迭代法求解线性方程组(C++实现)

    本系列是数值分析相关算法的文章 这次用迭代法求解线性方程组 不同于上次用高斯消元法之类的求解 迭代法对于稀疏矩阵方程组的运算 会大大提高 而如果用高斯相关的算法求解 会浪费大量资源计算无用的东西 所以有必要研究此算法 本文章主要使用了3个算
  • 最小二乘法–高斯牛顿迭代法

    最小二乘法 高斯牛顿迭代法 本文将详解最小二乘法的非线性拟合 高斯牛顿迭代法 1 原理 高斯 牛顿迭代法的基本思想是使用泰勒级数展开式去近似地代替非线性回归模型 然后通过多次迭代 多次修正回归系数 使回归系数不断逼近非线性回归模型的最佳回归
  • 如何才能避免辛苦开发出来的产品惨遭市场冷遇?

    精益创新与传统创新模式的主要区别 1 传统的火箭发射式创新 认为用户需求和解决方案都是可以预知的 且可以准确把握的 直到产品成型的那一刻才面向用户 2 精益创新 认为用户痛点和解决方案在本质上都是未知的 无法完美预测的 需要通过不断地验证与
  • 如果顶点属性是指针,如何使用 boost::graph dijkstra 算法?

    我使用 boost graph 来管理图表 我需要制作一个 maxmin 树 现在我尝试使用 boost dijkstra 算法 但我使用指向我的类的指针作为顶点属性 而不是使用typedef property
  • 带优先级队列的 Dijkstra 算法

    在我的 Dijkstra 算法的实现中 我有 1 个包含所有节点的数组和 1 个包含所有节点的优先级队列 每当一个节点出队时 我都会用新的距离和它的来源更新所有相邻节点 这样我就可以回溯路径 优先级队列中的节点将更新为新距离 数组中的节点将
  • Dijkstra最短路径算法

    以下是我们教授给我们的算法摘要 步骤 3 中提到的图中节点的父节点是什么 我有点困惑 因为我认为节点只有邻居而没有父节点 我的第二个问题是关于第 3 步 拾取堆栈中的第索引条记录 由于堆栈只允许您查看顶部 所以我不确定拾取第索引记录意味着什
  • 如果广度优先搜索 (BFS) 可以更快地完成同样的事情,为什么还要使用 Dijkstra 算法呢?

    两者都可用于从单一源查找最短路径 BFS运行在O E V 而 Dijkstra 运行O V E log V 另外 我见过 Dijkstra 在路由协议中的使用很像 因此 如果 BFS 可以更快地完成同样的事情 为什么还要使用 Dijkstr
  • 查找两个顶点之间的所有最短路径

    给定一个有向图G V E 两个顶点s t和两个权重函数w1 w2 我需要找到最短路径s to t by w2在所有最短路径之间s to t by w1 首先 我怎样才能找到两个顶点之间的所有最短路径s and t Dijkstra 算法帮助
  • 具有固定边数的最短路径

    在高效的时间内找到通过图形的最短路径 并附加该路径必须完全包含的约束n nodes 我们有一个有向加权图 它可能包含也可能不包含循环 我们可以使用 Dijkstra 算法轻松找到最短路径 但 Dijkstra 算法不保证边的数量 我们能想到
  • 实施 Dijkstra 算法

    我的任务是 大学课程 实施某种形式的寻路 现在 在规范中 我可以实现强力 因为要搜索的节点数量有限制 开始 中间两个 结束 但我想重新使用此代码并来实现迪杰斯特拉算法 http en wikipedia org wiki Dijkstra
  • 使用字典中的特定键构建列表(python)?

    我正在用 Python 实现 Dijkstra 搜索算法 在搜索结束时 我使用前驱图重建最短路径 从目标节点的前驱开始 例如 path path append destination previous predecessor map des
  • 原始地理坐标和图形节点之间的最短路径

    我已经实现了一个简单的 Dijkstra 算法 用于使用 Java 查找 osm 地图上的最短路径 从 osm 文件创建的图形中的寻路效果非常好 但是 如果用户的当前位置和 或目的地不是该图的节点 只是原始坐标 我们如何将这些坐标 链接 到
  • java有索引的最小优先级队列吗?

    我需要它来实现 Dijkstra 算法 并且我确实有自己的实现 但是使用 java 自己的类记录我的代码会更容易 不 Java标准库没有这样的数据结构 我想大多数人都用这个 http algs4 cs princeton edu 24pq

随机推荐

  • java基础 —— 高级编程篇

    java基础 高级编程篇 多线程 基本概念 线程的创建和使用 Thread类 创建 多 线程 线程的调度 线程的分类 线程的生命周期 线程同步 同步机制 死锁 死锁处理方法 线程通信 生产者 消费者问题 java常用类 String类 St
  • ROS navigation调试基础(实现真实机器人导航)

    最近使用了一下ROS中非常经典的导航包navigation 并通过自己的激光雷达以及相机里程计驱动了自己的小车在室内进行简单的定位以及导航 在此记录一下以免后期忘记 1 导航包安装 ROS中navigation导航包可以通过GitHub上下
  • Nacos控制台下线服务报错

    Nacos控制台下线服务报错 现象 在 Nacos控制台服务列表 点击下线按钮 Nacos控制台报错 提示错误信息 naming instance metadata did not find the Leader node 原因 Nacos
  • maven项目编译时报错org.junit包不存在解决办法

    在用idea快速搭建项目的时候 生成的pom xml文件里面对junit的依赖是 junit junit 4 11 test 在进行编译的时候 maven项目报错org junit包不存在 解决方法是将 test 这一行注释掉 测试用例记得
  • LLVM是什么

    有什么说的不对的地方 还请多多支出 谢谢 概述 LLVM 全称是这个Low Level Virtual Machine 底层虚拟机 名字是带有虚拟机 但是现在早已和虚拟机没有任何关系了 是整个LLVM项目 我目前了解的有5部分 LLVM 是
  • Echarts实现图形重新绘制方法总结

    1 业务需求 vue项目使用Echarts进行数据看板绘制 当数据发生改变时 需要重新进行图形绘制 2 解决方案 目前网上流传的方法 myChart setOption option true 亲测无效 因此重找了资料找到了解决方法 Ech
  • Windows系统下安装Metasploit

    Windows系统下安装Metasploit metasploit介绍 metasploit是一款开源的安全漏洞检测工具 里面含有海量的漏洞供大家直接使用 当然 你也可以自己去扩展漏洞库 下载软件包 下载地址 https windows m
  • 原生js写画布

    html部分
  • 【网安自学】XSS漏洞防御

    一 XSS漏洞的产生很大原因是 程序没有经过过滤或者过滤的敏感字符不严密就直接输出或写入数据库 导致一些别有用心的人通过构造巧妙的脚本恶意代码来实施攻击 二 根据漏洞产生的原因 防御XSS漏洞的方法就是对敏感字符进行转义和过滤 方法一 ht
  • 用Python探索性数据分析和数据可视化:从真实世界数据集中学习基础技能!

    以下是探索电子商务销售记录数据洞见的示例 涵盖了使用Matplotlib和Seaborn创建多种图表形式 随着互联网的发展以及消费者购物行为的改变 电子商务已经成为现代商业中不可或缺的组成部分 对于电子商务公司而言 深入分析销售数据可以帮助
  • 你真的了解websocket吗?(websock原理详解)

    什么是websocket WebSocket是在2008年6月诞生 2011年由IEFT标准化为RFC 6455 WebSocket是一种在单个TCP连接上进行全双工通信的协议 使得客户端和服务器之间的数据交换变得更加简单 并允许服务端主动
  • android 网络请求参数排序

    在网络开发过程中客户端跟服务器经常遇到各种各样的验证方式 参数排序就是常见的方法之一 按照参数的首字母升序或者降序 参数少的话可以主观的排序就行了 但是参数多的时候肯定不能这么干了 下面介绍几个方法 0 以Key进行排序 第一种 直接声明T
  • 【uniapp】scroll-view 实现自动滚动到最底部

    在做uniapp项目中 有个滚动视图组件scroll view 跟微信小程序里的组件一样的 想要实现自动滚动到最底部 是一件容易忽略的 小事情 文章目录 问题呈现 解决方案 注意事项 问题呈现 官网uniapp文档上说可以控制滚动条 并没有
  • 基于STM32F103ZET6核心板控制HX711(称重传感器带屏蔽)

    目的 使用核心板控制传感器 实现串口打印数据 硬件要求 1 gt stm32f103zet6核心板 2 gt HX711 带屏蔽 HX711有好几款板子 我这里使用的是带屏蔽的板子 只要知道引脚的功能什么板子都是一样的 HX711原理图 管
  • Tomcat & Servlet入门学习

    web相关概念回顾 1 软件架构 1 C S 客户端 服务器端 2 B S 浏览器 服务器端 2 资源分类 1 静态资源 所有用户访问后 得到的结果都是一样的 称为静态资源 静态资源可以直接被浏览器解析 如 html css JavaScr
  • B1094 谷歌的招聘 (20 分)

    2004 年 7 月 谷歌在硅谷的 101 号公路边竖立了一块巨大的广告牌 如下图 用于招聘 内容超级简单 就是一个以 com 结尾的网址 而前面的网址是一个 10 位素数 这个素数是自然常数 e 中最早出现的 10 位连续数字 能找出这个
  • Lyperledger Fabric笔记 - Ubuntu Kylin 14 部署fabric 1.4.3

    https www htcp net 3766 html 丢一连接 配环境累死个人 好的 我活着来了 终于配完了 期间几多辛酸那 预警 非教程 仅仅作个人笔记用 信息不全 报错信息也不全 只是记录一下自己踩的一些坑 第一次配置 一 系统配置
  • BlockBank六扇门社区AMA内容记录

    参与嘉宾 NOLVIA SERRANO GABRIEL HIRIS 主持人 BlockBank社区志愿者 喵喵参与嘉宾 NOLVIA SERRANO GABRIEL HIRIS 主持人 BlockBank社区志愿者 喵喵 AMA Topic
  • PyTorch笔记

    PyTorch快速入门 函数名后面带下划线 的函数会修改Tensor本身 例如 x add y 和x t 会改变 x 但x add y 和x t 返回一个新的Tensor 而x不变 Tensor和numpy对象共享内存 所以他们之间的转换很
  • Dijkstra算法-(迪杰斯特拉)算法的迭代实现与优先队列实现 图解算法过程

    Dijkstra算法 迪杰斯特拉 算法之迭代实现 Dijkstra算法 迪杰斯特拉 算法之优先队列实现 该算法的核心原理 很简单 如下图所示 先说说Dijkstra算法 迪杰斯特拉 算法之迭代实现 如下图为详细步骤 代码如下 两种实现方法都