1. 介紹
前文提到,對於揹包問題與旅行商問題,計算的複雜度是隨着計算數據的增加呈現指數級增長的,貪婪算法算可以處理,但得到的並不是最優解。
動態規劃的主要思路是先解決子問題,在逐步解決大問題。本文將通過兩個例子介紹動態規劃的推算思路。
2. 揹包問題
2.1 思路
通過動態規劃方法解決揹包問題的流程如下:
-
準備一個表格,商品作爲Y軸,揹包重量作爲x軸
-
使用下面的公式算出價格且更新到表格裏
-
使用方法2,逐行填充表格,直到將表格填滿。
2.2 推算過程
用於推算的數據如下:
- 小偷的揹包可以放4KG的物品
- 可偷物品的價格,重量如下:
物品 | 重量 | 價值 |
---|---|---|
吉他 | 1kg | 1500 |
音響 | 4kg | 3000 |
筆記本 | 3kg | 2000 |
手機 | 1kg | 2000 |
詳細推算過程如下:
- 初始化表格如下
* | 1 | 2 | 3 | 4 |
---|---|---|---|---|
吉他 | ||||
音響 | ||||
筆記本 | ||||
手機 |
- 吉他是第一個商品,且重量只有1kg,則對於不同大小的揹包而言都可以放得下,所以第一行的值都爲1500
* | 1 | 2 | 3 | 4 |
---|---|---|---|---|
吉他 | 1500 | 1500 | 1500 | 1500 |
音響 | ||||
筆記本 | ||||
手機 |
- 音響是第二個商品,對於1,2,3三個揹包都放不下,所以能放的物品價值還是1500,第四個揹包可以放下,使前面提到的公式推導一下。
- CELL[1][4]=1500
- 當前價值+剩餘空間價值=3000+0(沒有剩餘的空間,所以剩餘價值爲0)
通過上面的推算,可知音響這行最後一格的值爲3000
* | 1 | 2 | 3 | 4 |
---|---|---|---|---|
吉他 | 1500 | 1500 | 1500 | 1500 |
音響 | 1500 | 1500 | 1500 | 3000 |
筆記本 | ||||
手機 |
- 看下筆記本,前兩個揹包都放不下,從第三個開始。第三個揹包放完筆記本後價值爲2000,且比CELL[2,3]要大,所以該值更新爲2000
* | 1 | 2 | 3 | 4 |
---|---|---|---|---|
吉他 | 1500 | 1500 | 1500 | 1500 |
音響 | 1500 | 1500 | 1500 | 3000 |
筆記本 | 1500 | 1500 | 2000 | |
手機 |
再來看筆記本的最後一格,比較下面的值:
- CELL[2][4]=3000
- 2000(筆記本價格)+1500(剩餘空間的最大價值)=3500
由上可得出筆記本第四格的價值應該是3500
* | 1 | 2 | 3 | 4 |
---|---|---|---|---|
吉他 | 1500 | 1500 | 1500 | 1500 |
音響 | 1500 | 1500 | 1500 | 3000 |
筆記本 | 1500 | 1500 | 2000 | 3500 |
手機 |
- 手機的重量爲1kg.且比吉他的價格要貴,所以第一格替換成手機的價格
* | 1 | 2 | 3 | 4 |
---|---|---|---|---|
吉他 | 1500 | 1500 | 1500 | 1500 |
音響 | 1500 | 1500 | 1500 | 3000 |
筆記本 | 1500 | 1500 | 2000 | 3500 |
手機 | 2000 |
對於第二格,比較下面的值:
- CELL[3][2]=1500
- 2000(筆記本價格)+1500(剩餘空間的最大價值,C[3,1])=3500
由上可得出手機第二格的價值應該是3500
* | 1 | 2 | 3 | 4 |
---|---|---|---|---|
吉他 | 1500 | 1500 | 1500 | 1500 |
音響 | 1500 | 1500 | 1500 | 3000 |
筆記本 | 1500 | 1500 | 2000 | 3500 |
手機 | 2000 | 3500 |
第三格的推算過程與第二格類似,值同樣爲3500.
* | 1 | 2 | 3 | 4 |
---|---|---|---|---|
吉他 | 1500 | 1500 | 1500 | 1500 |
音響 | 1500 | 1500 | 1500 | 3000 |
筆記本 | 1500 | 1500 | 2000 | 3500 |
手機 | 2000 | 3500 | 3500 |
對於第四格,比較下面的值:
- CELL[3][4]=3500
- 2000(筆記本價格)+2000(剩餘空間的最大價值,C[3,3])=4000
由上可得出手機第四格的價值應該是4000
* | 1 | 2 | 3 | 4 |
---|---|---|---|---|
吉他 | 1500 | 1500 | 1500 | 1500 |
音響 | 1500 | 1500 | 1500 | 3000 |
筆記本 | 1500 | 1500 | 2000 | 3500 |
手機 | 2000 | 3500 | 3500 | 4000 |
最終可得知,小偷最多可偷4000元的商品,且偷的商品是手機+筆記本電腦。
2.4 其他注意事項
- 最終的結果和表格中商品的順序沒有關係
- 如果可偷的商品爲0.5kg. 則x軸的粒度要爲0.5。既0.5->1->1.5->2…
- 選擇商品的時候,每個商品都是獨立選擇的,不存在依賴關係。例如不應該出現選擇商品A,則必須(不能)選擇B的情況
- 最優解可能會導致最終的揹包沒有被裝滿
3. 最長公共子串
最場公共子串求出的是兩個字符串都包含的最長子串,例如:對於hish與fish兩個單詞,ish就是他們的最長公共子串。
3.1 思路
可以用解決揹包問題的思路來解決該問題,兩個單詞分別對應縱/橫軸,將公共子串的長度填到方格里,最後所有格子裏最大的值就是最大的公共子串的長度,連續從0到最大長度值對應的縱/橫軸對應的字母就是最長公共子串。
格子裏值的推算公式如下:
if word_a[i] == word_b[j]:
cell[i][j] = cell[i-1][j-1] + 1
else:
cell[i][j] = 0
按照上面的公式推算,FISH與HISH的結果如下:
既最大長度爲3,對應的子串爲ISH.
3.2 最長公共子序列
最長公共子序列:兩個單詞中都有的序列包含的字母數,最後求得的子序列長度越長,說明兩個單詞越相似
算法的步驟如下:
計算FOSH與FISH與FORT兩個單詞的最長公共子序列的過程與結果如下:
通過上述結果可看出,FISH與FOSH更像一些。
4. 總結
動態規劃的實際應用包括如下場景:
-
生物學家根據最長公共序列來確定DNA鏈的相似性,進而判斷度兩種動物或疾病有多相似。
-
前面討論了字符串的相似程度。 編輯距離( levenshtein distance)指出了兩個字符串的相
似程度,也是使用動態規劃計算得到的。編輯距離算法的用途很多,從拼寫檢查到判斷用戶上傳的資料是否是盜版,都在其中。 -
Microsoft Word等具有斷字功能的應用程序,使用動態規劃確定在什麼地方斷
字以確保行長一致。