【演算法基礎】動態規劃的理解
本章是個很有趣的問題,也是難倒很多人的問題,同時這又是個會而不難的問題。
動態規劃的核心邏輯是:將問題分解為子問題。在《演算法圖解》這本書裡,深入淺出得講了遞推公式的推演邏輯,但是在關鍵部分,遞推公式部分,並沒給出邏輯。
整個過程好像是,前面一段道路很平緩,走起來很舒適,但是突然一個大臺階擋住了去路,本篇將試圖為這個臺階做一下鋪墊,讓這個過程更加容易理解一些。
主體仍然以書上的例子作為演示素材。
問題定義
揹包問題場景之一,可以盜竊的東西如下:
現在你的揹包容量只有4磅,目標是在容量允許的情況下,偷到最有價值的物品組合。
最直接的想法是遍歷,三個物品,每個物品都有被偷和不被偷的2種選擇,所以總共有 種選擇。
如果有 個物品,那麼問題的規模就變成了 次方,顯然這是不可接受的演算法。
現在看看用動態規劃如何解決。
動態規劃
現在把問題拆解為兩個方向:
- 增多物品選擇
- 增大揹包空間
所以這是兩個維度的擴充套件,我們用一個二維的表格來跟蹤問題的解決方案。
每個動態規劃演算法都從一個表格開始。
行為物品種類,列為揹包容量大小。
那麼在第一行的時候,意味著我們只能選擇吉他,吉他的重量是1磅,價值是1500美元
所以在揹包容量為1時,最大價值是1500美元,容量為2,3,4時都是1500美元,因為此時只有一個選擇。
所以第一行填滿了:
現在我們擴大物品選擇選項,即音響也可以納入選擇了。我們此時來填第二行。
這裡我們即可以講講填充時的指導規則,而不是自己在腦海裡遍歷。。我們對選項不多的問題,天然有遍歷的傾向,然後問題擴大時,又因為沒有指導規則,就會手足無措。
現在有音響了,意味著我們可以選擇兩個物品:
- 吉他:重1磅,價值1500美金
- 音響:重4磅,價值3000美金
我們現在來填第二行第一格。我們可以這麼想,我們到底有多少選擇呢?
其中揹包空間是1磅重,其實我們就兩個選擇:
- 不選擇音響
- 選擇音響
如果不選擇音響的話,我們就可以不看第二行了,直接把條件再綜合一下:
- 不選擇音響(只有吉他可選)
- 揹包大小為1
能夠偷到的價值是不是和第一行第一列的數值1500美元一樣?
是的。但這只是第一個選擇。如果是第二個選擇呢?我們確定要選擇音響,但是一算,音響重4磅,裝不下,所以最終答案就只能是1500美元。
這個邏輯理解的話,我們可以直接上遞推公式了:
這兩個選項就分別對應著:當前的商品選還是不選,如果不選,那麼最大價值就是上面一行且同列的值,同列的原因是揹包容量大小相同。
如果選的話,條件也是當前物品能放進揹包,放不進去就談不上第二種選擇了。現在是能選,選上了以後,該物品的價值是到手了的。但是空間不一定用完,因此,我們再去查上一行,對應剩餘空間能裝的物品價值。
注:這個揹包問題的背景設定是每個物品只有一個。現在的被選了,那麼就回退到上一行來看剩餘空間可裝多少價值的問題。
上面的公式可以進一步寫成:
公式拿到,我們現在來繼續填充表格:
有了這個表格,我們就可以知道,在三個物品可選,且揹包大小為4時,最大可偷價值為3500。
即,表格一旦達成,問題解答就變成直接查表即可。
假定現在我們增加一個商品,一個手機,重量為1磅,價值為2000美金。我們知道吉他價值1500,重1磅,相比於手機,在1磅的情況下下,偷手機是價效比最好的。
所以我們來看新增一行:
即要填的表格是 。
這裡出現一個 ,我們的下標從1開始,所以這就是越界,越界的都用0來處理,因為實際表達的含義是,沒有剩餘空間的意思。
再看 .
同理:
所以最終在揹包為4磅容量,可偷四種物品時,最大可偷4000美元的東西。
如果物品是更小粒度呢?
比如增加了一件物品重量是0.5磅,那麼這個表格就得按照這個最小的粒度來劃分。
如果可以偷物品的一部分呢?
比如偷大米,小麥,一袋子太多,不是一袋子偷不偷的問題,而是可不可以拿走一部分。
這個問題動態規劃不可解,但是隔壁的貪心演算法可解:偷價效比最高的,即單價最貴的。
如果子問題之間相互依賴呢?
答案是動態規劃處理不了。動態規劃只處理相互離散的子問題。
END.
參考:
《演算法圖解》第九章