貪心演算法(greedy algorithms)

2021-09-03 00:07:10 字數 2391 閱讀 1777

麻煩不吝star和fork本博文對應的github上的技術部落格專案吧!謝謝你們的支援!

貪心演算法找到全域性最優解的要求

01揹包問題

參考文獻

貪心演算法的思路是:希望在解決問題所要求的每一步中,都盡量選擇哪個能讓當前/區域性(local)狀態最優的做法,以希望達到全域性也最優的狀態。

之前的mst問題中的kruskal演算法就可以看作一種貪心演算法,因為kruskal演算法就是先將邊按照權重由小到大排列,然後按照這個順序依次加入邊,以希望最後得到的生成樹也是最小的。

假設有一系列的活動a

ia_i

ai​,每個活動從某個時間點s

is_i

si​開始,並且持續進行一段時間,在某個時間點f

if_i

fi​結束。我們希望選擇一些活動去參加,使得參加的活動的總時長最長。

我們可以用以上貪心演算法來解決該問題,主要思路是:不斷選取完成時間最早的活動來做,並且移除和被選擇的活動時間有重合的其它活動。重複這個過程直到沒有任何可選活動。

該貪心演算法針對這個問題得到的解是最優的。

假設有一系列的字元,我們希望用一些二進位製碼來代替這些字元以進行資料壓縮,使得壓縮後的總位元數最小。哈夫曼編碼正是這樣一樣壓縮資料的方式。

如果我們已知各字元在文字中的出現頻率,考慮到為了讓壓縮後的資料更小,我們直覺是讓出現頻率高的字元用盡可能短的編碼,而出現頻率高的則可以用更長的編碼。

哈夫曼編碼的解決方案是這樣的:不斷找到當前出現頻率最小的兩個結點(字元或頻率),將它們結合,作為乙個新生成的結點的左右子結點,並將新生成的結點繼續放入比較,直到沒有落單的字元。

該貪心演算法針對這個問題得到的解是最優的。

對於乙個圖g,我們希望從中選取一些兩兩互不相鄰的邊,使得這樣的邊的數量最多。

該貪心演算法針對這個問題得到的解是不一定是最優的,但是它也確實得到了乙個盡量最大化的解(maximal)m,並且對於最優解m

∗m^*

m∗,存在這樣的關係:

∣ m∗

∣≤2∗

∣m∣|m^*|\le 2*|m|

∣m∗∣≤2

∗∣m∣

對於乙個圖g,我們嘗試找到乙個最小的頂點的集合c,使得c中的頂點整體碰到了所有圖中的邊。

但是這個演算法不保證能找到最優結果,比如下面這種情況:

所以該演算法會使得集合c的大小達到θ(m

lgm)

\theta(mlgm)

θ(mlgm

),不過我們可以通過改進使得|c|$\le$2opt:

看了上面幾個小例項,發現有時候貪心能找到全域性最優解,有時候又不能,甚至找到的解會很差。那麼決定乙個貪心演算法是否能找到全域性最優解的條件是什麼呢?

其實就是以下兩點:

有關01揹包問題,大家具體可以看動態規劃之01揹包問題(最易理解的講解)。

這裡主要想講的是,01揹包問題是要求物品不可分割的,這時如果用貪心演算法也無法保證全域性最優。但是如果物品是可無限分割的(fractional knapsack),那麼貪心又會是最優的(直覺上來說,優先將單位價值最高的物品放進揹包總是沒錯的)。

我們可以簡單證明貪心在此處的正確性:

經典貪心演算法 貪心演算法概述

貪心演算法具有最優子問題結構,它的特點是 短視 每次選擇對當前局面最有利的決策,來一步步獲得最優解。我個人認為,貪心不是乙個具體的方法,而是一類方法,貪心演算法的關鍵不在於想到,而在於正確性的證明。要證明乙個貪心演算法是正確的,需要證明我們可以把乙個最優解逐步轉化為我們用貪心演算法所得到的解,而解不...

演算法 貪心演算法

把乙個複雜問題分解為一系列較為簡單的區域性最優選擇,每乙個選擇都是對當前解的乙個擴充套件,知道獲得問題的完整解。在解決問題的策略上目光短淺,只根據當前已有的資訊做出選擇,而且一旦做出了選擇,不管將來有什麼結果這個選擇都不會改變。換言之,貪心法並不是從整體最優考慮,它所做出的選擇只是在某種意義上的區域...

演算法 貪心演算法

集合覆蓋問題 旅行商問題等都屬於np完全問題,在數學領域上並沒有快速得到最優解的方案,非常適合用貪婪演算法。判斷方法 1.元素較少時,一般執行速度很快,但隨著元素數量增多,速度會變得非常慢 2.涉及到需要計算比較 所有的組合 情況的通常是np完全問題 3.無法分割成小問題,必須考慮各種可能的情況。這...