1、(4)单源最短路径;(5)最小生成树;,学习要点,3,4.5 单源最短路径,给定带权有向图G=(V,E,W),其中每条边e=的权w(e)是非负实数,表示从i到j的距离。另外,还给定V中的一个顶点s,称为源。现在要计算从源到所有其它各顶点的最短路长度。这里路的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。1、算法基本思想 Dijkstra算法是解单源最短路径问题的贪心算法。,4,4.5 单源最短路径,其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点u属于集合S iff 从源s到u的最短路径长度已知。初始时,S中仅含有源 S=s,S=V时算法结束。设u是G的某一个
2、顶点从源s到u的特殊路径:从源到u且中间只经过S中顶点的路.distu:从s到u的最短特殊路径的长度shortu:从s到u的最短路径的长distu shortu,例,5,6,7,8,4.5 单源最短路径,每次从V-S中取出具有最短特殊路长度的顶点j,将j添加到S中,同时对disti 进行必要更新。,主循环体需要 时间。这个循环需要执行n-1次,所以完成循环需要 时间。,9,算法正确性,命题:当算法进行到第k 步时,对于S 中每个结点i,disti=shorti,归纳基础 k=1,S=s,dists=shorts=0,命题为真.,归纳步骤 假设命题对于k 为真.考虑k+1步,选择顶点v(边(u,
3、v).假若存在另一条s-v 路径L(绿色),最后一次出S 的顶点为x,在这次从S 中出来后经过V-S 的第一个顶点为y.,distv disty/v先被选,disty+d(y,v)L,distv=shortv,10,4.6 最小生成树,设G=(V,E,W)是无向连通带权图,即一个网络。E中每条边(v,w)的权为cvw。如果G的子图G是一棵包含G的所有顶点的树,则称G为G的生成树。生成树上各边权的总和称为该生成树的耗费(权)。在G的所有生成树中,耗费(权)最小的生成树称为G的最小生成树。网络的最小生成树在实际中有广泛应用。例如,在设计通信网络时,用图的顶点表示城市,用边(v,w)的权cvw表示建
4、立城市v和城市w之间的通信线路所需的费用,则最小生成树就给出了建立通信网络的最经济的方案。,11,4.6 最小生成树,命题 设G 是n 阶连通图,那么(1)T 是G 的生成树当且仅当T 有n1 条边.(2)若T 是G 的生成树,e T,那么Te含有一个圈(回路).,最小生成树性质:设G=(V,E)是连通带权图,S是V的真子集。如果(u,v)E,且uS,vV-S,且在所有这样的边中,(u,v)的权cuv最小,那么一定存在G的一棵最小生成树,它以(u,v)为其中一条边。这个性质有时也称为MST性质。,证明:假设G的任何最小生成树都不包含(u,v).将边(u,v)添加到G的一棵最小生成树上,将产生含
5、有边(u,v)的圈,且该圈中有一条不同于(u,v)的边(u,v),使得u S,vV-S.将(u,v)删去,得到另一棵生成树T.由于cuv最小,T的耗费T的。于是T是含(u,v)的最小生成树。,u,v,u,v,S,V-S,12,4.6 最小生成树,1.Prim算法 首先置S=1,然后,只要S是V的真子集,就作如下的贪心选择:选取满足条件iS,jV-S,且cij最小的边,将顶点j添加到S中。这个过程一直进行到S=V时为止。在这个过程中选取到的所有边恰好构成G的一棵最小生成树。,13,Prim算法-例,正确性证明,定理:对于任意k n,存在一棵最小生成树包含算法前k 步选择的边归纳基础:k=1,存在
6、一棵最小生成树T 包含边e=(1,i),其中(1,i)是所有关联1 的边中权最小的.设T 为一棵最小生成树,假设T 不包含(1,i),则T(1,i)含有一条回路,回路中关联1的另一条边为(1,j),令T=(T-(1,j)(1,i),则T也是生成树,且W(T)W(T).,14,归纳步骤:假设算法进行了k-1步,生成树的边为e1,e2,ek-1,这些边的k 个端点构成集合S.由归纳假设存在G 的一棵最小生成树T 包含这些边.算法第k 步选择了顶点ik+1,则ik+1到S中顶点的边权最小,设这条边为ek=(ik+1,il).由最小生成树性质,存在G 的一棵最小生成树,包含e1,e2,ek-1,ek.
7、,15,4.6 最小生成树,2.Kruskal算法首先将G的n个顶点看成n个孤立的连通分支。将所有的边按权从小到大排序。然后从第一条边开始,依边权递增的顺序查看每一条边,并按下述方法连接2个不同的连通分支:当查看到第k条边(v,w)时,如果端点v和w分别是当前2个不同的连通分支T1和T2中的顶点时,就用边(v,w)将T1和T2连接成一个连通分支,然后继续查看第k+1条边;如果端点v和w在当前的同一个连通分支中,就直接再查看第k+1条边。这个过程一直进行到只剩下一个连通分支时为止。,16,Kruskal算法-例,17,Kruskal算法正确性证明,18,命题:对于任意n1,算法对n 阶图得到一棵
8、最小生成树.证明:n=2,只有一条边,命题显然为真.假设对于n个顶点的图算法正确,考虑n+1个顶点的图G,G中最小权边e=(i,j),从G 中合并 i 和 j,得到图G.根据归纳假设,由算法可得G 的最小生成树T.令T=T e,则T 是关于G 的最小生成树.否则存在G 的含边e 的最小生成树T*,W(T*)W(T)(最小生成树性质).在T*中合并 i 和 j 得到G 的生成树T*-e,且W(T*-e)=W(T*)-w(e)W(T)-w(e)=W(T),与T 的最优性矛盾.,小结,19,(1)贪心算法适用于组合优化问题.求解过程是多步判断.判断的依据是局部最优策略,使目标值达到最大(或最小),与前面的子问题计算结果无关.(2)局部最优策略的选择是算法正确性的关键.(3)正确性证明方法:数学归纳法、交换论证.使用数学归纳法主要通过对算法步数或者问题规模进行归纳.如果要证明贪心策略是错误的,只需举出反例.(4)自顶向下求解,通过选择将问题归约为小的子问题.(5)如果对原始数据排序之后,贪心法往往是一轮处理,时间复杂度和空间复杂度低.,
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1