動態框架方法論
動態規劃
2020年12月29日
14:06
目錄 |
- - 經典三概念與解決思想 - 經典的解決思想 - 動態規劃的方法論 - 案例:找零 - 求解框架 - REF
|
經典三概念與解決思想
動態規劃是什麼?動態規劃有三個特徵。
- 重複子問題,這個特點很好理解,遞迴樹是一個非常好方法,它的一個功能就是能直觀地感受到重複子問題
- 最優子結構,當前問題可以由子問題的solution解決,這個特性,遞迴地使得當前問題和子問題具備相同的結構
- 狀態轉移方程,這也是最難的一步,既然當前問題可以由子問題解決,那麼轉移公式是?
經典的解決思想
- 自頂向下,逐步求解
- 自底向上,反向求精
這是計算機世界一種經典的思想,在動態規劃、遞迴、回溯中,自頂向下的方法通常是非常直接的暴力解法——這非常有用,是一切優化的開始。
動態規劃的方法論
解決這些問題需要找到四個要素:
- base,求解停止的基礎條件是?到哪種狀態可以直接返回。
- state,狀態,這是非常關鍵的,它指的是可以代表當前問題的一些狀態量的集合,對應到遞迴樹中,這個狀態就是遞迴樹中的一個節點——這非常重要。
- select,選擇,改變狀態的行為
- dp function,dp動態規劃函式,函式一般返回某個狀態的solution,這個也是最難定義的暴力解決方案
以找零錢問題為例,請參考REF中原題
- base,當amount=0的時候,表示不用湊硬幣了,直接return 0
- state,狀態,這個問題的關鍵狀態量只有一個,那就是當前問題的amount——這個目標金額,最少需要多少枚硬幣可以湊齊
- select,改變目標金額的唯一行為是選擇某個硬幣
- dp函式,根據以上dp函式可以定義為,c(最少需要的硬幣數) = dp(目標金額)
案例:找零
根據上述分析找零問題的暴力求解虛擬碼框架是:
1 def dp(n): 2 for coin in coins: 3 res = min(res, dp(n-coin)+1) 4 return res |
詳細解法,可以參考原文,見ref。
上述框架,加上基值條件,完整的程式碼如下。
1 def dp(n): 2 if n == 0: return 0 3 if n < 0: return -1 4 res = float('INF') 5 for coin in coins: 6 t = dp(n-coin) 7 if t == -1: continue 8 res = min(res, t+1) 9 return res if res != float('INF') else -1 10 # 備忘錄 11 memo = {} 12 def dp(n): 13 # memo 14 if n in memo: return memo[n] 15 # base 16 if n == 0: return 0 17 if n < 0: return -1 18 # init res 19 res = float('INF') 20 # chose coin 21 for coin in coins: 22 t = dp(n-coin) 23 # invalid 24 if t == -1: continue 25 res = min(res, t+1) 26 memo[n] = res if res != float('INF') else -1 27 return memo[n] 28 # 迭代 29 memo = [0] 30 31 for n in range(1, amount+1): 32 memo.append(amount+1) 33 for coin in coins: 34 # 檢查越界 35 if n - coin >= 0: 36 memo[n] = min(memo[n-coin]+1, memo[n]) 37 return memo[n] if memo[n] != (amount+1) else -1 |
- 去除重複子問題的最直接的方式就是使用備忘錄記錄狀態
- 完成了備忘錄方法,那麼最後的問題就是,如何自底向上計算出備忘錄(所有狀態對應的解法的陣列)
程式碼如上。
求解框架
該框架有點令人費解,但是仔細對照找零問題,其中核心問題就是理解“狀態”——狀態備忘錄,記錄的是當前狀態的solution。
1 # 初始化 base case 2 dp[0][0][...] = base 3 # 進行狀態轉移 4 for 狀態1 in 狀態1的所有取值: 5 for 狀態2 in 狀態2的所有取值: 6 for ... 7 dp[狀態1][狀態2][...] = 求最值(選擇1,選擇2...) |
REF
經典的入門問題是斐波那契數列數列,以及找零錢問題。解法太過常見,這次來談一些正確的思路。
相關文章
- 動態規劃方法論動態規劃
- 動態代理—IOC框架框架
- Flutter動態化框架ThreshFlutter框架
- 動態規劃之理論分析動態規劃
- hyperf 框架動態修改或追加配置框架
- APK動態載入框架(DL)解析APK框架
- vue element框架動態修改夜間模式Vue框架模式
- Hades:移動端靜態分析框架框架
- DL動態載入框架技術文件框架
- 動態規劃解題方法動態規劃
- 動態生成ios plist的方法iOS
- 動態定義一個方法
- 動態載入JS的方法JS
- Python中動態類和動態方法的建立與呼叫Python
- MyBatis框架之SQL對映和動態SQLMyBatis框架SQL
- Android 主題動態切換框架:PrismAndroid框架
- 人工智慧導論 (三) - 產生式/框架式表示方法人工智慧框架
- 論前端框架元件狀態抽象方案, 基於 ClojureScript 的 Respo 為例前端框架元件抽象
- 兩種動態建立表格的方法
- Struts2 動態方法呼叫(十三)
- Ruby如何實現動態方法呼叫
- pl/sql--動態SQL常用方法SQL
- Vue 框架-05-動態繫結 css 樣式Vue框架CSS
- 關於動態配置表檢查工具 (討論帖)
- 理論+實踐,帶你掌握動態規劃法動態規劃
- 演算法導論-動態規劃-鋼條切割演算法動態規劃
- Hadoop基礎(二):從Hadoop框架討論大資料生態Hadoop框架大資料
- MySQL動態修改varchar長度的方法MySql
- Vue 動態資料繫結核心方法Vue
- VS中呼叫DLL動態庫的方法
- Android 熱補丁動態修復框架小結Android框架
- WebClass實現動態WEB程式設計之理論篇 (轉)Web程式設計
- Hadoop系列002-從Hadoop框架討論大資料生態Hadoop框架大資料
- javascript 動態修改css樣式方法彙總(四種方法)JavaScriptCSS
- Spring框架使用@Autowired自動裝配引發的討論Spring框架
- 動態ip軟體基本知識和動態ip代理使用方法掃盲
- 製作GIF動態圖有什麼方法
- 動態ip代理的三種使用方法