floyd算法和动态规划的关系

来源:互联网 发布:ubuntu 22端口被拒绝 编辑:程序博客网 时间:2024/06/05 20:25

网上讲floyd算法的不少,不过都知道这是动态规划算法的应用,我却没看到几个说明白的,又是那种给你证明这么做是对的的方式,或者还有从前往后推不断加入中介点的,看着貌似正确,实际上根本没体现动态规划的思想所在.

动态规划算法,那自然是从后往前推才对,我就从后往前推来说明一下怎么推导出floyd算法的,即正常的思考过程,不是证明过程.

假设有5个点,1,2,3,4,5.我想求1到5的最短路径.

okay,根据动态规划的思想,从后往前推,那么类似背包问题,我们考虑对可能的最短路径进行情况划分:①最短路径包含4 ②最短路径不包含4

分析①:

最短路径包含4,那么这路径分为两段,第一段:1通过[1,2,3]到达4的最短路径;第二段:4通过[1,2,3]到达5的最短路径.注意中间点集合为[1,2,3],没有5,因为有5的话那就“绕路”了.

另外这里的1通过[1,2,3]到达4并不意味着中间点1,2,3全在路径上(当然1作为源点肯定在),只是表明这是可供选择的中间点的集合.

分析②:

最短路径不包含4,那就直接1通过[1,2,3]到达5的最短路径.

回头看看原问题的表述:1到5的最短路径.即1通过[1,2,3,4]到达5的最短路径.

数学化的表达一下:

L(1,[1,2,3,4],5)=min{ L(1,[1,2,3],4)+L(4,[1,2,3],5),L(1,[1,2,3],5) }.

okay,看到什么了?左边是[1,2,3,4],右边清一色的[1,2,3]。

没错![1,2,3,4]被分解为了几个[1,2,3],子问题规模变小了,动态规划目的达到了。

要是觉得还不够清楚,再分解一下L(1,[1,2,3],4)

L(1,[1,2,3],4)=min{ L(1,[1,2],4)+L(3,[1,2],4),L(1,[1,2],4) }.

看到了吗?有3没3的两种路径都会分解为[1,2].从[1,2,3]又分解为了[1,2].

这样下去,[1,2,3,4]->[1,2,3]->[1,2]->[1]->[].

实际上以上状态转移方程写的还有一点小瑕疵,[1,2,3,4]应该放在括号最左边.

假设源点为i,终点为j,中间点集合的元素数为k.

那么为了求解k=4时的状态,我们需要求解所有k=3的状态,

为了求解k=3时的状态,我们需要求解所有k=2的状态。。。

所谓所有k=3的状态,就是{i:1到5变化,j:1到5变化.k=3} 对应的各种状态.

所以k应该放在最左边,因为它是最外层循环.

L([1,2,3,4],1,5)=min{ L([1,2,3],1,4)+L([1,2,3],4,5),L([1,2,3],1,5) }.

嗯,就是这样.

原创粉丝点击