Floyed理解「建议收藏」

Floyed理解「建议收藏」Floyed理解 Floyd算法的本质是动态规划,其转移方程为:f(k,i,j)=min(f(k-1,i,j),f(k-1,i,k)+f(k-1,k,j))。f(k-1,i,j)表示经过前k-1个点f(k-1,i,k)+f(k-1,k,j)表示经过k这个点f(k,i,j)表示路径除开起点i与终点j,只经过前k个点中的某些点,从i到j的最小值。计算这个值只需要考…

大家好,又见面了,我是你们的朋友全栈君。

Floyed理解

Floyed理解「建议收藏」

 

Floyd算法的本质是动态规划,其转移方程为:f(k,i,j) = min( f(k-1,i,j), f(k-1,i,k)+f(k-1,k,j) )。

f(k-1,i,j)表示经过前k-1个点

f(k-1,i,k)+f(k-1,k,j)表示经过k这个点

f(k,i,j)表示路径除开起点i与终点j,只经过前k个点中的某些点,从i到j的最小值。

计算这个值只需要考虑两种情况:最短路经过k,和最短路不经过k(那么就经过前k-1个点中的某些点)。

由于k要从k-1转移而来,自然k为最外层的循环。而经过状态压缩(类似于背包问题)后,就变成了我们熟悉的f(i,j) = min( f(i,j), f(i,k)+f(k,j) )了。

 

 

接下来,是Floyd算法的更新过程。归纳一下它的更新过程,其实就是,每一次尝试在每一对节点Vv和Vw之间插入一个节点Vk,如果插入节点后,可以使得Vv和Vw之间的路径变短,那么进行一次更新,否则不更新。

那么,为什么按照这样的规则更新可以找到每对节点间的最短路径呢?我在这里举个例子说明一下,应该就可以把这个问题解释清楚了。假设我们事先已经知道从节点V2到V5之间的最短路径是:V2→V4→V9→V7→V5。

第一步,在初始化过程中,我们获得了(*D)[2][9]、(*D)[9][5]、(*D)[2][5]以及(*P)[2][9]、(*P)[9][5]、(*P)[2][5]的初始值。

第二步,按照Floyd算法进行迭代,迭代到k等于4时,我们会发现在V2和V9之间插入V4之后,V2和V9之间的路径长度达到了史上最低点,(*D)[2][9]更新为(*D)[2][4]+(*D)[4][9],(*P)[2][9]更新为4。而且在之后的迭代中都不会出现更短的路径,所以(*D)[2][9]和(*P)[2][9]在之后的迭代中都不会发生改变。

第三步,迭代到k等于7时,V9和V5之间的路径长度达到了史上最低点,(*D)[9][5]更新为(*D)[9][7]+(*D)[7][5],(*P)[9][5]更新为7,此后不再改变。

第四步,迭代到k等于9时,V2和V5之间的路径长度达到了史上最低点,(*D)[2][5]更新为(*D)[2][9]+(*D)[9][5],(*P)[2][5]更新为9,此后不再改变。这样也就找到了V2和V5之间的最短路径。

现在,我们算出了V2和V5之间的最短路径的长度,但是,怎样找到这条路径的轨迹呢?其实就是根据*P来推断。以上面的例子为例,如果我们要打印V2和V5之间的最短路径的轨迹。首先我们知道(*P)[2][5]=9,初步确定轨迹为V2→V9→V5。根据(*P)[2][9]=4且(*P)[9][5]=7,初步确定轨迹为V2→V4→V9→V7→V5。根据(*P)[2][4]=2,(*P)[4][9]=4,(*P)[9][7]=9,(*P)[7][5]=7,我们可以确定没有新的节点需要加入,所以确定最终的轨迹为V2→V4→V9→V7→V5。

 

Floyed题目推荐:

【P1119】灾后重建 – 洛谷
https://www.luogu.org/problem/show?pid=1119

【P1078】文化之旅 – 洛谷
https://www.luogu.org/problem/show?pid=1078

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/148322.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Qt播放器学习

    Qt播放器学习Phonon库安装:进入源代码的phonon目录,如”../qt-everywhere-opensource-src-4.6.0/src/phonon”,实际代码并不在里面,从phonon.pro文件可知源代码在“/src/3rdparty/phonon/phonon”,但并不影响编译。在终端输入“make;makeinstall”即可,如果安装时出错,也可手动将lib、includ

    2022年6月10日
  • java单例模式代码实现方式_java单例模式实现方式

    java单例模式代码实现方式_java单例模式实现方式JAVA常见的设计模式之单例模式 懒汉模式 懒汉式是典型的时间换空间,也就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间(搬运工)。标准的懒汉模式classLazySingleton{//私有成员属性privateLazySingletonlazySingleton;//私有构造方法privateLazySingleto…

    2022年8月11日
  • Zigbee协议栈ZStack构架

    Zigbee协议栈ZStack构架协议栈版本信息:ZigBee2006\ZStack-1.4.3-1.2.11、ZStack协议栈构架  Zigbee协议栈就是将各个层定义的协议都集合在一起,以函数的形式实现,并给用户提供一些应用层API,供用户调用。协议栈体系分层架构与协议栈代码文件夹对应表如下:   整个协议栈的构架,如图所示APP:应用层目录,这是用户创建各种不同工程的区域,在这个目录

    2022年5月8日
  • Android触摸屏事件派发机制详解与源码分析三(Activity篇)

    Android触摸屏事件派发机制详解与源码分析三(Activity篇)PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊!【工匠若水http://blog.csdn.net/yanbober】该篇承接上一篇《Android触摸屏事件派发机制详解与源码分析二(ViewGroup篇)》,阅读本篇之前建议先阅读。1背景还记得前面两篇从Android的基础最小元素控件(View)到ViewGr

    2022年9月11日
  • pytest skipif_pytest不是内部或外部命令

    pytest skipif_pytest不是内部或外部命令前言pytest.mark.skip可以标记无法在某些平台上运行的测试功能,或者您希望失败的测试功能Skip和xfail:处理那些不会成功的测试用例你可以对那些在某些特定平台上不能运行的测试用

    2022年7月29日
  • [面试题]25个MySQL经典面试题「建议收藏」

    [面试题]25个MySQL经典面试题「建议收藏」经典题目1、MySQL的复制原理以及流程基本原理流程,3个线程以及之间的关联;2、MySQL中myisam与innodb的区别,至少5点2.1问5点不同;2.2innodb引擎的4大特性2.32者selectcount(*)哪个更快,为什么3、MySQL中varchar与char的区别以及varchar(50)中的50代表的涵义3.1varchar与char的区别3.2…

    2022年8月27日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号