所有结点对的最短路径问题:本章对于给出信息的方式的不同 最短路径和矩阵乘法

显然,对于问题:所有结点对的最短路径问题,我们需要找到图中任何两个结点间的最短路径。同时,我们能轻易得对上一章所学的Bellman_Ford或是Dijkstra算法对每个结点都调用一次而得出结果——但显然,将会浪费很多时间。

以Dijkstra算法为例,若实现它的方式为数组实现,那么Extract会搜索整个数组,消耗O(|V|)的时间——加上外层嵌套的while循环,同时处理边所用到的时间为|E|,那么算法运行的总时间为O(|V|² + |E|) = O(|V|²)。而调用 n 次,也就需要O(|V|³)的时间。

至于在图稀疏的情况下,若 E = o(\frac{V^{2}}{lgV})采用二叉堆实现:隐藏在Relax操作中的DecreaseKey、Extract_Min均消耗O(lgV)的时间,并且我们仍然只对所有的边进行一次Relax操作,因此共有|E|次DecreaseKey,|V|次Extract_Min操作;同时对原来以数组形式表示的图进行Build_Min_Heap操作会消耗O(n)时间——虽然看上去为O(nlgn)次,不过若我们更为精确地计算:每一层高度为 h 的结点,它的Max_Heapify操作并不完全等于堆的高度,而是等于它本身的高度h。这样一来,计算所有有儿子的结点处理时间的∑运算便能得出O(n)的结果。(其中高度h层的结点数目为:\frac{n}{2^{h+1}},式中 n 是高度的函数,而非总元素数目,同样设最底下一层为0层)

详细的证明见书P88,在此我们仍需要把重点放在图中。

经过上述的计算,我们得到了总运行时间O((V+E)lgV)的结果,同时,至于为什么能够在从源节点出发的条件下达到O(ElgV)的结果,我目前还不清楚。猜测可能是由于当从源节点出发能够到达所有结点时,在处理完毕源节点后,对于后面的结点,在Max_Heapify中,将A[A.heapsize]换到堆的顶部时,只下渗与高度有关的次数:即下渗到同样d值为∞的层数便停止——因此,其与以上关于Build_Min_Heap的证明类似,对整体摊还分析产生的结果为O(V),即O(V+ElgV) = O(ElgV)。同时,在E = o(\frac{V^{2}}{lgV})的条件下,得到有O(V²)的结果。

对于我们来说,从直觉上来看,ElgV是小于V²的——但请不要忽略,E做到的是连接图中的顶点,因此它应该比V大的多——甚至在最大的情况下,会达到V!的水平。

以上是通过二叉堆进行优化,不过在此之后,还能通过斐波那契堆进行优化——由于extract_min的摊还时间为θ(lgn),同时DecreaseKey甚至达到了Θ(1)的时间。(这个堆的实现不难,不过时间摊还分析有一定的难度)因此使用它将会使整个算法运行的时间到达O(

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值