1. 程式人生 > 實用技巧 >演算法圖解學習筆記三

演算法圖解學習筆記三

演算法圖解學習筆記三

第九章  動態規劃

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更像。

解決方法: 比較最長公共子序列:兩個單詞中都有的序列包含的字母數。