package com.guigu.algorithm.dijkstra;
import java.util.Arrays;
/**
* @author: guorui fu
* @versiion: 1.0
*/
public class DijkstraAlgorithm {
public static void main(String[] args) {
char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
//邻接矩阵
int[][] matrix = new int[vertex.length][vertex.length];
final int N = 65535;//表示不可连接
matrix[0] = new int[]{N, 5, 7, N, N, N, 2};
matrix[1] = new int[]{5, N, N, 9, N, N, 3};
matrix[2] = new int[]{7, N, N, N, 8, N, N};
matrix[3] = new int[]{N, 9, N, N, N, 4, N};
matrix[4] = new int[]{N, N, 8, N, N, 5, 4};
matrix[5] = new int[]{N, N, N, 4, 5, N, 6};
matrix[6] = new int[]{2, 3, N, N, 4, 6, N};
//创建Graph
Graph graph = new Graph(vertex, matrix);
graph.showGraph();
graph.dsj(2);
graph.show();
}
}
class VisitedVertex {//已访问顶点集合
public int[] already_arr;//记录各个顶点是否访问过 1表示访问过,0为未访问过,动态更新
public int[] pre_visited;//每个下标对应的值为前一个顶点下标,动态更新
public int[] dis;//记录出发顶点到其他所有顶点的距离,动态更新,求最短距离
/**
* @param length 顶点个数
* @param index 出发顶点下标
*/
public VisitedVertex(int length, int index) {
this.already_arr = new int[length];
this.pre_visited = new int[length];
this.dis = new int[length];
//初始化dis数组
Arrays.fill(dis, 65535);
already_arr[index] = 1;
dis[index] = 0;//出发顶点的访问距离
}
//判断index对应顶点是否被访问过
public boolean in(int index) {
return already_arr[index] == 1;
}
/**
* 更新出发点到index顶点的距离
*
* @param index
* @param len
*/
public void updateDis(int index, int len) {
dis[index] = len;
// if (dis[index] == 65535){
// dis[index] = len;
// }else if (dis[index] < 65535 && dis[index] != 0){
// dis[index] += len;
// }
}
//将index更新为对应节点前驱节点
public void updatePre(int pre,int index){
pre_visited[pre] = index;
}
public int getDis(int index){
return dis[index];
}
//继续选择并返回新的访问顶点
public int updateArr(){
int min = 65535,index =0;
for (int i = 0; i < already_arr.length; i++) {
if (already_arr[i] == 0 && dis[i] < min){
min = dis[i];
index = i;
}
}
//更新index 顶点被访问过
already_arr[index] = 1;
return index;
}
//显示最后结果
public void show(){
System.out.println("=======已过顶点============");
for (int i : already_arr) {
System.out.print(i + " ");
}
System.out.println("=======前驱============");
for (int i : pre_visited) {
System.out.print(i + " ");
}
System.out.println("=======到各节点距离============");
for (int i : dis) {
System.out.print(i + " ");
}
}
}
class Graph {
private char[] vertex;//顶点数组
private int[][] matrix;//邻接矩阵
private VisitedVertex vv;//已访问顶点集合
public Graph(char[] vertex, int[][] matrix) {
this.vertex = vertex;
this.matrix = matrix;
}
//显示结果
public void show(){
vv.show();
}
//显示图的方法
public void showGraph() {
for (int[] link : matrix) {
System.out.println(Arrays.toString(link));
}
}
//迪杰斯特拉算法
public void dsj(int index){
vv = new VisitedVertex(vertex.length, index);
update(index);//更新index顶点到周围顶点距离 和 更新前驱顶点
for (int i = 1; i < vertex.length; i++) {
index = vv.updateArr();//选择并返回新的访问节点
update(index);
}
}
//更新index下标顶点到周围顶点的距离 和 周围顶点的前驱顶点
public void update(int index){
int len = 0;
//遍历邻接节点 广度优先遍历
for (int i = 0; i < matrix[index].length; i++) {
//对顶点到出发点的距离进行更新
//出发点到index的距离 + index到i的距离
len = vv.getDis(index) + matrix[index][i];
//顶点i没有被访问过,并且len < 已保存出发顶点到i的距离,就需要更新
if (!vv.in(i) && len < vv.getDis(i)) {
vv.updatePre(i,index);//保存这个节点为前驱节点
vv.updateDis(i,len);//更新距离
}
}
}
}
[算法] 迪杰斯特拉算法 计算最小加权路径
最新推荐文章于 2024-06-16 20:54:56 发布