应用场景-最短路径问题
看一个应用场景和问题: 战争时期,胜利乡有7个村庄(A, B, C, D, E, F, G) ,现在有六个邮差,从G点出发,需要分别把邮件分别送到 A, B, C , D, E, F 六个村庄 各个村庄的距离用边线表示(权) ,比如 A – B 距离 5公里 问:如何计算出G村庄到 其它各个村庄的最短距离? 如果从其它点出发到各个点的最短距离又是多少?.
迪杰斯特拉(Dijkstra)算法介绍
迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个结点到其他结点的最短路径。 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。
迪杰斯特拉(Dijkstra)算法过程
设置出发顶点为v,顶点集合V{v1,v2,vi…},v到V中各顶点的距离构成距离集合Dis,Dis{d1,d2,di…},Dis集合记录着v到图中各顶点的距离(到自身可以看作0,v到vi距离对应为di)
从Dis中选择值最小的di并移出Dis集合,同时移出V集合中对应的顶点vi,此时的v到vi即为最短路径更新Dis集合,更新规则为:比较v到V集合中顶点的距离值,与v通过vi到V集合中顶点的距离值,保留值较小的一个(同时也应该更新顶点的前驱节点为vi,表明是通过vi到达的)重复执行两步骤,直到最短路径顶点为目标顶点即可结束
迪杰斯特拉(Dijkstra)算法最佳应用-最短路径
战争时期,胜利乡有7个村庄(A, B, C, D, E, F, G) ,现在有六个邮差,从G点出发,需要分别把邮件分别送到 A, B, C , D, E, F 六个村庄各个村庄的距离用边线表示(权) ,比如 A – B 距离 5公里问:如何计算出G村庄到 其它各个村庄的最短距离?如果从其它点出发到各个点的最短距离又是多少?
思路图解
代码实现
package dijkstra
;
import java
.util
.Arrays
;
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
= new Graph(vertex
, matrix
);
graph
.showGraph();
graph
.dsj(6);
graph
.showDijkstra();
}
}
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 showGraph() {
for (int[] link
: matrix
) {
System
.out
.println(Arrays
.toString(link
));
}
}
public void dsj(int index
) {
vv
= new VisitedVertex(vertex
.length
, index
);
update(index
);
for (int i
= 0; i
< vertex
.length
; i
++) {
index
= vv
.updateArr();
update(index
);
}
}
private void update(int index
) {
int len
= 0;
for (int j
= 0; j
< matrix
[index
].length
; j
++) {
len
= vv
.getDis(index
) + matrix
[index
][j
];
if (!vv
.in(j
) && len
< vv
.getDis(j
)) {
vv
.updatePre(j
, index
);
vv
.updateDis(j
, len
);
}
}
}
public void showDijkstra() {
vv
.show();
}
}
class VisitedVertex {
public int[] already_arr
;
public int[] pre_visited
;
public int[] dis
;
public VisitedVertex(int length
, int index
) {
this.already_arr
= new int[length
];
this.pre_visited
= new int[length
];
this.dis
= new int[length
];
Arrays
.fill(dis
, 65535);
this.already_arr
[index
] = 1;
this.dis
[index
] = 0;
}
public boolean in(int index
) {
return already_arr
[index
] == 1;
}
public void updateDis(int index
, int len
) {
dis
[index
] = len
;
}
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
;
}
}
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
+ " ");
}
System
.out
.println();
char[] vertex
= {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
int count
= 0;
for (int i
: dis
) {
if (i
!= 65535) {
System
.out
.print(vertex
[count
] + "(" + i
+ ")");
} else {
System
.out
.println("N ");
}
count
++;
}
System
.out
.println();
System
.out
.println("===============================");
}
}