動態規劃(dynamic programming)與貪心演算法(greedy algorithm)
《演算法導論》動態規劃筆記
動態規劃的方法是付出額外的記憶體空間來節省計算時間,是典型的時空權衡(time-memory trade-off)的例子。時間上的節省可能是非常巨大的,有可能將指數時間的解轉化為多項式時間的解。
應用動態規劃方法求解的優化問題應該具備的兩個要素:最優子結構和子問題重疊。
最優子結構:
如果一個問題的最優解包含其子問題的最優解,我們就稱此問題具有最優子結構性質。
對於不同問題領域,最優子結構的不同體現在兩個方面:
·原問題的最優解涉及多少個子問題
在確定最優解使用那些子問題時,我們需要考察多少種選擇
最優子結構的性質:
問題的最優解由相關子問題的最優解組合而成,而這些子問題可以獨立求解。
獨立求解也就是同一個原問題的一個子問題的解不影響另一個子問題的解。
例:無權最長路徑問題不滿足子問題的獨立性,因為在兩個子問題中可能會重複利用某些頂點。
動態規劃設計的一般步驟:
刻畫一個最優解的結構特徵
遞迴地定義最優解的值
計算最優解的值,通常採用自底向上的方法
利用計算出的資訊構造一個最優解
動態規劃有兩種等價的實現方法:
帶備忘的自頂向下法(top-down with memoization)。此方法按照自然的遞迴形式編寫,但是過程中會儲存每個子問題的解,通常存在一個陣列或者雜湊表中。當需要一個子問題的解的時候,過程首先你檢查是否已經儲存過這個解。如果是,就直接返回此儲存的值。
自底向上法(bottom-up method)。當求解某個子問題的時候,它所依賴的那些更小的子問題都已經求解完畢,結果已經儲存。每個子問題只需求解一次,當我們求解它時,它的所有前提子問題都已經求解完成。
由於沒有頻繁地遞迴函式呼叫的開銷,自底向上的方法比自頂向下法的時間開銷可能會小一些。
例題以及虛擬碼實現:
鋼條切割問題:給定一段長度為n英寸的規劃鋼條和一個價格表p,求切割鋼條的方案,使銷售收益r最大。
自頂向下版本
MEMOIZED-CUT-ROD(p,n)
let r[0..n] be a new array
for i=0 to n
r[i]=-oo
return MEMOIZED-CUT-ROD-AUX
MEMOIZED-CUT-ROD-AUX(p,n,r)
if r[n]>=0
return r[n]
if n==0
q=0
else q=-oo
for i=1 to n
q=max(q,p[i]+MEMOIZED-CUT-ROD-AUX(p,n-i,r))
r[n]=q
return q
自底而上版本
BOTTOM-UP-CUT-ROD(p,n)
let r[0..n] be a new array
r[0]=0
for j=1 to n
q=-oo
for i= 1 to j
q=max(q,p[i]+r[j-i])
r[j]=q
return r[n]
效能比較:
自底向上和自頂向下的演算法具有相同的漸進執行時間,均為theta(n^2)。
自底向上動態規劃演算法是按“逆拓撲序”(reverse topological sort)來處理子問題圖中的頂點。
《演算法導論》貪心演算法筆記
演算法設計
1. 將最優化問題轉化為這樣的形式:對其作出一次選擇後,隻身下一個子問題需要求解。
2. 證明作出貪心選擇後,原問題總是存在最優解,即貪心選擇總是安全的。
3. 證明作出貪心選擇後,剩餘的子問題滿足性質:其最優解與貪心選擇組合即可得到原問題的最優解,這樣就得到了最優子結構。
貪心選擇性質(greedy-choice property)
我們可以通過作出區域性最優選擇來構造全域性最優解。
貪心演算法與動態規劃的不同之處:
在動態規劃中,每個步驟都要進行一次選擇,但是選擇通常依賴於子問題的解。在貪心演算法中,我們直接作出在當前問題中看來最優的選擇,而不必考慮子問題的解。
例:
0-1揹包問題不具貪心選擇性質
分數揹包問題具有貪心選擇性質
相關文章
- 貪心演算法(貪婪演算法,greedy algorithm)演算法Go
- 動態規劃(Dynamic programming)動態規劃
- 貪心演算法與動態規劃的區別演算法動態規劃
- 演算法---貪心演算法和動態規劃演算法動態規劃
- LeetCode:動態規劃+貪心題目整理LeetCode動態規劃
- 「演算法思想」分治、動態規劃、回溯、貪心一鍋燉演算法動態規劃
- LeetCode 300. 最長上升子序列(Python、動態規劃、貪心演算法)LeetCodePython動態規劃演算法
- 揹包問題演算法全解析:動態規劃和貪心演算法詳解演算法動態規劃
- AI學習筆記——強化學習之動態規劃(Dynamic Programming)解決MDP(1)AI筆記強化學習動態規劃
- 122. 買賣股票的最佳時機 II-簡單-動態規劃、貪心演算法動態規劃演算法
- 演算法設計與分析中的幾個核心演算法策略:動態規劃、貪心演算法、回溯演算法和分治演算法演算法動態規劃
- python 實現 割繩子問題(劍指offer 14題) 動態規劃 或者貪心演算法Python動態規劃演算法
- LeetCode 1326. Minimum Number of Taps to Open to Water a Garden 動態規劃 離散化 貪心LeetCode動態規劃
- 演算法-動態規劃演算法動態規劃
- 演算法_動態規劃演算法動態規劃
- 動態規劃演算法動態規劃演算法
- 動態規劃演算法原理與實踐動態規劃演算法
- 演算法系列-動態規劃(1):初識動態規劃演算法動態規劃
- 前端演算法 - 動態規劃前端演算法動態規劃
- 分享一個簡單但挺有意思的演算法題2-貪心-單調棧-動態規劃演算法動態規劃
- 初級演算法-動態規劃演算法動態規劃
- 【每日演算法】動態規劃四演算法動態規劃
- 「演算法」貪心與隨機化演算法隨機
- 淺談貪心與動歸
- 貪心演算法演算法
- 資料庫與動態規劃資料庫動態規劃
- 演算法(七):圖解動態規劃演算法圖解動態規劃
- 演算法-動態規劃-完全揹包演算法動態規劃
- 動態規劃動態規劃
- dfs與貪心演算法——洛谷5194演算法
- 機器人路徑規劃其一 Dijkstra Algorithm【附動態圖原始碼】機器人Go原始碼
- 找零問題與動態規劃動態規劃
- 演算法筆記之動態規劃(4)演算法筆記動態規劃
- Leetcode 題解演算法之動態規劃LeetCode演算法動態規劃
- 矩陣連乘(動態規劃演算法)矩陣動態規劃演算法
- 動態規劃之 KMP 演算法詳解動態規劃KMP演算法
- 動態規劃演算法(DP)學習<1>動態規劃演算法
- 貪心演算法Dijkstra演算法