迪杰斯特拉算法兼具动态规划和贪心思想
贪心思想
例:A能到达的各点中,AC距离最小
那么无论后续怎么变化,再找任何其他路径,A到C的距离都不可能小于A->x->C,因为A->x的距离已经大于A->C了
所有我们也不用再考虑C节点了,C已经是最小距离了
动态规划思想
现在有A->B A->C A->D
如果A->C的距离是三个中最小的一个,那么A->B->C,A->D->C 都是大于A->C这是上面论述过的
但是我们无法保证A->C->B比A->B要长
因此我们要更新A->B的距离,为Math.min(A->C->B,A->B)
综上所述,我们解题的思路为:
- 先计算A到各节点的距离,找出没有访问过的最小的那个点,并标记为访问过(因为此时该点的距离一定是最小的了)
- 更新没有访问过的其他节点的距离,更新规则为:Math.min(A->C->B,A->B)
循环1,2步骤,直到所有节点都被访问
就得到了A到各节点的最短路径
Code
public class Learn {
static char[] vexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
private static int INF=Integer.MAX_VALUE/2;
public static void dijkstra(int matrix[][]) {
boolean[] visited=new boolean[matrix.length];
int[] dist=new int[matrix.length];
visited[0]=true;
int min_cur=0;
int min_value;
//初始化
for (int i = 0; i < dist.length; i++) {
dist[i]=matrix[0][i];
}
for (int k = 0; k <dist.length ; k++) {
int temp=dist[min_cur];
int temp_cur=min_cur;
min_value=Integer.MAX_VALUE/2;
visited[min_cur]=true;
System.out.println("加入了点: "+vexs[min_cur]);
for (int i = 0; i < dist.length; i++) {
if(!visited[i]){
dist[i]=Math.min(dist[i],temp+matrix[temp_cur][i]);
if(dist[i]<min_value){
min_value=dist[i];
min_cur=i;
}
}
}
}
System.out.println("======================");
System.out.println(Arrays.toString(dist));
}
public static void main(String[] args) {
int matrix[][] = {
/*A*//*B*//*C*//*D*//*E*//*F*//*G*/
/*A*/ { 0, 12, INF, INF, INF, 15, 14},
/*B*/ { 12, 0, 10, INF, INF, 7, INF},
/*C*/ { INF, 10, 0, 3, 5, 6, INF},
/*D*/ { INF, INF, 3, 0, 5, INF, INF},
/*E*/ { INF, INF, 5, 5, 0, 2, 8},
/*F*/ { 15, 7, 6, INF, 2, 0, 9},
/*G*/ { 14, INF, INF, INF, 8, 9, 0}};
dijkstra(matrix);
}
}