演算法圖解學習筆記三
演算法圖解學習筆記三
第九章 動態規劃
9.1 揹包問題
問題簡介:假設你是一個小偷,揹包只能裝4kg東西,你可盜竊的商品有如下三件:音響 3000美元 4千克 膝上型電腦 2000美元 3千克 吉他 1500美元 1千克
1.簡單演算法:嘗試各種可能的商品組合,並找出價值最高的組合。------>可行但速度慢
3件商品 8種組合 4件商品 16種組合 執行時間O(2^n)
在前一章學習瞭如何找到近似解,但不一定是最優解
2.如何找最優解--->動態規劃
先解決子問題,再解決大問題
畫網格圖 計算每個單元格的公式=max(1.上一個單元格的值(c[i-1][j]),2.當前商品的價值+剩餘空間的價值(c[i-1][j-當前商品的重量]))
9.2 揹包問題FAQ
1.再增加一件商品將如何?
加一個iPhone 前面幾行不需要重新計算 因為動態規劃是一個逐步計算最大價值的過程
沿著一列往下走,最大價值不可能降低,因為每次迭代時你儲存的是當前的最大價值,最大價值不可能比以前低!
2.行的排列順序發生改變時結果將如何?
沒有編號,各行排列順序無關緊要
3.可以逐列填充網路
4.增加一件更小的商品將如何呢?
假設你可以偷一條項鍊 0.5kg 1000美元 需要考慮的粒度更細,必須調整網格
5.可以偷走商品的一部分嗎?
假設在雜貨店偷,只有豆子和大米與麵條,可偷一部分--->動態規劃沒法處理這個問題,動態規劃要麼不拿,要麼拿一整件
使用貪婪演算法 --->儘可能多拿價值高的商品,如果拿光了,在儘可能多拿價值次高的商品。
6.旅遊行程最優化---揹包問題 約束條件為時間 畫網格圖
7.處理相互依賴的情況
假如你還想去巴黎玩,解決不了。。僅當每個子問題都是離散的,即不依賴於其他子問題時,動態規劃才有用。
8.計算最終的解時會涉及兩個以上的子揹包嗎?
動態規劃最多隻需合併兩個子揹包,即更根本不會涉及兩個以上的子揹包,不過這些子揹包又可能包含子揹包。
9.最優解可能導致揹包沒裝滿
9.3 最長公共子串
1.動態規劃問題帶來的啟示:
(1).動態規劃可在給定約束條件下找到最優解
(2).問題可分解為彼此獨立且離散的子問題時可使用動態規劃。但要設計出動態規劃解決法案maybe很難
(3).每種動態規劃解決方案都涉及網路
(4).單元格中的值通常是你要優化的值。
(5).每個單元格都是一個子問題 --->learn 如何將問題分解為子問題,有助'於找到網格的座標軸
ALEX輸入了hish,那原來它要輸入的是fish還是vista?
2.繪製網格 填充網格
怎麼繪製? 單元格中的值是什麼?如何將這個問題劃分為子問題?網格的座標軸是什麼?
將某個指標最大化-------->找兩個單詞的最長公共子串 單元格中的值是我要優化的值
H | I | S | H | |
F | 0 | 0 | 0 | 0 |
I | 0 | 1 | 0 | 0 |
S | 0 | 0 | 2 | 0 |
H | 0 | 0 | 0 | 3 |
使用什麼公式呢?費曼演算法(Feynman) 步驟:
(1)將問題寫下來 (2)好好思考 (3)將答案寫下來
如果兩個字母不相同則為0,相同則為左上角鄰居的值+1
虛擬碼:
if word_a[i]=word_b[j]:#兩個字母相同 cell[i][j]=cell[i-1][j-1]+1 else: cell[i][j]=0
查詢hish與vista的最長公共子串時,網格如下
V | I | S | T | A | |
H | 0 | 0 | 0 | 0 | 0 |
I | 0 | 1 | 0 | 0 | 0 |
S | 0 | 0 | 2 | 0 | 0 |
H | 0 | 0 | 0 | 0 | 0 |
需要注意的是:這個問題的最終答案不在最後一個單元格中!
揹包問題---->答案總在最後的單元格中 但對於最長公共子串問題---->答案為網格中最大的數字
9.4 最長公共子序列
如果Alex不小心輸入了fosh,他原本想輸入的是fish還是fort呢?
我們用最長的公共子串公式來比較他們.
F | O | S | H | |
F | 1 | 0 | 0 | 0 |
O | 0 | 2 | 0 | 0 |
R | 0 | 0 | 0 | 0 |
T | 0 | 0 | 0 | 0 |
F | O | S | H | |
F | 1 | 0 | 0 | 0 |
I | 0 | 0 | 0 | 0 |
S | 0 | 0 | 1 | 0 |
H | 0 | 0 | 0 | 2 |
最長公共子串長度一樣,都包含兩個字母,但fosh與fish更像。
解決方法: 比較最長公共子序列:兩個單詞中都有的序列包含的字母數。