迪杰斯特拉算法
迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。
Java代码实现:
package com.yg.algorithm;/*
@author Mu_Mu
@date 2020/3/22 11:51
*/
import java.util.Arrays;
public class DijkstraAlgorithm {
private static final int MAX = 10000;
public static void main(String[] args) {
char[] vertexs = {'A', 'B', 'C', 'D', 'E'};
int[][] matrix = {{MAX, MAX, MAX, 5, 2}, {MAX, MAX, 8, MAX, 3}
, {MAX, 8, MAX, MAX, 4}, {5, MAX, MAX, MAX, 9},{2,3,4,9,MAX}};
DGraph dGraph = new DGraph(vertexs, matrix);
dGraph.dsj(4);
dGraph.showShortPath();
}
}
class vVertex {
//记录各个顶点是否访问过,1访问过,0未访问过
public int[] alreadyArr;
//每个下标对应的值为前一个顶点的下标
public int[] preVisited;
//记录从出发顶点到其他所有顶点的距离
public int[] dis;
/*
* @param length 表示顶点个数
* @param index 表示出发顶点的下标
*/
public vVertex(int length, int index) {
alreadyArr = new int[length];
dis = new int[length];
preVisited = new int[length];
Arrays.fill(dis, 65535);
alreadyArr[index] = 1;
dis[index] = 0;
}
//判断下标为index的顶点是否访问过
public boolean in(int index) {
return alreadyArr[index] == 1;
}
//更新出发点到下标为index顶点的距离,len为待更新的距离
public void updateDis(int len, int index) {
dis[index] = len;
}
//更新pre顶点的前驱顶点,index为新前驱顶点的下标
public void updatePre(int pre, int index) {
preVisited[pre] = index;
}
//继续选择新的访问顶点,比如E作为出发点,则离E最近的A就是第一个访问顶点
public int selectNextVertex() {
int min=65535,index=0;
for (int i = 0; i < alreadyArr.length; i++) {
if (alreadyArr[i] == 0 && dis[i] < min) {
min=dis[i] ;
index = i;
}
}
alreadyArr[index]=1;
return index;
}
}
class DGraph {
private char[] vertexs;//顶点数组
private int[][] matrix;//邻接矩阵
vVertex vVertex;
public DGraph(char[] vertexs, int[][] matrix) {
this.vertexs = vertexs;
this.matrix = matrix;
}
//迪杰斯特核心算法
public void dsj(int index) {
vVertex = new vVertex(vertexs.length, index);
update(index);
for (int i = 1; i < vertexs.length; i++) {
index=vVertex.selectNextVertex();
update(index);
}
}
//显示最短路径
public void showShortPath() {
for (int i = 0; i < vVertex.dis.length; i++) {
System.out.print(vertexs[i]+"("+vVertex.dis[i]+")\t");
}
}
//更新下标为index的顶点到周围顶点的距离和周围顶点的前驱顶点
public void update(int index) {
int len=0;
for (int i = 0; i < matrix[index].length; i++) {
//len为出发点到下标为index的顶点的距离+下标为index到下标为i顶点之间的距离
len = vVertex.dis[index] + matrix[index][i];
if ( !vVertex.in(i) &&len < vVertex.dis[i]) {
//更新下标为i的顶点到出发点的距离
vVertex.updateDis(len, i);
//更新下标为i的顶点的前驱顶点
vVertex.updatePre(i,index);
}
}
vVertex.alreadyArr[index]=1;
}
//打印图
public void print() {
for (int[] arr : matrix) {
System.out.println(Arrays.toString(arr));
}
}
}
运行结果: