1、, 为弧上的权值;II) 若不存在为;Step 2. 选取一个最小的权值,加入到S中.Step 3. 对其余T中点对应到初始点v0距离值修改,具体的修改为若加进点w,如果加入w之后,从v0到vi的距离有所减小,则用w到v0得知代替其余T中点对应到初始点v0距离值重复步骤2,3,直到将所有的点,都经历一遍为止,即w = vi为止;具体步骤的示意图如下图3.1所示:图3.1 迪杰斯特拉算法求最短路径的具体步骤3.3迪杰斯特拉算法的可行性分析及实际应用分析迪杰斯特拉算法的本质就是遍历一个图之中所有的点的一种最短路径算法7,算法的思想是以其中的一个点为起点,向该点的外围扩散,直到将所有的点,都经历一遍
2、为止,即w=vi为止;因此算法必然会在有限步后终止,不会出现死循环。所以,算法是可行的,也是正确的。问题1: 已知如图3.2 所示的单行线交通网, 它是一个有向图,每条弧旁的数字表示这条单行线的长度. 现在某人要从出发,通过这个交通网到去,求使下图中总路程最小的路径.图3.2引入基本变量: ij: 各边的权数,d(v1,vj):v1到vj的路的总权数的最小值P标号:从v1到vj 的最短路径的权数已确定T标号:从v1到vj 的最短路径的权数的上界Si: 算法进行到第 i 步时,具P标号点的集合.(v)=m:从vs到v的最短路上,v的前一个点是vm, (v)=0,则v = vs.(v) =M:D中
3、不含从vs到v的路;下面我们结合图表演示Dijkstra算法的基本步骤和基本原理我们用图表结全的方法讲述Dijkstra算法的基本步骤第一步: 因ij0,故 d(v1,v1)=0. v1加上P标号(图3.3中用划圈表示).图3.3表3.1 第一步被圈去的次序顶点从v1到该点的最短路的长度该节点的前一个节点1v1起点v2v3v4v5v6v7v8v9第二步:从v1共发出3条弧,(v1,v2),(v1,v3),(v1,v4).若从v1出发沿(v1,v2)到达v2,权数为 d(v1,v1) + 12 = 6;若从v1出发沿(v1,v3)到达v3,权数为 d(v1,v1) + 13 = 3;若从v1出发
4、沿(v1,v4)到达v4,权数为 d(v1,v1) + 14 = 1.mind(v1,v1) + 12, d(v1,v1) + 13,d(v1,v1) + 14 = min6, 3, 1= d(v1,v1) + 14 = 1故从v1出发到v4的路径的最小权必为1, 最短路是(v1,v4),d(v1,v4) =1,图3.4表3.2 第二步加P标号的次序632第三步:加上红圈的点表示具有P标号, 现考查从v1及v4指向其余点的弧从v1出发,分别沿(v1,v2)、(v1,v3)到达v2,v3,权数分另别为6和3,从v4出发,沿(v4,v6)到达v6,权数为 d(v1,v4) +46 = 1 +10=
5、11,mind(v1,v1) + 12,d(v1,v1) + 13,d(v1,v4) + 46 = min 6, 3, 11 = d(v1,v1) + 13 = 3故从v1到v3的最短路是(v1,v3),d(v1,v3)=3,v3加上P标号.图3.5表3.3 第3步11第四步:加上红圈的点表示具有P标号, 现考查从v1, v3和v4发出的弧. 从v1出发,沿(v1,v2)到达v2总权数为d (v1,v1) +126,从v3出发,沿(v3,v2)到达v2总权数为d(v1,v3) + 32=5,56, 因此到达v2的路径长度的上界应改为5, v2的前一个节点也应改为v3. 从v3出发,沿(v3,v
6、4)到达v4,因v4已具有P标号,不再参与计算. 从v4出发,沿(v4,v6)到达v6权数为 d(v1,v4) +46 = 1 +10=11,mind(v1,v1) + 12,d(v1,v3) + 32,d(v1,v4) + 46 = min 6, 5, 11 = d(v1,v3) + 13 = 5.故从v1到v2的最短路是(v1,v3,v2),d(v1,v2) = 5, v2加上P标号.图3.6表3.4 第4步46, 5v1,按照同样的方法,重复这个过程即可得到从v1出发到v8的最短路,最终的表格如下:表3.5 最终表格5711,10v49812从表中我们可以到得从从v1出发到v8的最短路的
7、长度为12,具体路短为:v8v5v2v3v1 .我们基于Dijkstra算法的基本原理, 应用C语言编写了计算机程序, 代码如下:#include#define MIN(x,y) (x=y ? x : y)void main() double a1010, v103, t; int i, j, k, n=9, m, i0, m0; for (i=0; i=n; i+) for (j=0; j0) continue; t = aij; if (t 0.0) continue; t += vi0; if (vj0 0) vj0 = t; vj2 = i; else if( t 0 | vj0 0) continue; t ) t = vj0; k = j; vk1 = 1.0; i = k; if (k = m) break; for (j=1; printf(%3d - %5.2f - %5.2f - %5.2fn, j, vj0, vj1, vj2); printf(The least chain is: %d, m); k = (int) (vm02); - %d, k); m0 = k; if(k = i0) break;运行程序,我们得到的结果, 如图3.7所示,与我们表上作业方法所得的结果完全一致. 图3.7 Dijkstra算法求解问题1