floyed算法的一些感想
雖然我還在學動態規劃,但這並不影響我去試圖研究floyed,在對floyed算法進行研究了40min後,我感覺我似乎應該好像是勉強理解了floyed算法
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=k;j++)
if(f[i][k]+f[k][j]<f[i][j])
f[i][j]=f[i][k]+f[k][j];
以上為floyed的基礎模板。Floyed算法,用來計算這個圖上任意點對間的距離,3重循環,簡單思考便知道,k表示要i - k和k - j去嘗試更新i – j。
Floyed算法最神奇的地方在於k循環的位置,為什麽要放在最外層而不是最內層,簡單思索後,放在最外層是用k點一次更新所有點的距離,而放在最內層則是將i—j的距離嘗試用所有點k去更新,乍一看似乎沒有什麽區別?好像是一樣的,但是我們實際手動推算就會發現,沒有這麽簡單!(沒錯就是手推,雖然暴力,但是極其有效。)
我們來想想這有什麽區別先:
外層:用k更新所有i—j
內層:枚舉所有k來更新i—j
區別就在於這兩種更新方式的順序變了,那麽放在內層會產生如何影響呢?
for(int i=1;i<=n;i++)
for(int j=1;j<=k;j++)
for(int k=1;k<=n;k++)
if(f[i][k]+f[k][j]<f[i][j])
f[i][j]=f[i][k]+f[k][j];
如果k層在最內層,就是每次更新i—j時都要枚舉一遍k點,但實際上,i—k卻沒有更新過,所以導致i—j無法更新,然後就會產生惡性循環,然後boom的炸掉,到最後也許只有幾個幸運點對成功更新出正確距離
但是在外層呢?我們不得不贊嘆floyed算法的強大與神奇,因為k點一次更新了所有的點對,所以在進行後續更新操作時,i—k的距離是肯定被更新過了的,保證了算法的正確性,感覺之所以說floyed用到了動態規劃思想的原因實際是下一個i—j中,距離是否被更新,只與與j直接相連的k點的所記錄的值,即i—k和k—j這個定值有關。
最後感嘆floyed算法的強大與神奇。
floyed算法的一些感想