60 likes | 154 Views
6.3 最短路问题. 6.3.1 狄克斯特拉算法 ( Dijkstra algorithm, 1959) 计算两节点之间或一个节点到所有节点之间的最短路 令 d ij 表示 v i 到 v j 的直接距离 ( 两点之间有边 ) ,若两点之间没有边,则令 d ij = ,若 两点之间是有向边,则 d ji = ;令 d ii = 0 , s 表示始点, t 表示终点 0 、令 始点 T s =0 ,并用 框住, 所有其它节点临时标记 T j = ;
E N D
6.3最短路问题 6.3.1 狄克斯特拉算法 (Dijkstra algorithm, 1959) • 计算两节点之间或一个节点到所有节点之间的最短路 令dij表示vi到 vj的直接距离(两点之间有边),若两点之间没有边,则令 dij= ,若两点之间是有向边,则 dji= ;令 dii= 0,s表示始点,t表示终点 0、令始点Ts=0,并用框住,所有其它节点临时标记 Tj= ; 1、从 vs出发,对其相邻节点 vj1进行临时标记,有 Tj1=ds,j1; 2、在所有临时标记中找出最小者,并用框住,设其为 vr。若此时全部节点都永久标记,算法结束;否则到下一步; 3、从新的永久标记节点 vr出发,对其相邻的临时标记节点进行再标记,设 vj2为其相邻节点,则 Tj2=min{Tj2, Tr+dr,j2 },返回第2步。
例1 狄克斯特拉算法 11 10 31 0 15 12 8 13 15
Dijkstra最短路算法的特点和适应范围 • 一种隐阶段的动态规划方法 • 每次迭代只有一个节点获得永久标记,若有两个或两个以上节点的临时标记同时最小,可任选一个永久标记;总是从一个新的永久标记开始新一轮的临时标记,是一种深探法 • 被框住的永久标记 Tj 表示 vs到 vj的最短路,因此 要求 dij0,第 k 次迭代得到的永久标记,其最短路中最多有k条边,因此最多有n1次迭代 • 可以应用于简单有向图和混合图,在临时标记时,所谓相邻必须是箭头指向的节点;若第 n1次迭代后仍有节点的标记为 ,则表明 vs到该节点无有向路径 • 如果只求 vs到 vt的最短路,则当 vt得到永久标记算法就结束了;但算法复杂度是一样的 • 应用 Dijkstra 算法 n1次 ,可以求所有点间的最短路 • vs到所有点的最短路也是一棵生成树,但不是最小生成树
6.3.2 Warshall-Floyd算法 (1962) • Warshall-Floyd算法可以解决有负权值边(弧)的最短路问题 • 该算法是一种整体算法,一次求出所有点间的最短路 • 该算法不允许有负权值回路,但可以发现负权值回路 • 该算法基于基本的三角运算 定义 对给定的点间初始距离矩阵{dij},令dii=,对所有 i。对一 个固定点 j,运算 dik=min{dik, dij+djk}, 对所有 i, k j , 称为 三角运算。(注意,这里允许 i=k) 定理 依次对 j=1,2,…,n 执行三角运算,则 dik最终等于 i到 k间最短路的长度。
6.3.2 Floyd-Warshall 算法 (1962) • 若网路中存在负回路,则计算中,某些 dii 会小于0,此时应中断算法 • 显然,Floyd 算法要进行 n(n-1)2 次加法和比较 • 如何回溯找出任两点之间的最短路? • 在Floyd 算法中设一伴随矩阵E={eik}, eik记录了 i到k最短路中最后一个中间节点 for i=1 to n do dii=; for all eij=0; for j=1 to n do for i=1 to n do if ij then for k=1 to n do if kj then begin dik=min{dik, dij+djk}; if dik>dij+djk then eik=j end;
小结 • 最短路有广泛的应用 (6.3.4节 市话局扩容方案) • 最短路的多种形式:无向图,有向图无循环圈,有向图,混合图,无负边权,有负边权,有负回路,k-最短路等 • 当存在负权值边时,Floyd算法比Dijkstra算法效率高,且程序极简单。但Dijkstra算法灵活 • 若图是前向的,则Dijkstra算法也可以求两点间最长路 • 一般情况下,两点间最长路是 NP-complete,但最短路是 P算法 • 两点间k-最短路:分为边不相交的和边相交的 求边不相交的k-最短路非常容易:先求最短路,将该最短路中的边从网路删去,再用Dijkstra算法可求次最短路,以此类推