迪杰斯特拉算法

迪杰斯特拉算法

迪杰斯特拉算法用来计算图中某一点v_0其他点最短距离,这个图可以是加权,也可以是无权的,距离指的是从一点到其它点所经过的边的权重和;

假设现在有一个加权无向图,我们要求节点1到其他点的最短距离:

算法流程

  1. 初始化图arr:用一个邻接矩阵来表示一张图,矩阵元素a_{i,j}为节点i到节点j的边权重,初始化时,如果i,j有一条边,则a_{i,j}初始化为便权重,否者置为Integer.MAX_VALUE,即整型最大值。
  2. 初始化一维向量D,这个向量保存的是v_0其他点的最短距离,初始值设为图中v_0到其他点的距离。以上图为例,节点1到其他点最短距离分别是D[0] = 0, D[1] = 7, D[2] = 9, D[3] = MAX, D[4] = MAX,D[5] = 14。
  3. 已经计算过的点的集合visited,这是个向量,用来保存某个点是否访问过过到v_0的最短距离。
  4. 从向量D中寻找一个距离v_0最近而且没被访问过的点mark,以及最短距离min,将mark点标记为已访问:visited[mark]=1。第一次迭代中,距离节点1最短距离的是节点2,距离为7,设置visited[1] = 1,min=7,mark=1。
  5. 调整其他没被访问过的点wv_0的最短距离,即更新向量D:如果v_0w的最短距离(D[w])要大于v_0到mark的最短距离(D[mark])加上图上mark到w的距离arr[mark][w],我们就更新D[w] : D[w] = min + arr[mark][w]。目前访问的点有1,2,然后调整3,4,5,6点到1点的最短距离,比如D[3]为max,大于7+15(即arr[1][3])所以D[3]调整为22,然后visited[3]=1,其它未被访问过的点经过同样的调整。
  6. 重复步骤4,5直到v_0到所有节点的最短距离都被计算完,也就是重复节点个数次。

java实现

package test;
public class Main {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//初始化图的邻接矩阵
		long[][] arr = {
				{0, 7, 9, -1,-1, 14},
				{7, 0, 10, 15, -1, -1},
				{9, 10, 0, 11, -1, 2},
				{-1, 15, 11, 0, 6 ,-1},
				{-1, -1, -1, 6, 0, 9},
				{14, -1, 2, -1, 9 ,0}
		};
		for(int i = 0; i < 6; i++)
			for(int j = 0; j < 6; j++)
				if(arr[i][j] == -1)
					arr[i][j] = Integer.MAX_VALUE;
		//用来记录某个节点是否计算过到v0的最短距离
		int[] visited = new int[6];
		//用来保存v0到某一点的最短距离
		long[] D = new long[6];
		//初始化D
		for(int i = 0; i < 6; i++)
			D[i] = arr[0][i];
		
		visited[0] = 1;
		int mark = 0;
		for(int i = 1; i < 6; i++)
		{
			long min = Integer.MAX_VALUE;
			//寻找距离v0的最小距离
			for(int j = 0; j < 6; j++)
				if(visited[j] == 0 && min > D[j])
				{
					min = D[j];
					mark = j;				
				}
			visited[mark] = 1;
			//根据上一步骤得到的最短距离,更新其他点到v0的最短距离
			for(int j = 0; j < 6; j++)
			{
				if(visited[j] == 0 && D[j] > arr[mark][j] + min)
				{
					D[j] = min + arr[mark][j];
				}
			}
		}
		for(Long i : D)
			System.out.println(i);
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值