Python動態規劃:從基礎到高階優化的全面指南

動態規劃(Dynamic Programming)是解決復雜優化問題的核心技術,也是算法領域的明珠。本文將深入探討Python實現動態規劃的全方位技術,涵蓋基礎概念、經典問題、優化技巧和實際工程應用,帶您掌握這一強大工具的精髓。

一、動態規劃的本質:最優決策的藝術

動態規劃不是簡單的編程技巧,而是一種系統化的決策方法論。其核心思想是理查德·貝爾曼提出的"最優性原理":一個多階段決策過程的最優策略具有這樣的性質,即無論初始狀態和初始決策如何,其余決策必須構成最優策略。

動態規劃三大特征:
  1. 重疊子問題:問題可分解為重復計算的子問題

  2. 最優子結構:問題最優解包含子問題最優解

  3. 無后效性:當前決策不影響先前狀態

# 斐波那契數列的遞歸與DP對比
def fib_recursive(n):if n <= 1: return nreturn fib_recursive(n-1) + fib_recursive(n-2)  # 指數級復雜度def fib_dp(n):if n == 0: return 0dp = [0] * (n+1)dp[1] = 1for i in range(2, n+1):dp[i] = dp[i-1] + dp[i-2]  # 線性復雜度return dp[n]# 測試:n=40
%timeit fib_recursive(40)  # 約10秒
%timeit fib_dp(40)        # 約0.5微秒

二、動態規劃四步解題框架

步驟1:定義狀態
  • 明確dp數組含義

  • 確定狀態變量和維度

步驟2:建立狀態轉移方程
  • 找到狀態間遞推關系

  • 數學化表示最優子結構

步驟3:初始化邊界條件
  • 設置初始狀態值

  • 處理特殊情況

步驟4:確定計算順序
  • 自底向上或自頂向下

  • 確保無后效性

def coin_change(coins, amount):"""零錢兌換問題:最少硬幣數"""# 步驟1:定義狀態 - dp[i]表示金額i的最小硬幣數dp = [float('inf')] * (amount+1)# 步驟2:初始化邊界 - 金額0需要0枚硬幣dp[0] = 0# 步驟3:狀態轉移for coin in coins:for i in range(coin, amount+1):dp[i] = min(dp[i], dp[i-coin] + 1)# 步驟4:返回結果return dp[amount] if dp[amount] != float('inf') else -1# 測試
print(coin_change([1, 2, 5], 11))  # 輸出:3 (5+5+1)

三、經典動態規劃問題精解

3.1 背包問題:組合優化的基石

0-1背包問題

def knapsack_01(weights, values, capacity):n = len(weights)# dp[i][w] 前i個物品放入容量w的最大價值dp = [[0]*(capacity+1) for _ in range(n+1)]for i in range(1, n+1):for w in range(1, capacity+1):if weights[i-1] <= w:dp[i][w] = max(dp[i-1][w], dp[i-1][w-weights[i-1]] + values[i-1])else:dp[i][w] = dp[i-1][w]return dp[n][capacity]# 測試
weights = [2, 3, 4, 5]
values = [3, 4, 5, 6]
capacity = 8
print(knapsack_01(weights, values, capacity))  # 輸出:10 (物品2+4)

完全背包問題

def knapsack_unbounded(weights, values, capacity):dp = [0] * (capacity+1)for w in range(1, capacity+1):for i in range(len(weights)):if weights[i] <= w:dp[w] = max(dp[w], dp[w-weights[i]] + values[i])return dp[capacity]# 測試
print(knapsack_unbounded(weights, values, capacity))  # 輸出:12 (物品1*4)
3.2 最長公共子序列(LCS)
def longest_common_subsequence(text1, text2):m, n = len(text1), len(text2)# dp[i][j] 表示text1[0:i]和text2[0:j]的LCS長度dp = [[0]*(n+1) for _ in range(m+1)]for i in range(1, m+1):for j in range(1, n+1):if text1[i-1] == text2[j-1]:dp[i][j] = dp[i-1][j-1] + 1else:dp[i][j] = max(dp[i-1][j], dp[i][j-1])# 回溯構造LCSlcs = []i, j = m, nwhile i > 0 and j > 0:if text1[i-1] == text2[j-1]:lcs.append(text1[i-1])i -= 1j -= 1elif dp[i-1][j] > dp[i][j-1]:i -= 1else:j -= 1return dp[m][n], ''.join(reversed(lcs))# 測試
text1 = "abcde"
text2 = "ace"
length, seq = longest_common_subsequence(text1, text2)
print(f"長度: {length}, 序列: {seq}")  # 長度: 3, 序列: "ace"
3.3 最短編輯距離
def min_edit_distance(word1, word2):m, n = len(word1), len(word2)dp = [[0]*(n+1) for _ in range(m+1)]# 初始化邊界for i in range(1, m+1):dp[i][0] = ifor j in range(1, n+1):dp[0][j] = j# 狀態轉移for i in range(1, m+1):for j in range(1, n+1):if word1[i-1] == word2[j-1]:dp[i][j] = dp[i-1][j-1]else:dp[i][j] = min(dp[i-1][j] + 1,    # 刪除dp[i][j-1] + 1,    # 插入dp[i-1][j-1] + 1   # 替換)return dp[m][n]# 測試
print(min_edit_distance("horse", "ros"))  # 輸出:3 (h->r, 刪o, 刪e)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/90912.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/90912.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/90912.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

視覺大模型部署實踐篇(Docker+dify+ollama安裝)

一、概述 目的:實現一個本地化部署的大模型,通過工作流對圖像進行一些處理。基于此,我選擇了Docker+Dify+Ollama的部署。 具體實現邏輯:Docker來運行dify,dify用來繪制大模型的工作流或者rag等,Ollama用來部署本地大模型,dify調用Ollama部署的大模型進行推理。 二、Dock…

服務器啟動日志等級

目錄 標準日志等級 服務器啟動階段常見日志 日志配置建議 常見服務器/工具的日志等級配置方式 ET框架 Apache/Nginx 等 Web 服務器 Docker 容器 服務器啟動過程中的日志等級是幫助開發者和運維人員理解系統狀態的重要工具。常見的日志等級及其含義如下&#xff1a; 標準…

linux_centos7安裝jdk8_采用jdk安裝包安裝

你問我為什么不用yum? 我yum安裝不了&#xff0c;我也解決不了qwq. 文章目錄一.下載安裝包1.找到安裝包下載位置2.上傳安裝包到linux3.解壓jdk安裝包4.配置環境一.下載安裝包 1.找到安裝包下載位置 去官網找到你要下載jdk版本&#xff1a; Oracle官網 下面演示安裝jdk8的&am…

Linux驅動23 --- RkMedia 使用

目錄 一、上電自動掛載 二、RkMedia 2.1 認識 RkMedia rtsp rtmp RTSP 和 RTMP 的選擇 2.2 安裝 VLC 2.2 RkMedia 例程使用 一、上電自動掛載 cd /etc/init.d/ vi Smyprofile.sh 添加這個內容 #!/bin/sh ifconfig eth0 192.168.66.88 mount -t nfs 192.168.66.66…

Linux:線程同步與線程互斥

線程互斥競態條件當多個線程&#xff08;或進程&#xff09;并發訪問和操作同一個共享資源&#xff08;如變量、文件、數據庫記錄等&#xff09;時&#xff0c;最終的結果依賴于這些線程執行的相對時序&#xff08;即誰在什么時候執行了哪條指令&#xff09;。 由于操作系統調度…

HTML 常用標簽速查表

HTML 常用標簽速查表 &#x1f9f1; 結構類標簽 標簽含義用途說明<html>HTML文檔根元素所有HTML內容的根節點<head>頭部信息放置元信息&#xff0c;如標題、引入CSS/JS等<body>頁面內容主體所有可視內容的容器&#x1f4dd; 文本與標題標簽 標簽含義用途說…

1.gradle安裝(mac)

1.下載二進制包 官網下載&#xff1a;Gradle Releases 國內鏡像&#xff08;騰訊云&#xff09;&#xff1a;https://mirrors.cloud.tencent.com/gradle/ 2.解壓并配置環境變量 解壓到指定目錄&#xff08;示例&#xff1a;/opt/gradle&#xff09; sudo mkdir -p /opt/gr…

Rust賦能土木工程數字化

基于Rust語言在數字化領域應用 基于Rust語言在土木工程數字 以下是基于Rust語言在土木工程數字化領域的30個實用案例,涵蓋結構分析、BIM、GIS、傳感器數據處理等方向。案例均采用Rust高性能、安全并發的特性實現,部分結合開源庫或算法。 結構分析與計算 有限元分析框架 使…

KTH5791——3D 霍爾位置傳感器--鼠標滾輪專用芯片

1 產品概述 KTH5791是一款基于3D霍爾磁感應原理的鼠標滾輪專用芯片&#xff0c;主要面向鼠標滾輪的旋轉的應用場景。兩個 專用的正交輸出使該產品可直接替代機械和光學旋轉編碼器的輸出方式&#xff0c;使得鼠標磁滾輪的應用開發工作極簡 化即兼容目前所有鼠標的滾輪輸出方式。…

決策樹(Decision Tree)完整解析:原理 + 數學推導 + 剪枝 + 實戰

1?? 什么是決策樹&#xff1f;決策樹&#xff08;Decision Tree&#xff09;是一種常見的監督學習方法&#xff0c;可用于分類和回歸。 其基本思想是&#xff1a;通過特征條件的逐層劃分&#xff0c;將數據集分割成越來越“純凈”的子集&#xff0c;直到子集中的樣本幾乎屬于…

C語言:20250728學習(指針)

回顧/*************************************************************************> File Name: demo01.c> Author: 阮> Description: > Created Time: 2025年07月28日 星期一 09時07分52秒**********************************************************…

esp32s3文心一言/豆包(即火山引擎)大模型實現智能語音對話--流式語音識別

一、引言 在之前的帖子《Esp32S3通過文心一言大模型實現智能語音對話》中&#xff0c;我們介紹了如何使用Esp32S3微控制器與文心一言大模型實現基本的智能語音對話功能&#xff0c;但受限于語音識別技術&#xff0c;只能處理2-3秒的音頻數據。為了提升用戶體驗&#xff0c;滿足…

面試150 最長遞增子序列

思路 定義 dp[i] 表示以第 i 個元素結尾的最長遞增子序列的長度&#xff0c;初始時每個位置的最長子序列長度為 1。然后通過雙重循環遍歷每一對元素 j < i&#xff0c;如果 nums[i] > nums[j]&#xff0c;說明 nums[i] 可以接在 nums[j] 的遞增序列之后&#xff0c;更新 …

TCP 套接字--服務器相關

1.創建 TCP 套接字int server_sockfd socket(AF_INET,SOCK_STREAM, 0);函數原型&#xff1a;#include <sys/socket.h>int socket(int domain, int type, int protocol);domain協議族&#xff08;地址族&#xff09;AF_INET&#xff08;IPv4&#xff09;type套接字類型SO…

六、搭建springCloudAlibaba2021.1版本分布式微服務-admin監控中心

前言Spring Boot Actuator 是 spring-boot 自帶監控功能 &#xff0c;可以幫助實現對程序內部運行情況監控&#xff0c;比如監控狀況、Bean 加載情況、環境變量、日志信息、線程信息等。 Spring Boot Admin是一個針對 spring-boot 的 actuator 接口進行 UI 美化封裝的監控工具。…

輕量級遠程開發利器:Code Server與cpolar協同實現安全云端編碼

前言&#xff1a;作為一款專為Web環境設計的VS Code托管方案&#xff0c;Code Server通過精簡架構重新定義了遠程開發體驗。其核心優勢在于將完整的編輯器功能封裝于輕量容器中——僅需不到200MB內存即可運行基礎服務&#xff0c;并支持在樹莓派等低性能設備上流暢操作。系統采…

圖論:最小生成樹

今天要介紹兩中最小生成樹的算法&#xff0c;分別是prim算法和kruskal算法。 最小生成樹是所有節點的最小連通子圖&#xff0c;即&#xff1a;以最小的成本&#xff08;邊的權值&#xff09;將圖中所有節點鏈接到一起。 圖中有n個節點&#xff0c;那么一定可以用n-1條邊將所有節…

haproxy七層代理

1、負載均衡Load Balance(LB) 概念 負載均衡&#xff1a;是一種服務或基于硬件設備等實現的高可用反向代理技術&#xff0c;負載均衡將特定的業務(web服務、網絡流量等)分擔給指定的一個或多個后端特定的服務器或設備&#xff0c;從而提高了 公司業務的并發處理能力、保證了業務…

【NLP輿情分析】基于python微博輿情分析可視化系統(flask+pandas+echarts) 視頻教程 - 微博文章數據可視化分析-點贊區間實現

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;最近寫了一套【NLP輿情分析】基于python微博輿情分析可視化系統(flaskpandasecharts)視頻教程&#xff0c;持續更新中&#xff0c;計劃月底更新完&#xff0c;感謝支持。今天講解微博文章數據可視化分析-點贊區間實現 視頻…

Redis實戰(3)-- 高級數據結構zset

有序集合&#xff08;ZSET&#xff09;&#xff1a;可以用作相關有序集合相對于哈希、列表、集合來說會有一點點陌生,但既然叫有序集合,那么它和集合必然有著聯系,它保留了集合不能有重復成員的特性,但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下標作為排序依據…