算法導論筆記——第十六章 貪心算法
通常用於最優化問題,我們做出一組選擇來達到最優解。每步都追求局部最優。對很多問題都能求得最優解,而且速度比動態規劃方法快得多。
16.1 活動選擇問題
按結束時間排序,然後選擇兼容活動。
定理16.1 考慮任意非空子問題Sk,令am是Sk中結束時間最早的活動,則am在Sk的某個最大兼容活動子集中。
16.2 貪心算法原理
設計貪心算法步驟:
1》將最優化問題轉化為這樣的形式:對其做出一次選擇後,只剩下一個子問題需要求解。
2》證明作出貪心選擇後,原問題總是存在最優解,即貪心選擇總是安全的。
3》證明作出貪心選擇後,剩余的子問題滿足性質:其最優解與貪心選擇組合即可得到原問題的最優解,這樣就得到了最優子結構。
貪心選擇性質:
我們可以通過做出局部最優(貪心)選擇來構造全局最優解。
動態規劃:依賴子問題的解。自底向上或自頂向下,都需要先求解子問題。
貪心算法:進行選擇時可能依賴之前的選擇,但不依賴將來的選擇或子問題的解。在進行第一次選擇前不求解任何子問題。自頂向下。
如果進行貪心選擇時我們不得不考慮眾多選擇,通常意味著可以改進貪心選擇,使其更為高效。通過對輸入進行預處理或者使用適合的數據結構(通常是優先隊列),通常可使貪心選擇更快速。
最優子結構:
如果一個問題的最優解包含其子問題的最優解,則稱此問題具有最優子結構性質。此性質是能否應用動態規劃和貪心算法的關鍵要素。
貪心對動態規劃:
0-1背包問題(動態規劃)和分數背包問題(貪心算法)
16.3 赫夫曼編碼
前綴碼:沒有任何碼字是其他碼字的前綴。前綴碼可以保證達到最優數據壓縮率。
文件的最優編碼方案總是對應一棵滿(full)二叉樹。即每個非葉結點都有兩個孩子結點(國內外教程定義不一致,國內還要求同時是完全二叉樹)。
若C為字母表且所以字符的出現頻率均為正數,則最優前綴碼對應的樹恰有|C|個葉節點,每個葉節點對應字母表中的一個字符,且恰有|C|-1個內部結點。
引理16.2 令C為一個字母表,其中每個字符c屬於C都一個頻率c.freq。令x和y是C中頻率最低的兩個字符。那麽存在C的一個最優前綴碼,x和y的碼字長度相同,且只有最後一個二進制位不同。
引理16.3 令C為一個字母表,其中每個字符c屬於C都一個頻率c.freq。令x和y是C中頻率最低的兩個字符。令C‘為C去掉字符x和y,加入 一個新字符z後得到的字母表,即C‘=C-{x,y}U{z}。類似C,也為C‘定義freq,不同之處只是z.freq=x.freq+y.freq。令T‘為字母表C‘的任意一個最優前綴碼對應的編碼樹。於是我們可以將T‘中葉節點z替換為一個以x和y為孩子的內部結點,得到樹T,而T表示字母表C的一個最優前綴碼。
16.4 擬陣和貪心算法
16.5 用擬陣求解任務調度問題
算法導論筆記——第十六章 貪心算法