最短路径学年论文
摘要:主要介绍最短路径问题中的经典算法——迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd)算法,以及在实际生活中的运用。
关键字:Dijkstra算法、Floyd算法、赋权图、最优路径、Matlab
目录
摘要 (1)
1引言 (1)
2最短路 (2)
2.1 最短路的定义 (2)
2.2最短路问题常见算法 (2)
3 Dijkstra算法 (2)
3.1Dijkstra算法描述 (2)
3.2 Dijkstra算法举例 (3)
3.3算法的正确性和计算复杂性 (5)
3.3.1贪心选择性质 (5)
3.3.2最优子结构性质 (6)
3.3.3 计算复杂性 (7)
4 Floyd算法 (7)
4.1Floyd算法描述 (8)
4.2 Floyd算法步骤 (11)
4.3 Floyd算法举例 (11)
5 Dijkstra算法和Floyd算法在求最短路的异同 (11)
6 利用计算机程序模拟算法 (11)
7 附录 (11)
8 论文总结 (13)
9 参考文献 (13)
1 引言
最短路问题是图论理论的一个经典问题。寻找最短路径就是在指定网络中两结点间找一条距离最小的路。最短路不仅仅指一般地理意义上的距离最短,还可以引申到其它的度量,如时间、费用、线路容量等。
最短路径算法的选择与实现是通道路线设计的基础,最短路径算法是计算机科学与地理信息科学等领域的研究热点,很多网络相关问题均可纳入最短路径问题的范畴之中。经典的图论与不断发展完善的计算机数据结构及算法的有效结合使得新的最短路径算法不断涌现。 2 最短路
2.1 最短路的定义
对最短路问题的研究早在上个世纪60年代以前就卓有成效了,其中对赋权图 的有效算法是由荷兰著名计算机专家E.W.Dijkstra 在1959年首次提出的,该算法能够解决两指定点间的最短路,也可以求解图G 中一特定点到其它各顶点的最短路。后来海斯在Dijkstra 算法的基础之上提出了海斯算法。但这两种算法都不能解决含有负权的图的最短路问题。因此由Ford 提出了Ford 算法,它能有效地解决含有负权的最短路问题。但在现实生活中,我们所遇到的问题大都不含负权,所以我们在的()
0ij w ≥的情况下选择Dijkstra 算法。
定义1若图G=G(V,E)中各边e 都赋有一个实数W(e),称为边e 的权,则称这种图为赋权图,记为G=G(V,E,W)。
定义2若图G=G(V,E)是赋权图且()0W e ≥,()e E G ∈,假设[i,j] 的权记为()i j W ,,若i 与j 之间没有边相连接,那么()i j =W ∞,。路径P 的定义为路径中各边的长度之和,记W (P )。图G 的结点u 到结点v 距离记为d(u,v),则u 、v 间的最短路径可定义为
{
()min P 0d(u,v)=,u v W =∞(),不可达时
。
2.2 最短路问题常见算法
在求解网络图上节点间最短路径的方法中,目前国内外一致公认的较好算法有迪杰斯特拉(Dijkstra)及弗罗伊德(Floyd)算法。这两种算法中,网络被抽象为一个图论中定义的有向或无向图,并利用图的节点邻接矩阵记录点间的关联信息。在进行图的遍历以搜索最短路径时,以该矩阵为基础不断进行目标值的最小性判别,直到获得最后的优化路径。
Dijkstra 算法是图论中确定最短路的基本方法,也是其它算法的基础。为了求出赋权图中任意两结点之间的最短路径,通常采用两种方法。一种方法是每次以一个结点为源点,重复执行Dijkstra 算法n 次。另一种方法是由Floyd 于1962年提出的Floyd 算法,其时间复杂度为
()3O n ,虽然与重复执行Dijkstra 算法n 次的时间复杂度相同,但其形式上略为简单,且实际运
算效果要好于前者。 3 Dijkstra 算法 3.1 Dijkstra 算法描述
Dijkstra 算法是解但愿最短路径问题的一个贪心算法。其基本思想是,设置顶点集合S 并不断地做贪心选择来扩充这个集合。一个顶点属于集合S 当且仅当从源到该顶点的最短路径长度已知。初始时,S 中仅含有源。设u 是图G 的某一顶点,把从源到u 且中间只经过S 中顶点的路称为源到u 的特殊路径,并记录当前每个顶点所对应的特殊路径长度。Dijkstra 算法每次从V —S 中取出具有最短路径长度的顶点u ,将u 添加到S 中,同时对短路径进行修改。一旦S 包含了所有V 中顶点,那么最后记录的最短路径就是源到所有其他顶点之间的最短路径长度。
算法要点如下:
(1) 把V 分为两个子集S 和T 。初始时,S={a},T=V-S ,其中a 为源点; (2) 对T 中每一个元素t 计算D (t ),根据D (t )值找出T 中距a 最短的一结点x ,
写出a 到x 的最短路径长度D (x );
(3) 更新S ,置S 为S {x},更新T ,置T 为T-{x},判断条件:若T=?,则终止,
否则再重复(2)。
3.2 Dijkstra 算法举例
问题的提出,给定一个带权有向图(既有向网)G 和源点Vo ,求Vo 到G 中其他每个顶点的最短路径。限定各边上的权值必须不小于0.如下图所示:
图1 公路网络赋权图
为了方便计算,先作出该网络的距离邻接矩阵,如下:
123456123
456
05250159A 2108105802591020252
0v v v v v v v v v v v v ????∞∞∞????∞??=∞????∞??∞????∞∞∞??
设()(){}1234560,,,,,,j W v T v v s v v v v v -
==∞∈=,
第一次迭代
①计算()
,2,3,4,5,6j T v j =如下
()()(){}{}22112min ,min ,055T v T v W v w =+=∞+= ()()(){}{}33113min ,min ,022T v T v W v w =+=∞+= ()()(){}{}44114min ,min ,0T v T v W v w =+=∞+∞=∞ ()()56,T v T v =∞=∞
②取
(){}()3
2min j j
v s
T v T v ∈==,令()()332W v T v ==
③由于()36k n =≠=,令{}2456,,,,3s v v v v i -
==转(1) 第二次迭代:
①算()
,2,4,5,6j T v j =如下
()()(){}{}22323min ,min 5,213T v T v W v w =+=+= ()()(){}{}44334min ,min 8,288T v T v W v w =+=+= ()()(){}{}55335min ,min 10,21010T v T v W v w =+=+= ()()(){}{}66336min ,min ,2T v T v W v w =+=∞+∞=∞
②取(){}()2
min 3j j
v s
T v T v -
∈==令()()22
3W v T v ==
③由于()26k n =≠=,令{}456,,2s v v v i -
==转(1) 第三次迭代:
①算()
,4,5,6j T v j =如下
()()(){}{}44224min ,min 8,358T v T v W v w =+=+= ()()(){}{}55225min ,min 10,3910T v T v W v w =+=+= ()6T v =∞
②取(){}()()()4
4
4
min 8,8j j
v s
T v T v W v T v -
∈====
③由于()46k n =≠=,令{}56,4s v v i -
==转(1) 第四次迭代:
①算()
,5,6j T v j =如下
()()(){}{}55445min ,min 10,2810T v T v W v w =+=+= ()()(){}{}66446min ,min ,8513T v T v W v w =+=∞+=
②取(){}()()()5
5
5
min 10,10j j
v s
T v T v W v T v -
∈====
③由于()56k n =≠=,令{}6s v -
=转(1) 第五次迭代:
①算()
,6j T v j =如下
()()(){}{}66556min ,min 13,10212T v T v W v w =+=+=
②由于6k n ==。因此已找到1v 到6v 的最短距离为12。计算结束。 对应的迭代表格如下:
找最短路线:逆向追踪得132456v v v v v v →→→→→ 最短距离为12,即从城市1v 到城市6v 的距离最短,即费用最省。
3.3算法的正确性和计算复杂性 3.3.1贪心选择性质
Dijkstra 算法是贪心算法策略的一个典型例子。它所做的贪心选择是从V —S 中选择具有最短特殊路径的顶点u ,从而确定从源到u 的最短路径长度dist[u]。这种贪心选择导致最
优解在于如果存在一条源到u 且长度比dist[u]更短的路,设这条路初次走出S 之外到达的顶点x V S ∈—,然后徘徊于S 内外若干次,最后离开S 到达u ,如图2所示。
在这条路径上,分别标记d(v,x),d(x,u)和d(v,u)为顶点v 到顶点x ,顶点x 到顶点u 和顶点v 到顶点u 的路长,那么有:
dist[x]d(v,x)≤
d(v,x)+d(x,u)=d(v,u) 利用权边的非负性,可知d(v,x)0≥,从而推出dist[x]dist[u]≤。此为矛盾。这就证明了dist[u]是从源点到u 的最短路径长度。 图2 从源到u 的最短路径 3.3.2最优子结构性质 要完成Dijkstra 算法正确性的证明,还必须证明最优子结构性质,即算法中确定的 dist[u]确实是当前从源到顶点u 的最短特殊路径长度。为此,只要考察算法在添加u 到S 中后,dist[u]的值所起的变化。将添加u 之前的S 成为老S 。当添加了u 之后,可能出现一条到顶点i 的新的特殊路。如果这条新特殊路是先经过老S 到达顶点u ,然后从u 经一条边直接到达顶点i ,则这种路的最短的长度是dist[u]+c[u][i]。此时如果 dist[u]+c[u][i] 径经过老S 到达u 后,不是从u 经过一条边直接到达i ,而是像图3那样,回到老S 中某个顶点x ,最后才到达顶点i ,那么由于x 在老S 中,因此x 比u 先加入S ,所以图3中从源到x 的路的长度比从源到u ,再从u 到x 的路的长度小。于是当前dist[i]的值小于从源经x 到i 的路的长度,也小于图中从源经u 和x ,最后到达i 的路的长度。因此,在计算中不必考虑这种路。由此可知,不论算法中dist[u]的值是否发生变化,它总是关于当前顶点集S 到达u 的最短特殊路径长度。 图3 非最短路径的特殊路径 3.3.3 计算复杂性 对于一个具有n 个顶点和e 条带权边的图来说,如果用带权邻接矩阵表示这个图,那么Dijkstra 算法的主循环体需要O(n)的时间。这个循环体需要执行n-1次,所以完成循环需要 2O(n )时间。算法的其余部分所需要的时间不超过2O(n )。 4 Floyd 算法 4.1 Floyd 算法描述 Floyd 算法又称距离矩阵法,算法主要是寻找加权图中任意两个结点间最短路径的算法。其基本思想是:两结点间的最短路径要么是相邻时最短,要么是以通过几个中间结点为跳板时距离最短。算法每次以其中一个结点为跳板,如果以该结点为跳板后两结点间路径缩短,则更新这两结点间的路径。算法执行n 次结束,直到测试完每个充当跳板的结点。若用Dijkstra 算法计算任意两点间的最短路径,需要执行n 次,且图中含有负权值时不能用Dijkstra 算法。Floyd 算法只能求出两点间最短路径的长度,无法得到这条最短路径,当然,如果记录了每步更新所经过的中间结点,仍可通过回溯得到两点间的最短路径。 4.2 Floyd 算法步骤 对于图G ,如果(,)w i j 表示i 和j 之间的可实现的距离,那么(,)w i j 表示端i 和j 之间的最短距离当且仅当对于任意的i, j, k ,有(,)(,)(,)w i j w i k w k j ≤+。该算法用矩阵形式来表示,并进行系统化的计算,通过迭代来消除不满足上述定理的情况,对于n 个端,一给定边长ij d 的图,顺序计算各个n n ?的W 阵和R 阵,前者代表径长,后者代表转接路由。 其步骤如下: 0F :置 (0)(0)[]ij ij W w = 其中 和 0(0)[]ij R r = 其中 1F :已得(1)k W - 和(1)k R - 阵,求()k W 和()k R 阵中的元素如下 2F :k 由上述步骤可见,(1) ()k k W W -→ 是计算经k v 转接时是否能缩短经常,如有缩短,更 改ij w 并在R 阵中记下转接的端。最后算得() n W 和() n R ,就得到了最短径长和转接路由。 4.3 Floyd 算法实例 假设某旅游路线的赋权图如下: 图4 某旅游路线赋权图 ,,0ij i j ij i j d v v w v v i j ??=∞ ??=? 有边无边(0) (0) (0) 0ij ij ij w j r w i j <∞?= ?=∞ =?或()(1)(1)(1)min[,] k k k k ij ij ik kj w w w w ---=+(1)()(1)(1) (1) ,,k k k ij ij ij k ij k k k ik ij ij r w w r r w w ----? =?=? ?若若 现在我们以上述生成的图4为考察对象,根据算法流程,设W阵和R阵分别代表路径长和转接路由。那么计算结果如下: (0)041 40144 1409 90912 9066 1601 412610 W ∞∞∞∞ ?? ?? ∞∞∞ ?? ?? ∞∞∞∞ ?? =∞∞∞ ?? ?? ∞∞∞ ?? ∞∞∞ ?? ?? ∞∞ ?? (0) 0200060 1030007 0204000 0030507 0004067 1000507 0204560 R ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ??(1) 041 4014(5)4 1409 90912 9066 1(5)601 412610 W ∞∞∞∞ ?? ?? ∞∞ ?? ?? ∞∞∞∞ ?? =∞∞∞ ?? ?? ∞∞∞ ?? ∞∞ ?? ?? ∞∞ ?? (1) 0200060 10300(1)7 0204000 0030507 0004067 1(1)00507 0204560 R ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ??(2) 04(18)1(8) 401454 (18)1409(19)(18) 90912 9066 15(19)601 (8)4(18)12610 W ∞∞ ?? ?? ∞∞ ?? ?? ∞ ?? =∞∞∞ ?? ?? ∞∞∞ ?? ∞ ?? ?? ?? (2) 02(2)006(2) 1030017 (2)2040(2)(2) 0030507 0004067 11(2)0507 (2)2(2)4560 R ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ?? (3) 0418(27)18 4014(23)54 1814091918 (27)(23)909(28)12 9066 1519(28)601 841812610 W ∞ ?? ?? ∞ ?? ?? ∞ ?? =?? ?? ∞∞∞ ?? ?? ?? ?? (3) 022(3)062 103(3)017 2204022 (3)(3)305(3)7 0004067 112(3)507 2224560 R ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ?? (4) 041827(36)18 401423(32)54 181409(18)1918 27239092812 (36)(32)(18)9066 151928601 841812610 W ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ?? (4) 0223(4)62 1033(4)17 2204(4)22 3330537 (4)(4)(4)4067 1123507 2224560 R ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ?? (5) 0418273618 4014233254 181409181918 2723909(15)12 3632189066 1519(15)601 841812610 W ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ?? (5) 0223462 1033417 2204422 33305(5)7 4444067 112(5)507 2224560 R ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ?? (6) 0418(16)(7)1(2) 4014(20)(11)54 181409181918 (16)(20)9091512 (7)(11)189066 151915601 (2)41812610 W ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ?? (6) 022(6)(6)6(6) 103(6)(6)17 2204422 (6)(6)30557 (6)(6)44067 1125507 (6)224560 R ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ??(7) 0418(14)712 4014(16)(10)54 181409181918 (14)(16)909(13)12 7(10)189066 1519(13)601 241812610 W ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ?? (7) 022(7)666 103(7)(7)17 2204422 (7)(7)305(7)7 6(7)44067 112(7)507 6224560 R ?? ?? ?? ?? ?? =?? ?? ?? ?? ?? ?? 经过7轮迭代,我们得到了最终的W 和R 阵,分别包含了径长信息和路由信息。我们可以从(7) W 和(7)R 中找到任何两个端点间的最短径长和最短路由,对应着我们所建立的旅 行线路模型中的任何两景点间的最短路径长度和路线。 若要求旅游点3到点1的最短路径,则可以从(7)M 中找到对应的最小值为18,从(7)R 中找到312r =,就是要经点2转接;再看211r =,此时已经到达目的节点,所以路由是 321→→点点点。 5 Dijkstra 算法和Floyd 算法在求最短路径的异同 相同: ① 是按路径长度递增的思路进行查找最短路径。 ② 都需要借助带权领接矩阵; ③ 都引进了辅助数组; ④ Floyd 法的替代算法是n 次调用Dijkstra 法(n 为图G 中结点数目)。 相异: ① Dijkstra 算法是从一点出发到其余路径的最短路径,而Floyd 算法是找图中所有顶点间的最短路径; ② Dijkstra 算法是找到最短后再尝试利用该最短辅助找其余最短的;而Floyd 算法是在插入第i-1个顶点的基础上比较插入第i 个后和之前的最短; ③ 路径长度递增不一样:Dijkstra 算法增的路径是比较出最短的增,而Floyd 算法增的路径是按编号递增; ⑤ Dijkstra 算法从源点出发,而弗法可以从任意点出发; ⑤ 结果不同,Dijkstra 算法找到的是从源点到其余顶点的最短路径;Floyd 算法则可以求任两点之间的最短路径。 6 利用计算机程序模拟算法 对于图G 来说,如果G 中的结点个数较少,可以通过逐步迭代或者通过以上的列表形式算出不同点之间的最短路径,但相对于结点数目较多的图而言,显得力不从心,也大大增加了计算过程中的失误率。这个时候,我们就迫切希望寻求算学工具来解决人工的局限性。为此引入Matlab 来简化求解步骤,通过输入邻接矩阵和始末点来快速计算最短路径的值,并导出途经各结点。 其中Dijkstra 算法中的例子,可以另16v ~v 对应于标号1~6,邻接矩阵为A ,通过调用Matlab 功能函数可迅速得出最优路径及相关途经点。程序见附录。 7 附录 Dijkstra 算法: function [d,path]=dijkstra(W,s,t) [n,m]=size(W);ix=(W==0);W(ix)=inf; if n~=m,error('Square W required');end visited(1:n)=0; dist(1:n)=inf;parent(1:n)=0;dist(s)=0;d=inf; for i=1:(n-1), ix=(visited==0);vec(1:n)=inf;vec(ix)=dist(ix); [a,u]=min(vec);visited(u)=1; for v=1:n,if (W(u,v)+dist(u) dist(v)=dist(u)+W(u,v);parent(v)=u; end;end;end if parent(t)~=0,path=t;d=dist(t); while t~=s,p=parent(t);path=[p path];t=p;end; end Floyd算法: function [d,r]=floyd(a) n=size(a,1); d=a; for i=1:n for j=1:n r(i,j)=j; end end r for k=1:n for i=1:n for j=1:n if d(i,k)+d(k,j) d(i,j)=d(i,k)+d(k,j); r(i,j)=r(i,k) end end end k d r end 8论文总结 本文将最短路径理论应用到实际生活中,具有很重要的意义。将实际生活中出现的问题进行优化解决。同时也凸显出学习和应用最短路问题原理的重要性。另外,最短路问题在城市道路建设、物资供应站选址等问题上也有很重要的作用,分析和研究最短路问题将趋于热门化。 9 参考文献 [1] 计算机算法设计与分析王晓东著电子工业出版社 [2] 离散数学方世昌著西安电子科技大学出版社 [3] Matlab程序设计教程刘卫国著中国水利水电出版社 [4] 数学建模简明教程袁震东、蒋鲁敏、束金龙著华东师范大学出版社 [5] 数据结构(C语言版)严蔚敏、吴伟民著清华大学出版社