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