《图论》——最短路径 Dijkstra算法(戴克斯特拉算法)

简介: 十大算法之Dijkstra算法: 最短路径是图论算法中的经典问题。图分为有向图、无向图,路径权值有正值、负值,针对不同的情况需要分别选用不同的算法。在维基上面给出了各种不同的场景应用不同的算法的基本原则:最短路问题。

十大算法之Dijkstra算法:

最短路径是图论算法中的经典问题。图分为有向图、无向图,路径权值有正值、负值,针对不同的情况需要分别选用不同的算法。在维基上面给出了各种不同的场景应用不同的算法的基本原则:最短路问题

针对无向图,正权值路径,采取Dijkstra算法


如上图,是求a到b的最短路径,这里并不限定b节点,修改为到任意节点的路径,问题是完全一样的。


首先需要记录每个点到原点的距离,这个距离会在每一轮遍历的过程中刷新。每一个节点到原点的最短路径是其上一个节点(前驱节点)到原点的最短路径加上前驱节点到该节点的距离。以这个原则,经过N轮计算就能得到每一个节点的最短距离。


第一轮,可以计算出,2、3、4、5、6到原点1的距离分别为:[7, 9, -1, -1, 14]。-1表示无穷大。取其中最小的,为7,即可以确定1的最短路径为0,2为下一轮的前驱节点。同时确定2节点的最短路径为7,路线:1->2。


第二轮,取2节点为前驱节点,按照前驱节点的最短距离加上该节点与前驱节点的距离计算新的最短距离,可以得到3,4,5,6节点到原点的距离为:[17, 22, -1, -1],此时需要将这一轮得到的结果与上一轮的比较,3节点:17 > 9,最短路径仍然为9;4节点:22 < 无穷大,刷新4节点的最短路径为22;5节点:不变,仍然为无穷大;6节点:14 < 无穷大,取14,不变。则可以得到本轮的最短距离为:[9, 22, -1, 14],取最短路径最小的节点,为3,作为下一轮的前驱节点。同时确定3节点的最短路径为9,路线:1->3。


第三轮,同上,以3为前驱节点,得到4,5,6的计算距离为:[20, -1, 11],按照取最短路径的原则,与上一轮的进行比较,刷新为:[20, –1, 11],选定6为下一轮的前驱节点。同时取定6的最短路径为11,路线:1->3->6。


第四轮,同上,以6为前驱节点,得到4和5的计算距离为[20, 20],与上一轮进行比较,刷新后为[20, 20],二者相等只剩下两个节点,并且二者想等,剩下的计算已经不需要了。则两个节点的最短路径都为20。整个计算结束。4的最短路径为20,路线:1->3->4。5的最短路径为20,路线:1->3->6->5。


如果二者不相等,则还需要进行第五轮,先确定二者中的一个的最短路径和路线,再取定剩下的。直到整个5次循环都完成。

代码如下:


package Graph;

/*
 *Dijkstra,最短路径算法 
 */

public class Dijkstra {

	public static final int M = -1;
	static int[][] map = {
		{ 0,  7,  9,  M,  M, 14 }, 
        { 7,  0,  10, 15, M, M },
        { 9,  10, 0,  11, M, 2 }, 
        { M,  15, 11, 0,  6, M },
        { M,  M,  M,  6,  0, 9 }, 
        { 14, M,  2,  M,  9, 0 }
	};
	static int n =map.length;       //顶点的个数
	static int[] shortest = new int[n];  //存放从start到其他节点的最短路径
	static boolean[] visited = new boolean[n]; //标记当前该顶点的最短路径是否已经求出,true表示已经求出
	
	public static void main(String[] args) {
		int orig = 0; //起始点
		//寻找最短路径
		int[] shortPath = dijkstra_alg(orig);
		
		if(shortPath == null){
			return;
		}
		
		for(int i=0; i< shortPath.length; i++){
			System.out.println("从" + (orig + 1) + "出发到" + (i + 1) + "的最短距离为:"+ shortPath[i]);
			}
	}

	private static int[] dijkstra_alg(int orig) {
		// TODO Auto-generated method stub
		// 初始化,第一个顶点求出
        shortest[orig] = 0;
        visited[orig] = true;
		for(int count = 0; count != n-1; count ++)
		{
			//选出一个距离初始顶点最近的为标记顶点
			int k = M;
			int min = M;
			for(int i =0; i< n ; i++)//遍历每一个顶点
			{
				if( !visited[i] && map[orig][i] != M) //如果该顶点未被遍历过且与orig相连
				{
					if(min == -1 || min > map[orig][i]) //找到与orig最近的点
					{
						min = map[orig][i];
						k = i;
					}
				}
			}
			//正确的图生成的矩阵不可能出现K== M的情况
			if(k == M)
			{
				System.out.println("the input map matrix is wrong!");
				return null;
			}
			shortest[k] = min;
		    visited[k] = true;
			//以k为中心点,更新oirg到未访问点的距离
		    for (int i = 0; i < n; i++)
            {
                if (!visited[i] && map[k][i] != M)
                {
                    int callen = min + map[k][i];
                    if (map[orig][i] == M || map[orig][i] > callen)
                    {
                    	map[orig][i] = callen;
                    }
                }
            }
		}
		
		return shortest;
	}
}

运行结果如下:

从1出发到1的最短距离为:0
从1出发到2的最短距离为:7
从1出发到3的最短距离为:9
从1出发到4的最短距离为:20
从1出发到5的最短距离为:20
从1出发到6的最短距离为:11


相关文章
|
17天前
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
43 15
|
24天前
|
运维 监控 算法
监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。
|
1月前
|
存储 算法 iOS开发
【狂热算法篇】并查集:探秘图论中的 “连通神器”,解锁动态连通性的神秘力量(通俗易懂版)
【狂热算法篇】并查集:探秘图论中的 “连通神器”,解锁动态连通性的神秘力量(通俗易懂版)
|
1月前
|
存储 算法 测试技术
【狂热算法篇】探秘图论之 Floyd 算法:解锁最短路径的神秘密码(通俗易懂版)
【狂热算法篇】探秘图论之 Floyd 算法:解锁最短路径的神秘密码(通俗易懂版)
|
1月前
|
算法 编译器 C++
【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
|
15天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于生物地理算法的MLP多层感知机优化matlab仿真
本程序基于生物地理算法(BBO)优化MLP多层感知机,通过MATLAB2022A实现随机数据点的趋势预测,并输出优化收敛曲线。BBO模拟物种在地理空间上的迁移、竞争与适应过程,以优化MLP的权重和偏置参数,提升预测性能。完整程序无水印,适用于机器学习和数据预测任务。
|
5天前
|
算法 数据安全/隐私保护 异构计算
基于LSB最低有效位的音频水印嵌入提取算法FPGA实现,包含testbench和MATLAB对比
本项目展示了一种基于FPGA的音频水印算法,采用LSB(最低有效位)技术实现版权保护与数据追踪功能。使用Vivado2019.2和Matlab2022a开发,完整代码含中文注释及操作视频。算法通过修改音频采样点的最低有效位嵌入水印,人耳难以察觉变化。然而,面对滤波或压缩等攻击时,水印提取可能受影响。该项目运行效果无水印干扰,适合实时应用场景,核心逻辑简单高效,时间复杂度低。
|
5天前
|
算法 数据安全/隐私保护
基于GA遗传算法的拱桥静载试验车辆最优布载matlab仿真
本程序基于遗传算法(GA)实现拱桥静载试验车辆最优布载的MATLAB仿真,旨在自动化确定车辆位置以满足加载效率要求(0.95≤ηq≤1.05),目标是使ηq尽量接近1,同时减少车辆数量和布载耗时。程序在MATLAB 2022A版本下运行,展示了工况1至工况3的测试结果。通过优化模型,综合考虑车辆重量、位置、类型及车道占用等因素,确保桥梁关键部位承受最大荷载,从而有效评估桥梁性能。核心代码实现了迭代优化过程,并输出最优布载方案及相关参数。
|
10天前
|
机器学习/深度学习 存储 算法
基于MobileNet深度学习网络的活体人脸识别检测算法matlab仿真
本内容主要介绍一种基于MobileNet深度学习网络的活体人脸识别检测技术及MQAM调制类型识别方法。完整程序运行效果无水印,需使用Matlab2022a版本。核心代码包含详细中文注释与操作视频。理论概述中提到,传统人脸识别易受非活体攻击影响,而MobileNet通过轻量化的深度可分离卷积结构,在保证准确性的同时提升检测效率。活体人脸与非活体在纹理和光照上存在显著差异,MobileNet可有效提取人脸高级特征,为无线通信领域提供先进的调制类型识别方案。
|
4天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于模糊神经网络的金融序列预测算法matlab仿真
本程序为基于模糊神经网络的金融序列预测算法MATLAB仿真,适用于非线性、不确定性金融数据预测。通过MAD、RSI、KD等指标实现序列预测与收益分析,运行环境为MATLAB2022A,完整程序无水印。算法结合模糊逻辑与神经网络技术,包含输入层、模糊化层、规则层等结构,可有效处理金融市场中的复杂关系,助力投资者制定交易策略。