最短路算法

本文深入探讨了图论中的两种经典算法——Dijkstra算法和Floyd算法,用于寻找图中节点间的最短路径。Dijkstra算法适用于无负权边的图,通过不断松弛找到单源最短路径;Floyd算法通过动态规划策略,逐步更新所有节点对之间的最短路径。此外,还提及了SPAF算法作为解决图中负权边问题的一种方法。代码示例展示了这两种算法的实现过程。
摘要由CSDN通过智能技术生成

dijkstra算法

思路

  1. dijkstra算法是一种解决单源最短路径的算法,能够找到起点(也叫做源点)到其他各个顶点的最短路径
  2. 将每条边的路径大小用邻接矩阵weight[i][j]存储将源点到其他各个点的距离用dis[n]数组存储,使用visit[n]数组来标记某个点是否已经被访问,并将其初始化
  3. 在未被访问的点中找到dis中距离源点最近的点dis[index],并将其设置未已经被访问
  4. 如果未被访问的顶点的 dis[i] > dis[index] + weight[index][i],则 dis[i] = dis[index] + weight[index][i],该操作叫做松弛
  5. 重复3、4步骤,即可找到源点到各个顶点的最小值

代码

public class Dijkstra {
	//用于存储从0到各个边的大小
	int[] dis;
	private final static int INF = Integer.MAX_VALUE;
	
	public int[] dijkstra(int n, int[][] weight) {
		
		//初始化dis数组
		dis = new int[n];
		//用于记录该点是否已经被访问
		boolean[] visit = new boolean[n];
		for(int i=0; i<n; i++) {
			dis[i] = weight[0][i];
			visit[i] = false;
		}
		//将起点标为已访问
		visit[0] = true;
		dis[0] = 0;
		int j = 0;
		while(j<n-1) {
			//找到离起点最近的点
			int min = INF;
			int index = 0;
			for(int i=0; i<n; i++) {
				if(!visit[i] && min > dis[i] ) {
					min = dis[i];
					index = i;
				}
			}
			visit[index] = true;
			//使用距离源点最近的index点对dis进行松弛
			for(int i=0; i<n; i++) {
				//如果未访问的点的距离比起点到index+index到i的距离大,进行松弛
				if(!visit[i] && weight[index][i]!=INF && dis[i] > dis[index] + weight[index][i]) {
					dis[i] = dis[index] + weight[index][i];
				}
			}
			System.out.println(index + " 离源点的距离为: " + dis[index]);
			j++;
		}
		return dis;
	}
	
	public static void main(String[] args) {
		int n = 7;
		int[][] weight = new int[7][7];
		weight[0]=new int[]{INF,5,7,INF,INF,INF,2};
		weight[1]=new int[]{5,INF,INF,9,INF,INF,3};
		weight[2]=new int[]{7,INF,INF,INF,8,INF,INF};
		weight[3]=new int[]{INF,9,INF,INF,INF,4,INF};
		weight[4]=new int[]{INF,INF,8,INF,INF,5,4};
		weight[5]=new int[]{INF,INF,INF,4,5,INF,6};
		weight[6]=new int[]{2,3,INF,INF,4,6,INF};
		int[] dis = new Dijkstra().dijkstra(n, weight);
		System.out.println(Arrays.toString(dis));
	}
}

floyd算法

思路

  1. 将路径长度存储在邻接矩阵 weight[i][j] 中
  2. 设置中间点k,判断 i 到 j 的距离 weight[i][j] 是否大于 i 先到 k,再从 k 到 j 的距离之和(weight[i][j] > weight[i][k] + weight[k][j]),如果成立,则修改 weight[i][j] = weight[i][k] + weight[k][j] 的路径长度
  3. 每个顶点都可作为中间点,最终即可得到 i 到 j 的最短路径(i,j为任意点)

代码

public void floyd(int n, int[][] weight) {
	for(int k=0; k<n; k++) //中间点
		for(int i=0; i<n ;i++) //起点
			for(int j=0; j<n; j++) //终点
				if(weight[i][j] < weight[i][k] + weight[k][j])
					weight[i][j] = weight[i][k] + weight[k][j];
}

SPAF解决负边权(待更)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值