在求解一些最優化問題的時候,一般會分成多個步驟,每一步都有乙個選擇。貪心演算法的思想在於,先不從整體考慮,每次都只做當前看來最優的思想,即區域性最優解,期望通過一步步的區域性最優解,最後構造出全域性最優解。
貪心演算法是很多問題的最優解,當然也有很多問題只是區域性最優,或者近似最優解,在構造貪心演算法的時候,要注意貪心選擇是否能求出最後的最優解。
乙個問題的最優解包含其子問題的最優解,那麼此問題具有最優子結構性質。前面的分治法,動態規劃和此篇的貪心法,都具有最優子結構性質。
問題的整體最優解可以通過一些列區域性最優的選擇(貪心選擇)來達到。因此貪心演算法和分治法一樣,都是自頂向下的思想。
揹包容量為
c ,共
n個物品,物品
i 的(重量,價值)=(wi
, vi ),求解揹包裝載的最大值。
貪心演算法無法求出最優解。如果先按照單位價值最大排序,盡量裝滿揹包,有時候得到的結果也近似最優解。
和 0-1 揹包不同的是,物品可以部分裝載到揹包中去。因此只要貪心地按照單位價值較大的物品順序裝滿揹包即可。
輪船的載重量為
c ,物品
i的重量為 wi
,求解在體積不受限制的情況下,把最可能多的貨櫃裝上輪船。
可以用貪心的思想,把質量輕的物品優先裝載。
字首碼:任何乙個字元的編碼都不是其他字元編碼的字首(編碼都是葉節點即可)
最優字首碼:使平均碼長達到最小的字首碼
哈夫曼編碼:自底向上構造表示最優字首碼的二叉樹 t
貪心地合併兩個具有最小頻率的節點,並每次把合併後的節點加入到優先佇列(最小堆)中去。
初始化優先佇列o(n),最小堆的 removemin 和 put 需要 o(logn)
單源最短路徑要解決的問題,是計算圖中某個點到其他所有點的最短路徑。形式化定義如下:假設帶權有向圖 g=(v,e),每條邊的權都是非負實數,給定乙個頂點,稱為 源。計算從源到其他頂點的最短路長度,稱單源最短路徑問題。
如果邊的權重都是非負的,一般用 dijkstra 的貪心演算法解決,效率較高。如果不是非負的,可以用 bellman-ford 演算法,或者用其佇列優化的改進版本,spfs 演算法。我有四篇博文講了單源最短路徑問題和這三種演算法,不太詳細,有空我會整理一下。我又開始挖坑了。。。
對了 dijkstra 演算法涉及優先佇列和廣度優先演算法,還是值得一看的。
先定義這個問題,假設圖 g 的子圖 g』 是包含所有頂點的樹,那麼 g』 是圖 g 的生成樹,樹上的總權重是該生成樹的耗費,耗費最小的生成樹稱為 g 的最小生成樹(mst,minimum spanning tree)。
要計算最小生成樹,可以利用貪心演算法,一種是 prim 演算法,貪心地把點加入到乙個集合,更新總權重;另一種是 kruskal 演算法,貪心地把圈中最小的邊加入到 mst 中。
prim 演算法
思想是從乙個點開始拓展,構成最小生成樹(mst),每次找到剩下的點中與 mst 連線的權重最小的邊 c[i][j],貪心地加入到 mst 中。
kruskal 演算法
先把邊從大到小排序,貪心策略是權重小的邊優先,這樣把邊乙個個地加到 mst 中來;注意如果邊在同乙個連通分支中,就不能加入 mst 中,因為會構成閉環。
kruskal 演算法要用到並查集,計算時間複雜度為 o(
elog
e),比 prim 演算法的 o(
n2) 要差一點,但是如果是稀疏圖,邊數比點數的平方少很多,那麼 kruskal 演算法比 prim 演算法要好很多。
多級排程問題是說,有
n 個作業,想用
m臺機器來完成,可以用「最長處理時間作業優先」的貪心策略
擬陣,是個啥??【黑人問號.jpg】
研究生課程 演算法分析筆記
演算法分析有四大經典的思想,分治法 貪心法 動態規劃,最後乙個是回溯法和分支限界法,後面會針對性都出一篇部落格總結。這篇博文先總結一下除了四大演算法之外的,雜七雜八的筆記。複雜度分析涉及一些比較麻煩的符號,主要是五個 上界符號 o 下界符號 準確界 非緊上界 o 非緊下界 不過感覺主要用的多的還是上...
研究生課程 演算法分析筆記
演算法分析有四大經典的思想,分治法 貪心法 動態規劃,最後乙個是回溯法和分支限界法,後面會針對性都出一篇部落格總結。這篇博文先總結一下除了四大演算法之外的,雜七雜八的筆記。複雜度分析涉及一些比較麻煩的符號,主要是五個 上界符號 o 下界符號 準確界 非緊上界 o 非緊下界 不過感覺主要用的多的還是上...
研究生課程教給我什麼?
一門課的評分0 10分。0分表示這門課什麼也沒講,6分表示課程讓人學到了基本的概念,10分表示課程很完美。第 一門必修課是 演算法分析與設計 老師是乙個很認真負責的老先生,用的課本是e文的 計算機演算法 這門課個人評價7分。老師要求我們把3 10章所有的 習題至少做60 這個數量是很多的,而且有好多...