Dijkstra算法——邻接矩阵实现+路径记录

这篇具有很好参考价值的文章主要介绍了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]);
		}
		//设置顶点自己到自己的权重为0
		for(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];
		//初始化 result
		for(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);
		//初始化 notFound
		for(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;
			//刷新 notFound
			for(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 来记录最短路径,最终打印最短路径距离和对应路劲信息。
Dijkstra算法——邻接矩阵实现+路径记录,随笔,算法文章来源地址https://www.toymoban.com/news/detail-802274.html

到了这里,关于Dijkstra算法——邻接矩阵实现+路径记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【路径规划】全局路径规划算法——Dijkstra算法(含python实现 | c++实现)

    路径规划与轨迹跟踪系列算法学习 最短路径算法-迪杰斯特拉(Dijkstra)算法 迪杰斯特拉dijkstra算法的python实现 Python实现迪杰斯特拉算法 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个节点遍历其余各节点的最短路

    2024年02月08日
    浏览(33)
  • dijkstra迪杰斯特拉算法(邻接表法)

    算法简易过程: 求单源有向图最短路径 使用 邻接表法 来存储顶点和边,录入 有向图 。 (当然也可以无向图,不过录入时要录入两次,比如 a b 3        b a 3)  代码如下: 测试如下:  

    2024年02月07日
    浏览(33)
  • 基于Dijkstra算法实现无人机三维路径规划

    基于Dijkstra算法实现无人机三维路径规划 无人机在飞行任务中往往需要寻找一条最优路径以达到最佳的飞行效果。而在三维空间中,路径规划问题变得更加复杂。本文将介绍如何基于Dijkstra算法来解决无人机三维路径规划问题,并且提供相应的matlab代码。 一、Dijkstra算法简介

    2024年02月14日
    浏览(43)
  • Dijkstra实现(邻接表C++版)

    从V0出发,到各个节点的最短距离 Dijkstra的过程,就是维护并更新一个表来实现的。 其中distance表示是从起始节点,到当前节点的距离。 path表示经过哪个节点达到当前节点。 表初始化为:path全-1,distance全为INT_MAX。 vertices path distance 0 -1 ∞ 1 -1 ∞ 2 -1 ∞ 3 -1 ∞ 4 -1 ∞ 5 -1 ∞

    2023年04月13日
    浏览(17)
  • 使用邻接矩阵实现最小生成树Prim算法 题目编号:1135

    用邻接矩阵存储无向图,实现最小生成树Prim算法,图中边的权值为整型,顶点个数少于10个。 部分代码提示: #include using namespace std; const int MaxSize = 10; const int INF = 32767; class MGraph { public: MGraph(char a[], int n, int e); private: char vertex[MaxSize]; int arc[MaxSize][MaxSize]; int vertexNum, arcNum; }

    2024年02月06日
    浏览(30)
  • 自动驾驶路径规划——Dijkstra算法

    这个学期学校开设了相应的课程,同时也在学习古月居机器人学系列的《基于栅格地图的机器人路径规划指南》,为了巩固知识,方便自己的学习与整理,遂以学习笔记的形式记录。      深度优先搜索( Depth First Search , DFS ) :首先从某个顶点出发,依次从它的各个未被

    2024年01月22日
    浏览(30)
  • 基于Dijkstra算法的机器人编队路径规划问题

    基于Dijkstra算法的机器人编队路径规划问题 路径规划是机器人领域中的一个重要问题,它涉及确定从起点到目标点的最佳路径。Dijkstra算法是一种经典的图算法,用于解决最短路径问题。在本文中,我们将介绍如何使用Dijkstra算法来实现机器人编队的路径规划,并提供相应的

    2024年02月08日
    浏览(41)
  • 【数据结构与算法】图——邻接表与邻接矩阵

    图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中, G表示一个图,V是顶点的集合,E是边的集合 。 在图中数据元素,我们则称之为顶点(Vertex)。 图中,任意两个顶点之间都可能有关系,顶点之间的逻辑关系用边来表示,边集可以是

    2024年02月02日
    浏览(29)
  • 一起来学算法(邻接矩阵)

           邻接矩阵是数学和计算机科学中常用的一种表示方式,用来表述有向图或无向图,一张图由一组顶点(或结点)和一组表组成,用邻接矩阵就能表示这些顶点间存在的边的关系        对于图而言,是数据结构中最复杂的结构,而是在做题的过程中,最大的难点在于

    2024年02月05日
    浏览(27)
  • 【路径规划】(1) Dijkstra 算法求解最短路,附python完整代码

    好久不见,我又回来了, 这段时间把路径规划的一系列算法整理一下 ,感兴趣的点个关注。今天介绍一下机器人路径规划算法中最基础的 Dijkstra 算法,文末有 python 完整代码,那我们开始吧。 1959 年,荷兰计算机科学家 ·EdsgerWybe·Dijkstra 发表了论文《 A note on two problems in c

    2023年04月08日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包