例如下图中的有向图,应用Dijkstra算法计算从源顶点1到其它顶点最短路径的过程列表在下表中。

算法过程描述:
表格中默认选取的起始顶点为1顶点,所以本问题就转化为求解1顶点到2, 3, 4, 5这几个顶点的最短路径。首先初始条件列出1顶点到2, 3, 4, 5各个顶点的距离,这个距离直接在图的存储邻接矩阵中得到,选取距离最近的一个也就是2顶点加入集合S,下面要进行的是比较关键的一步,这个时候应该去获取3, 4, 5三个顶点到集合S的最短距离(从1顶点出发,可以经过S中的任意顶点):将1到2顶点的距离加上2到各个点的距离,然后用这个距离来同1到各个顶点的距离相比较,谁小就取谁,以此类推,然后每次取Distance[]最小的值进入集合S。
这样下去,Distance[]中存放的就是每个顶点到集合S的最短距离,比如当前的集合只有1, 2,按照规则顶点4应该入选进集合S,因为Distance[3]没有入选集合的顶点中对应的Distance[]最小的顶点。现在需要计算3和5到新集合S={1, 2, 4}的最短距离,这个时候就只需要将Distance[2]和Distance[4]中的值(现在这里面的值表示集合S={1, 2}到顶点3和5顶点的最短距离),但是现在集合中加入了顶点4,怎么计算?计算方法如下:
Distance[3] + 邻接矩阵中顶点4到顶点3的距离 < Distance[2] ?
Distance[3]:(顶点4到S={1, 2}的最短距离)
Distance[2]: (顶点3到S={1, 2}的最短距离)
如果这个小于成立,那么很明显新的集合到顶点3的最小距离应该是先从S={1, 2}到顶点4的最短距离,然后再从顶点4到顶点3。
由于每一次的比较都是在上一次集合的最优结果中计算的,所以新计算出来的顶点3到集合S={1, 2, 4}的最短距离也是全局最优的。
对应的C语言代码如下:
- #include <stdio.h>
-
- #define M 65535 //无穷大
- #define N 5 //顶点数
-
-
-
- void Dijkstra(int Cost[][N], int v0, int Distance[], int prev[])
- {
- int s[N];
- int mindis,dis;
- int i, j, u;
-
- for(i=0; i<N; i++)
- {
- Distance[i] = Cost[v0][i];
- s[i] = 0;
- if(Distance[i] == M)
- prev[i] = -1;
- else
- prev[i] = v0;
- }
- Distance[v0] = 0;
- s[v0] = 1;
-
-
- for(i=1; i < N; i++)
- {
- mindis = M;
- u = v0;
- for (j=0; j < N; j++)
- if(s[j]==0 && Distance[j]<mindis)
- {
- mindis = Distance [j];
- u = j;
- }
- s[u] = 1;
- for(j=0; j<N; j++)
- if(s[j]==0 && Cost[u][j]<M)
- {
-
- dis = Distance[u] +Cost[u][j];
-
-
- if(Distance[j] > dis)
- {
- Distance[j] = dis;
- prev[j] = u;
- }
- }
- }
- }
-
-
- void PrintPrev(int prev[],int v0,int vn)
- {
- int tmp = vn;
- int i, j;
-
- int tmpprv[N];
-
- for(i=0; i < N; i++)
- tmpprv[i] = 0;
-
-
- tmpprv[0] = vn+1;
-
- for(i =0, j=1; j < N ;j++)
- {
- if(prev[tmp]!=-1 && tmp!=0)
- {
- tmpprv[i] = prev[tmp]+1;
- tmp = prev[tmp];
- i++;
- }
- else break;
- }
-
-
- for(i=N-1; i >= 0; i--)
- {
- if(tmpprv[i] != 0)
- {
- printf("V%d", tmpprv[i]);
- if(i)
- printf("-->");
- }
- }
- printf("-->V%d", vn+1);
- }
-
- int main()
- {
-
- charchar *Vertex[N]={"V1", "V2", "V3", "V4", "V5"};
-
- int Cost[N][N]={
- {0, 10, M, 30, 100},
- {M, 0, 50, M, M},
- {M, M, 0, M, 10},
- {M, M, 20, 0, 60},
- {M, M, M, M, 0},
- };
- int Distance[N];
- int prev[N];
- int i;
-
-
- Dijkstra(Cost, 0, Distance, prev);
- for(i=0; i < N; i++)
- {
-
- printf("%s-->%s:%d\t", Vertex[0], Vertex[i], Distance[i]);
-
- PrintPrev(prev, 0, i);
- printf("\n");
- }
-
- return 0;
- }
程序运行结果截图:
