1. 程式人生 > >floyd演算法和動態規劃的關係

floyd演算法和動態規劃的關係

網上講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) }.

嗯,就是這樣.