動態框架方法論
動態規劃
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
經典的入門問題是斐波那契數列數列,以及找零錢問題。解法太過常見,這次來談一些正確的思路。
相關文章
- 動態規劃方法論動態規劃
- Flutter動態化框架ThreshFlutter框架
- 動態規劃之理論分析動態規劃
- Hades:移動端靜態分析框架框架
- hyperf 框架動態修改或追加配置框架
- vue element框架動態修改夜間模式Vue框架模式
- Python中動態類和動態方法的建立與呼叫Python
- 動態規劃解題方法動態規劃
- Hadoop系列002-從Hadoop框架討論大資料生態Hadoop框架大資料
- Hadoop基礎(二):從Hadoop框架討論大資料生態Hadoop框架大資料
- <討論>2020年 的 python 介面自動化框架Python框架
- MyBatis框架之SQL對映和動態SQLMyBatis框架SQL
- 人工智慧導論 (三) - 產生式/框架式表示方法人工智慧框架
- 激勵方法論3、驅動力3.0
- 論前端框架元件狀態抽象方案, 基於 ClojureScript 的 Respo 為例前端框架元件抽象
- 兩種動態建立表格的方法
- Vue 框架-05-動態繫結 css 樣式Vue框架CSS
- 180628-動態任務執行框架想法篇框架
- 理論+實踐,帶你掌握動態規劃法動態規劃
- 關於動態配置表檢查工具 (討論帖)
- Spring框架使用@Autowired自動裝配引發的討論Spring框架
- VS中呼叫DLL動態庫的方法
- MySQL動態修改varchar長度的方法MySql
- QuickTask動態指令碼支援框架整體介紹篇UI指令碼框架
- SpringMVC框架詳細教程(二)_建立動態Web專案SpringMVC框架Web
- 動態ip軟體基本知識和動態ip代理使用方法掃盲
- jQuery動態生成html元素的幾種方法jQueryHTML
- Swift 幾種動態判斷類的方法Swift
- 朋友圈分享動態吸引好友的方法
- 製作GIF動態圖有什麼方法
- 動態IPvps的介紹及其連線方法
- 動態ip代理的三種使用方法
- Java 動態設定 JVM 引數的方法JavaJVM
- android動態許可權到自定義許可權框架Android框架
- 基於JS的高效能Flutter動態化框架MXFlutterJSFlutter框架
- net 靜態方法與非靜態方法
- Mybatis框架:foreach迴圈遍歷欄位(為了解決動態表、動態欄位查詢資料)MyBatis框架
- win10動態桌布steam怎麼操作_win10動態桌布steam設定方法Win10