目录
1. 应用场景-最短路径问题 2. 迪杰斯特拉(Dijkstra)算法介绍 3. 迪杰斯特拉(Dijkstra)算法过程 4. 算法分析过程 5. 代码实现
1. 应用场景-最短路径问题
胜利乡有7个村庄(A, B, C, D, E, F, G) ,现在有六个邮差,从G点出发,需要分别把邮件分别送到 A, B, C , D, E, F 六个村庄 各个村庄的距离用边线表示(权) ,比如 A – B 距离 5公里 问:如何计算出G村庄到其它各个村庄的最短距离? 如果从其它点出发到各个点的最短距离又是多少?
2. 迪杰斯特拉(Dijkstra)算法介绍
迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个结点到其他结点的最短路径。 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止
3. 迪杰斯特拉(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集合中顶点的距离值,保留值较小的一个(同时也应该更新顶点的前驱节点为vi,表明是通过vi到达的) 重复执行两步骤,直到最短路径顶点为目标顶点即可结束
4. 算法分析过程
先定义三个数组,分别是已访问节点、前驱节点、出发顶点到其他顶点的距离
class Visited_vertex {
public int [ ] already_arr;
public int [ ] pre_visited;
public int [ ] dis;
}
A B C D E F G
A { N , 5 , 7 , N , N , N , 2 } ;
B { 5 , N , N , 9 , N , N , 3 } ;
C { 7 , N , N , N , 8 , N , N } ;
D { N , 9 , N , N , N , 4 , N } ;
E { N , N , 8 , N , N , 5 , 4 } ;
F { N , N , N , 4 , 5 , N , 6 } ;
G { 2 , 3 , N , N , 4 , 6 , N } ;
经过G出发访问一轮后,继续选择并返回新的访问顶点, 比如访问G之后,就是以 A点作为新的访问顶点(注意不是出发顶点),遍历所有的顶点,即可得到
5. 代码实现
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 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 ;
int 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 ( ) ;
}
}
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 showDijkstra ( ) {
vv. show ( ) ;
}
private void update ( int index) {
int len = 0 ;
int [ ] ints = matrix[ index] ;
for ( int i = 0 ; i < ints. length; i++ ) {
len = vv. getDis ( index) + ints[ i] ;
if ( ! vv. in ( i) && len < vv. getDis ( i) ) {
vv. updatePre ( i, index) ;
vv. updateDis ( i, len) ;
}
}
}
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) ;
}
}
}