算法(三):動態規劃

不從定義等角度來考慮動態規劃的含義,而只是從解決問題的思路上來說明如何將問題化繁爲簡。

問題特點

通過一個經典的動態規劃來了解動態規劃問題。
如下一個圖,求出從起始點到終止點的最短路徑:
問題描述
初看起來,這個問題就是一個最短路徑問題,使用迪傑斯特拉最短路徑,或者弗洛伊德算法,甚至A*算法都可以完美求解。
但如果再仔細觀察,就可以發現另一個特徵,即階段特徵,上面的圖的路徑都是分爲階段的:
剔除路徑的圖
我們將路徑剔除,但保留路徑的連接關係,可以看出,原圖可以分爲4個階段,相鄰的階段間有路徑項鍊,階段內部沒有路徑。
這也是動態規劃的一般思路,即整體可以分爲多個階段,階段與階段間是相關的,通過階段的迭代求解,得出最終結果。

問題求解

上面的問題可以如下求解:
從最後一個階段開始,從後往前,求出當前階段到下一階段的最短路徑,一直到第一個階段:
階段一
1. 求出最後一個階段到倒數第二個階段的最短路徑
階段二
2. 求出當前階段到倒數第二階段的最短路徑
階段三
3. 問題的最後,求出最後的最短路徑

體會求解過程與貪婪算法的不同,動態規劃並沒有子問題的解是總體的一部分這種特性,所以,並不能簡單的套用貪婪算法。
通常來說,最有效的方法是能夠使用圖來表示動態規劃問題,這樣求解的方法就會一目瞭然。

總結:動態規劃的全局最優不一定包含局部最優,因此每次的轉檯轉移需要記錄下之前的所有最優解;而貪心算法每一步的最優解都是全局最優的一部分。

問題延伸

最後以一個百度的筆試算法題最爲結束:
小明上班的模式有兩種——加班和不加班。加班的工資要比不加班要高,但加班後第二天不能上班,只能休息。給定每天的加班工資和不加班工資,求出最優的上班選擇。
數據如下:
第一天:12 10
第二天:5 1
第三天:11 4
第四天:8 7

問題分析

這是個典型的動態規劃問題,問題特點在於當天的選擇隻影響下一天的選擇。通過分析這種層級關係,我們可以建立對應的圖解模式:
問題轉化
即對於每一階段(每一天)可以有三種選擇——加班,正常上班,休息。
如果當前選擇加班,則下一年只能休息,一次表示的圖結構如上圖所示。
這樣問題就抽象成了經典的動態規劃解法。
然後在編程實現就不難了。

發佈了72 篇原創文章 · 獲贊 50 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章