Dijkstra最短路径算法——java代码实现

具体的算法详解可以看这篇博客Dijkstra最短路径算法详解
这里我利用.txt文件存储了有向加权图中顶点之间的连接关系以及边上的权重,文件格式如下:
在这里插入图片描述
代码所构造的有向加权图如下:
在这里插入图片描述

package Graph;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

public class AdjMatrix {
	public int index;  //中转点的索引
	public int distance;   //最短距离
	public boolean flag;   
	public static ArrayList<Integer> transfer;  //中转点数组
	private int V;    //顶点个数
	private int E;    //边的个数
	private int[][] adj;  //邻接矩阵
	private int[] dis;    //所有点的最短距离
	
	public int findMin(int[] arr) {
		flag=false;
		int min=(int)Double.POSITIVE_INFINITY;
		for(int i=0;i<arr.length;i++) {
			if(arr[i]<min&&arr[i]!=0) {
				min=arr[i];
				index=i;
				flag=true;
			}
		}
		return min;
	}
	
	public AdjMatrix(String fileName) {
		File file=new File(fileName);
		try {
			Scanner scanner=new Scanner(file);
			V=scanner.nextInt();
			adj=new int[V][V];
			int inf=(int) Double.POSITIVE_INFINITY;
			for(int i=0;i<V;i++) {
				for(int j=0;j<V;j++) {
					if(i!=j)
						adj[i][j]=inf;
				}
			}
			E=scanner.nextInt();
			for(int i=0;i<E;i++) {
				int a=scanner.nextInt();
				int b=scanner.nextInt();
				int w=scanner.nextInt();
				//数组相应位置处有顶点之间连接的赋值为1
				adj[a][b]=w;
			}
			transfer=new ArrayList<>();
			transfer.add(0);
			dis=new int[V];
			for(int i=0;i<V;i++) {
				dis[i]=adj[0][i];
			}
			index=0;
			while(true) {
				int mindis=findMin(adj[index]);
				if(flag==false)
					break;
				transfer.add(index);
				distance+=mindis;
				for(int i=0;i<V;i++) {
					if(adj[index][i]!=inf) {
						dis[i]=distance+adj[index][i];
					}
				}
			}
			System.out.println("Minimum distance between points:");
			for(int i=0;i<V;i++)
			{
				System.out.print(dis[i]+" ");
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		AdjMatrix adj=new AdjMatrix("graph.txt");
		System.out.println("\nThe apex of the path:");
		System.out.println(transfer);
	}
}

运行结果如下:

Minimum distance between points:
0 1 8 4 13 17 
The apex of the path:
[0, 1, 3, 2, 4, 5]

最短路径如下所示:
在这里插入图片描述

Dijkstra算法是一种用于在加权图中找到最短路径算法,它可以处理没有负权边的图。算法的基本思想是,从源点开始,逐步增加到其他顶点的距离,直到找到最短路径为止。Dijkstra算法采用贪心策略,每次找到距离源点最近的一个未被访问的顶点,并更新其他顶点到源点的距离。 在Java实现Dijkstra算法通常需要使用优先队列来优化查找当前距离源点最近顶点的过程。以下是Dijkstra算法Java实现的一个简单例子: ```java import java.util.*; class Dijkstra { // 图的顶点数量 private static final int N = 9; // Dijkstra算法实现 public static void dijkstra(int[][] graph, int startVertex) { // 记录源点到每个顶点的最短路径 int[] dist = new int[N]; // 初始化距离数组,所有顶点距离设置为无穷大 Arrays.fill(dist, Integer.MAX_VALUE); // 用于标记顶点是否被访问过 boolean[] visited = new boolean[N]; // 起始点到自身的距离是0 dist[startVertex] = 0; // 用优先队列优化查找最小距离的顶点 PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.comparingInt(i -> dist[i])); // 将起始点加入优先队列 pq.add(startVertex); while (!pq.isEmpty()) { // 从优先队列中选出距离最小的顶点 int u = pq.poll(); // 如果这个顶点已经被访问过,跳过 if (visited[u]) continue; // 标记顶点为已访问 visited[u] = true; // 遍历所有邻接的顶点 for (int v = 0; v < N; v++) { // 如果顶点u到顶点v存在边,并且顶点v未被访问 if (graph[u][v] != 0 && !visited[v]) { // 计算源点通过顶点u到顶点v的路径长度 int newDist = dist[u] + graph[u][v]; // 如果新的路径长度小于当前记录的路径长度,则更新之 if (newDist < dist[v]) { dist[v] = newDist; // 将顶点v加入优先队列 pq.add(v); } } } } // 输出从源点到每个顶点的最短路径长度 for (int i = 0; i < N; i++) { System.out.println("Distance from vertex " + startVertex + " to vertex " + i + " is " + dist[i]); } } public static void main(String[] args) { // 示例图的邻接矩阵表示 int[][] graph = { {0, 4, 0, 0, 0, 0, 0, 8, 0}, {4, 0, 8, 0, 0, 0, 0, 11, 0}, {0, 8, 0, 7, 0, 4, 0, 0, 2}, {0, 0, 7, 0, 9, 14, 0, 0, 0}, {0, 0, 0, 9, 0, 10, 0, 0, 0}, {0, 0, 4, 14, 10, 0, 2, 0, 0}, {0, 0, 0, 0, 0, 2, 0, 1, 6}, {8, 11, 0, 0, 0, 0, 1, 0, 7}, {0, 0, 2, 0, 0, 0, 6, 7, 0} }; // 从顶点0开始计算最短路径 dijkstra(graph, 0); } } ``` 在这个例子中,`graph`是一个图的邻接矩阵表示,`dijkstra`方法实现Dijkstra算法,`main`方法用于测试算法。请注意,这个例子假设图是用邻接矩阵表示的,并且顶点编号从0开始。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值