迪杰斯特拉算法——最短路径算法

最短路径(Dijkstra)算法 最短路径算法Dijktra 阅读详情

基本介绍

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个结点到其他结点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。

基本思想

  • 集合S表示最短距离已经确定的顶点集。
  • 其余的顶点放在另一个集合V-S中。
  • 数组D来记录当前所找到的从源点s到每个顶点的最短特殊路径长度。
  • 从尚未确定最短路径长度的集合V-S中取出一个最短特殊路径长度最小的顶点u,将u加入集合S,同时修改数组D中由s可达的最短路径长度。

实例

在这里插入图片描述

  1. D的初始状态为:如果从源点s到顶点v有弧则D[v]记为弧的权值;否则将D[v]置为无穷大。
  2. 每次从尚未确定最短路径长度的集合V-S中取出一个最短特殊路径长度最小的顶点u,将u加入集合S,同时修改数组D中由s可达的最短路径长度:若加进u做中间顶点,使得vi的最短特殊路径长度变短,则修改vi;的距离值(即当D[u]+W[u,vi]<D[vi]时,令D[vi=D[u]+W[u,vi])。
  3. 然后重复上述操作,一旦S包含了所有V中的顶点,D中各顶点的距离值就记录了从源点s到该顶点的最短路径长度。
    在这里插入图片描述

算法复杂度

  • 注意该算法要求图中不存在负权回路。
  • 空间复杂度取决于存储方式,邻接矩阵为0(n2)。
  • 时间复杂度取决于求权值最小边的方式:
    • 采用最小堆来选择权值最小的边,那么每次改变最短特殊路径长度时需要对堆进行一次重排,此时的时间复杂度为O((n+e)loge),**适合于稀疏图。
    • 通过直接比较D数组元素 ,确定代价最小的边就需要总时间O(n2);取出最短特殊路径长度最小的顶点后,修改最短特殊路径长度共需要时间O(e),因此共需要花费 O(n2) 的时间,这种方法适合于稠密图。

代码实现

有{A,B,C,D,E,F,G}七个点,从G点出发,分别到A,B,C,D,E,E六个点。

在这里插入图片描述

package com.shortest_path;
import java.util.Arrays;
public class DijikstraAlgorithm {

	public static void main(String[] args) {
		char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
		// 邻接矩阵
		int[][] matrix = new int[vertex.length][vertex.length];
		final int N = 65535;// 表示不可连接
		matrix[0] = new int[] { N, 5, 7, N, N, N, 2 };
		matrix[1] = new int[] { 5, N, N, 9, N, N, 3 };
		matrix[2] = new int[] { 7, N, N, N, 8, N, N };
		matrix[3] = new int[] { N, 9, N, N, N, 4, N };
		matrix[4] = new int[] { N, N, 8, N, N, 5, 4 };
		matrix[5] = new int[] { N, N, N, 4, 5, N, 6 };
		matrix[6] = new int[] { 2, 3, N, N, 4, 6, N };
		// 创建Graph对象
		Graph graph = new Graph(vertex, matrix);
		// 测试,看邻接矩阵是否正确
		graph.showGraph();
		// 测试,迪杰斯特拉
		graph.dsj(6);
		graph.showDijikstra();
	}

}

class Graph {
	private char[] vertex;// 顶点数组
	private int[][] matrix;// 邻接矩阵
	private VisitedVertex vv;// 已经访问的顶点的集合

	// 构造器
	public Graph(char[] vertex, int[][] matrix) {
		this.vertex = vertex;
		this.matrix = matrix;
	}

	// 显示结果
	public void showDijikstra() {
		vv.show();
	}

	// 显示图
	public void showGraph() {
		for (int[] link : matrix) {
			System.out.println(Arrays.toString(link));
		}
	}

	// 迪杰斯特拉算法实现
	public void dsj(int index) {
		vv = new VisitedVertex(vertex.length, index);
		update(index);// 更新index下标顶点到周围顶点的距离和前驱顶点
		for (int j = 1; j < vertex.length; j++) {
			index = vv.updateArr();
			update(index);
		}
	}

	// 更新index下标到周围顶点的距离和周围顶点的前驱顶点
	private void update(int index) {
		int len = 0;
		// 根据遍历我们的邻接矩阵的matrix[index]行
		for (int j = 0; j < matrix[index].length; j++) {
			// len含义:出发方法到index顶点的距离+从index顶点到j顶点的距离的和
			len = vv.getDis(index) + matrix[index][j];
			// 如果j顶点没有被访问过,并且len小于出发顶点到j顶点的距离,就需要更新
			if (!vv.in(j) && len < vv.getDis(j)) {
				vv.updatePre(j, index);// 更新j顶点的前驱为index顶点
				vv.updateDis(j, len);// 更新出发顶点的到j顶点的距离
			}
		}
	}

}

/**
 *
 * @ClassName:VisitedVertex
 *
 * @Description:TODO 已访问顶点集合
 */
class VisitedVertex {
	public int[] already_arr;// 记录各个顶点是否访问过 1表示访问过,0未访问,会动态更新
	public int[] pre_visited;// 每个下标对应的值为前一个顶点下标,会动态更新
	public int[] dis;// 记录出发顶点到其他所有顶点的距离,比如G为出发顶点,就会记录G到其它顶点的距离,会动态更新,求的最短距离就会存放到dis

	// 构造器
	/**
	 * @param length
	 *            表示顶点个数
	 * @param index
	 *            出发顶点对应的下标
	 */
	public VisitedVertex(int length, int index) {
		this.already_arr = new int[length];
		this.pre_visited = new int[length];
		this.dis = new int[length];
		// 初始化dis数组
		Arrays.fill(dis, 65535);
		this.already_arr[index] = 1;// 设置出发顶点被访问过
		this.dis[index] = 0;// 设置出发顶点的访问距离为0
	}

	/**
	 * @Method_Name:in
	 * @Description: 判断index是否被访问过
	 * @param index
	 * @return boolean
	 */
	public boolean in(int index) {
		return already_arr[index] == 1;
	}

	/**
	 * @Method_Name:updateDis
	 * @Description: 更新出发顶点到index的距离
	 * @param index
	 * @param len
	 *            void
	 */
	public void updateDis(int index, int len) {
		dis[index] = len;
	}

	/**
	 * @Method_Name:updatePre
	 * @Description: 更新pre这个顶点的前驱为index顶点
	 * @param pre
	 * @param index 
	 * void
	 */
	public void updatePre(int pre, int index) {
		pre_visited[pre] = index;
	}

	/**
	 * @Method_Name:getDis
	 * @Description: 返回出发顶点到index顶点的距离
	 * @param index
	 * @return int
	 */
	public int getDis(int index) {
		return dis[index];
	}

	// 继续选择并返回新的访问顶点
	public int updateArr() {
		int min = 65535, index = 0;
		for (int i = 0; i < already_arr.length; i++) {
			if (already_arr[i] == 0 && dis[i] < min) {
				min = dis[i];
				index = i;
			}
		}
		// 更新index 顶点被访问过
		already_arr[index] = 1;
		return index;
	}

	// 显示最后的结果
	public void show() {
		System.out.println("-----------");
		for (int i : already_arr) {
			System.out.print(i + " ");
		}
		System.out.println();
		for (int i : pre_visited) {
			System.out.print(i + " ");
		}
		System.out.println();
		for (int i : dis) {
			System.out.print(i + " ");
		}
		System.out.println();
		char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
		int count = 0;
		for (int i : dis) {
			if (i != 65535) {
				System.out.print(vertex[count] + "(" + i + ") ");
			} else {
				System.out.println("N");
			}
			count++;
		}
		System.out.println();
	}
}
迪杰斯特拉(Dijkstra)最短路径算法 迪杰斯特拉算法是一种用于在带权有向图或无向图中寻找从一个特定源节点到其他所有节点的最短路径的算法。它属于贪心算法的一种,通过不断选择当前距离源节点最短距离的节点,并更新其相邻节点的距离信息,直到找到所有节点的最短路径。 阅读详情

相关推荐

图论:Dijkstra算法——最详细的分析,图文并茂,一次看懂!

Dijstra算法

普罗米修斯的博客 18万+

迪杰斯特拉算法(求最短路径)

迪杰斯特拉算法(求最短路径) 迪杰斯特拉算法用于查找图中某个顶点到其它所有顶点的最短路径,该算法既适用于无向加权图,也适用于有向加权图。 注意,使用迪杰斯特拉算法查找最短路径时,必须保证图中所有边的权值为非负数,否则查找过程很容易出错。 迪杰斯特拉算法的实现思路 图 1 是一个无向加权图,我们就以此图为例,给大家讲解迪杰斯特拉算法的实现思路。 图 1 无向加权图 假设用迪杰斯特拉算法查找从顶点 0 到其它顶点的最短路径,具体过程是: 统计从顶点 0 直达其它顶点的权值,如下表所示: 表 1 顶点 0

ccc369639963的博客 4万+

单源最短路径,迪杰斯特拉算法

单源最短路径,迪杰斯特拉算法 一、问题描述二、思路梳理三、跑通样例四、代码实现 奇妙的算法世界,单源最短路径,迪杰斯特拉算法 今天我们要讲解的内容是单源最短路径,迪杰斯特拉算法。 一、问题描述 假期来临,小漫打算去海南旅行,如果出发地北京和目的地海南之间有多条路径,不同路径上有不同的中转城市。城市之间如果可以通行,通行的路程是已知的。那么从北京到海南的最短距离是多少呢? 例如,从北京出

muyutang_group的博客 898

图解迪杰斯特拉(Dijkstra)最短路径算法

【干货满满!】在介绍最短路径之前我们首先要明白两个概念:什么是源点,什么是终点?在一条路径中,起始的第一个节点叫做源点;终点:在一条路径中,最后一个的节点叫做终点;注意!源点和终点都只是相对于一条路径而言,每一条路径都会有相同或者不相同的源点和终点。而最短路径这个词不用过多解释,就是其字面意思:在图中,对于非带权无向图而言,从源点到终点边最少的路径(也就是BFS广度优先的方法);而对于带权图而言,从源点到终点权值之和最少的路径叫最短路径;最短路径应用:道路规划;我们最关心的就是去实现寻找最短路径,通过实现.

ZER00000001的博客 7万+

【最短路径】算法7-15:迪杰斯特拉最短路径算法

题目描述 在带权有向图G中,给定一个源点v,求从v到G中的其余各顶点的最短路径问题,叫做单源点的最短路径问题。 在常用的单源点最短路径算法中,迪杰斯特拉算法是最为常用的一种,是一种按照路径长度递增的次序产生最短路径的算法。 可将迪杰斯特拉算法描述如下: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200816113221978.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,t

qq_45601866的博客 743

使用cubeMX生成USB HID设备

本文主要介绍如何使用stm32开发板和cubeMX生成HID设备,供参考。

专注音频,高效工作,快乐生活! 970

图解迪杰斯特拉算法(最短路径问题)

一、单源最短路径问题 如上图给定一个带权图 G = <V,E>,其中每条边(vi,vj)上的权 W[vi,vj] 是一个非负实数。另外,给定 V 中的一个顶点 s 充当源点。现在要计算从源点 s 到所有其他各顶点的最短路径,这个问题通常称为单源最短路径(single-source shortest paths)问题。 用一句话总结来说,单源最短路径就是:从图的某一点(源点)出发,到达其余各顶点(终点)的最短路径。 解决单源最短路径问题的一个常用算法是迪杰斯特拉算法,它是由 E.W.Dijkst

Ronz 的博客 5万+

[WeChatMsg]导出csv格式微信聊天记录的手把手教程

手把手教大家如何导出自己的聊天记录得到csv文件,即使是电脑小白也可以轻松学会o(* ̄▽ ̄*)ブ

weixin_51094633的博客 1万+

图解最短路径之迪杰斯特拉算法(Java实现)

概述 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。迪杰斯特拉算法采用的是贪心策略,将Graph中的节点集分为最短路径计算完成的节点集S和未计算完成的节点集T,每次将从T中挑选V0->Vt最小的节点Vt加入......

编码强迫症患者 3万+

Keil5与ARM编译器V5安装指南:从下载到配置全流程解析

本文提供Keil5与ARM Compiler V5的完整安装与配置指南。针对新版Keil5默认不包含V5编译器导致老工程编译失败的问题,详细解析了从软件下载、授权管理到获取并正确安装ARM Compiler V5(AC5)的全流程,确保开发者能顺利搭建兼容老项目的稳定开发环境。

weixin_29158047的博客 874

别再只盯着轨迹线了!FLUENT DPM后处理实战:从粒子采样到直方图报告的完整流程

本文详细介绍了FLUENT DPM后处理的完整流程,从粒子采样到直方图报告的实战技巧。通过设置采样面、分析.dpm文件数据以及创建加权直方图,帮助工程师获取粒子速度、粒径分布等定量信息,提升多相流模拟的深度分析能力。特别适合需要超越轨迹线分析的CFD工程师。

weixin_28730353的博客 276

图解:最短路径之迪杰斯特拉算法

点击关注上方“五分钟学算法”,设为“置顶或星标”,第一时间送达干货。转自景禹今天我们主要看一个最短路径算法,迪杰斯特拉算法(Dijkstra Algorithm)( 计算从某个源点到其他...

程序员吴师兄的博客 1万+

从Protocol到硬件控制:揭秘高通UEFI中ABL与XBL的协作机制

本文深入解析了高通UEFI架构中ABL与XBL的协作机制,重点探讨了Protocol通信在硬件控制中的关键作用。通过对比传统GPIO控制方式,揭示了Protocol架构在安全性、可维护性和灵活性方面的优势,并提供了关机充电场景的实战案例分析及调试技巧。

weixin_29185199的博客 430

迪杰斯特拉(Dijkstra)算法求最短路径

一.最短路径 从某顶点(源点)出发到另一顶点(目的地)的路径中,有一条各边(或弧)权值之和最小的路径称为最短路径 迪杰斯特拉算法:从单原点到其余各店的最短路径 二.基本思想 依最短路径的长度递增的次序求得各条路径。其中,从源点到顶点v的最短路径是所有最短路径中长度最短者 路径长度最短的最短路径的特点: 在这条路上,必定只含一条弧,并且这条弧的权值最小(记为v0->v1) 下一条路径长度次短的最短路径的特点: 或者是直接从源点到该点(只含一条弧) 或者是从源点经过顶点v1,再到达该顶点(由两条弧组

weixin_45841522的博客 3万+

车牌识别系统

随这图形图像技术的发展,现在的车牌识别技术准确率越来越高,识别速度越来越快。无论何种形式的车牌识别系统,它们都是由触发、图像采集、图像识别模块、辅助光源和通信模块组成的。车牌识别系统涉及光学、电器、电子控制、数字图像处理、计算视觉、人工智能等多项技术。触发模块负责在车辆到达合适位置时,给出触发信号,控制抓拍。辅助光源提供辅助照明,保证系统在不同的光照条件下都能拍摄到高质量的图像。图像预处理程序对抓拍的图像进行处理,去除噪声,并进行参数调整。然后通过车牌定位、字符识别,最后将识别结果输出。 牌照自动识别是一

FPGA/MATLAB学习教程/源码/项目合作开发 2万+

基于Python的新闻聚合与推荐系统:抓取多新闻网站内容并根据用户兴趣进行个性化推荐

本文介绍了如何使用Python构建一个新闻聚合与推荐系统,涵盖了从新闻数据抓取、用户兴趣建模到推荐算法实现的全过程。通过爬虫技术抓取新闻网站内容,使用TF-IDF、Word2Vec等算法进行内容分析,并通过推荐算法向用户推送个性化的新闻,最终帮助用户快速获取自己感兴趣的信息。你可以根据具体需求,进一步扩展和优化系统。例如,加入更多的推荐算法、优化爬虫的抓取效率、增强前端展示的互动性等。通过本文的指导,您应该能够构建一个完整的新闻聚合与推荐系统,并为用户提供个性化的新闻推荐服务。

2201_76125261的博客 1513

迪杰斯特拉Dijkstra算法求最短路径---python

一,迪杰斯特拉算法(Dijkstra)的局限性: 由于迪杰斯特拉算法是贪心算法,只关注当前不关注远处,即他只会关注当前结点能连接到的边,却不关注远处连接不了的边,因此迪杰斯特拉算法并不能处理拥有负权边的情况,如下图所示: 求从A到C的最短路径,若是Dijkstra算法,在A点时,只会关注A-&gt;C的边和A-&gt;B的边,由于3比4小,所以Dijkstra算法会选择从边权值为3的边走向...

ZJE 1万+

手把手教你 Ubuntu 24.04 离线安装 Ollama

本文介绍 Ubuntu 下离线安装 Ollama 并使用 Ollama 部署 llama3.1-70b 大模型

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 1018

图的最短路径之(迪杰斯特拉算法)python实现

前面我们已经了解到了无环有向图怎样求关键路径的方法,今天我们来看看无向图怎样求最短路径,这在实际应用过程中的作用很大,不如交通路线图,从出发点到终点,走哪条路用时最短,或者花费最少等问题。 我们先来看单源最短路径的求法。即给定了起点vvv,求从起点出发,到图中各个顶点的最短路径问题。 对于这个问题,迪杰斯特拉(Dijkstra)提出了一个按路径长度递增的次序产生的最短路径的算法。 下面介绍迪杰斯特拉算法思想: (1)、假设用带权的邻接矩阵arcs来表示带权有向图,arcs[i][j]表示弧<viv_i

time_money的博客 8336

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

六、最短路径——迪杰斯特拉(Dijkstra)算法

在网图和非网图中,最短路径的含义是不同的。由于非网图它没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径;而对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点是源点,最后一个顶点是终点。显然,我们研究网图更有实际意义,就地图来说,距离就是两顶点间的权值之和。而非网图完全可以理解为所有的边的权值都为1的网。 迪杰斯特拉是一个按路径长度递增的次序产生最短路径的算法。它的思路大体是这样的。 比如...

ThinPikachu的博客 1万+

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

迪杰斯特拉算法——最短路径

分析过程: 需要构建的有向图和最短路径 分析每次取出里面的最短路径 程序执行的过程: 代码块: 迪杰斯特拉算法 : #include<stdio.h> #include<string.h> #include<malloc.h> #include<stdlib.h> #define INFINITY 65535 //定义一个无限大的值 #define MaxSize 50 //最大顶点个数 #include <iostream> usi

wh1236666的博客 1557

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

c语言迪杰斯特拉算法求最短路径,迪杰斯特拉 ( Dijkstra ) 最短路径算法

迪杰斯特拉算法介绍迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。基本思想通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算)。此外,引进两个集合S和U。S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的...

weixin_42295892的博客 4095

最短路径——迪杰斯特拉算法

日常生活中常常涉及最短路径问题,如在一个城市交通网中,如何选取从起点到达终点的路径,才能使这一趟旅程的路程最短?或所需时间最少?或所需交通费用最低?诸如此类问题都可以抽象为求解图的最短路径问题。我们把图的顶点表示为城市的交通站点,边表示交通站点间的路径,边的权值表示为交通站点间的路径的距离、所需时间或费用等等,则上述问题放映到图上就是,如何求解图顶点间权值之和最小的路径。

m0_72579201的博客 3305

最短路径之迪杰斯特拉(Dijkstra)算法

最短路径: (1) 在网图中,指两顶点之间经历的边上权值之和最短的路径 (2) 在非网图中,指两顶点之间经历的边数最少的路径 单源最短路径问题:(源点就是起点,即起点已经确定且只有一个) 问题描述:给定带权有向图 G=<V, E> 和源点 v ∈V,求从源点 v 到G中其余各顶点的最短路径。 迪杰斯特拉(Dijkstra)算法 :按路径长度递增的次序产生最短路径 求从A到各顶点的最短距离: 初始:S = < A > 第一步:S = <A, B> A->B: (A,

weixin_46497503的博客 4372

详细实现最短路径(迪杰斯特拉算法)

最短路径,说白了,就是图里从一个顶点到另一个顶点的最小权值之和。 今天,小编带大家一起用迪杰斯特拉(Dijkstra)算法实现它吧! 一.实现原理 其实,在小编看来,迪杰斯特拉算法与普里姆算法有些异曲同工之妙,建议大家可以先看看学懂最小生成树(普里姆算法) 这篇文章,这样更有利于理解迪杰斯特拉算法。 回到正文,迪杰斯特拉算法其实是一种贪心算法。其原理是从起点顶点(源点)出发,确定其到每个顶点的最短路径,直到确定到终点顶点(终点)为止,此时从顶点开始确定的这条路径就是最短路径。 ...

weixin_61857742的博客 3281

迪杰斯特拉算法 – 图的单源最短路径

迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

Bald_pupils的博客 3179
上一篇: 常用算法——动态规划算法
下一篇: 弗洛伊德算法——最短路径算法
lu_long
博客等级 码龄8年 11粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值