一、什麼是動態規劃?
1、動態規劃基本思想
動態規劃是一種多階段決策最優化模型,用來解決最長路徑、最短路徑、背包問題等,一般用於優化問題。動態規劃涉及到搜索、最優化與存儲,使用備忘錄技術降低時間複雜度。在求解問題的過程中,動態規劃方法把原問題分解成多個子問題,遞歸求解子問題,在進行逐步求解的過程中,保存每一個子問題的解,最終得到原問題的最優解。
2、動態規劃適用範圍
動態規劃適用於滿足最優化原理和無後效性的問題。最優化原理指的是全局最優解包含局部最優解,無後效性指的是子問題的最優解可以得到父問題的最優解。
3、動態規劃步驟
動態規劃步驟主要包括問題抽象、狀態設計、狀態轉移方程設計以及實現。通常設計狀態轉移方程是實現動態規劃的核心步驟,狀態轉移方程有時需要使用高級數據結構,比如哈希表、優先隊列等。
二、Python實現動態規劃
1、Python語言優缺點
Python語言具有靈活易用、語言簡單、入門門檻低等特點,具有良好的文檔,是人工智能、Web開發等領域的首選語言。Python語言對於動態規劃的實現,由於其語言易用性良好,因此很多實際問題在Python語言中可以快速解決。
2、Python代碼示例
def fib(n: int) -> int: if n < 2: return n pre, cur = 0, 1 for i in range(2, n + 1): tmp = cur cur += pre pre = tmp return cur
代碼示例是斐波那契數列的實現,當然這個實現的遞推式真簡單:F[i] = F[i-1] + F[i-2],但是實際上,對於許多實際問題,可能需要用比較高級的數據結構,比如dp數組、哈希表等,因此更多時候Python的實現並不一定比其他語言效率高。
三、Python動態規劃實踐案例1:背包問題
1、背包問題基本思想
背包問題是最常見的動態規劃模型之一,背包問題以選取物品的最大價值之和為目標,常見有完全背包問題、多重背包問題、01背包問題等。
2、Python代碼示例
def knapsack_01(k: int, v: List[int], w: List[int], n: int) -> int: dp = [[0] * (k + 1) for _ in range(n + 1)] for i in range(1, n + 1): for j in range(1, k + 1): if j < w[i - 1]: dp[i][j] = dp[i - 1][j] else: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i - 1]] + v[i - 1]) return dp[n][k]
代碼示例是01背包問題的動態規劃實現,其中k為背包大小,v為物品價值數組,w為物品重量數組,n為物品個數。
四、Python動態規劃實踐案例2:最長公共子序列
1、最長公共子序列基本思想
最長公共子序列是指兩個字符串中的最長公共的子序列,可以用於比較兩個字符串的相似度,也可以用於基因序列比對等領域;同時也是最常見的動態規劃模型之一。
2、Python代碼示例
def LCS(s1: str, s2: str) -> int: m, n = len(s1), len(s2) dp = [[0] * (n + 1) for _ in range(m + 1)] for i in range(1, m + 1): for j in range(1, n + 1): if s1[i - 1] == s2[j - 1]: dp[i][j] = dp[i - 1][j - 1] + 1 else: dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) return dp[m][n]
代碼示例是最長公共子序列的動態規劃實現,對於兩個字符串s1、s2,返回它們的最長公共子序列長度。
五、總結
本文詳細闡述了Python動態規劃,介紹了動態規劃基本思想及步驟,對Python語言的優缺點進行了系統分析,並舉了背包問題、最長公共子序列兩個具體案例進行了闡述,從多個維度全面解釋Python動態規劃的實現。
原創文章,作者:ENOOX,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/370259.html