算法-贪心法
貪心法是把一個復雜問題分解為一系列較為簡單的局部最優選擇,每一步選擇都是對當前解的一個擴展,直到獲得問題的完整解。貪心法的典型應用是求解最優化問題,而且對許多問題都能得到整體最優解,即使不能得到整體最優解,通常也是最優解的很好近似。
概述
貪心法的設計思路
貪心法目光短淺,并不是從整體最優考慮,它所做出的選擇只是在某種意義上的局部最優,這種局部最優選擇并不總能獲得整體最優解,但通常能獲得近似最優解。
用貪心法求解的問題一般有兩個最重要的性質:最優子結構性質和貪心選擇性質。
1)最優子結構性質:當一個問題的最優解包含其子問題的最優解時,稱此問題具有最優子結構性質,也稱此問題滿足最優性原理,問題的最優子結構性質是該問題可以用動態規劃法或貪心法求解的關鍵特征。
2)貪心選擇性質:所謂貪心選擇性質是指問題的整體最優解可以通過一系列局部最優的選擇,即貪心選擇來得到,貪心法通常以自頂向下的方式作出一系列的貪心選擇。確定是否有貪心選擇性質
- 通常先考察問題的一個整體最優解,并證明可修改這個最優解,使其從貪心選擇開始
- 作出貪心選擇后,原問題簡化為規模較小的類似子問題
- 用數學歸納法證明,通過每一步貪心選擇,最終可得到問題的整體最優解
貪心法的求解過程
貪心法通常用來求解最優化問題,從某一個初始狀態出發,根據當前的局部最優策略,以滿足約束方程為條件,以使目標函數增長最快(最慢)為準則,在候選集合中進行一系列的選擇,以便盡快構成問題的可行解。
圖問題中的貪心法
TSP問題
TSP問題是指旅行家要旅行n個城市,要求各個城市經歷且僅經歷一次,然后回到出發城市,并要求所走的路程最短。
貪心法求解TSP問題的貪心策略有兩種
最近鄰點策略:從頂點出發,每次選擇相鄰的同時又是距離最短的。該方案的最終結果難以保證,所以pass。
最短鏈接策略:每次在整個圖的范圍內選擇最短邊加入到解集合中,但是,要保證加入解集合中的邊最終形成一個哈密頓回路。因此,當從剩余邊集E’中選擇一條邊(u,v)加入解集合S中,應滿足以下條件:
- 邊(u,v)是邊集E’中代價最小的邊
- 邊(u,v)加入解集合S后,S中不產生回路
- 邊(u,v)加入解集合S后,S不產生分枝
這個思路可以解決TSP問題,獲取最短邊使用堆排序,判斷兩個頂點是否連通及是否產生分枝,使用并查集,可以將時間性能提高為O(nlog2 n)
TSP問題樂扣上沒有相關題目,此處就不做了,不過這個思路其實比動態規劃要容易一些,但是在具體的實現上,困難很多。
圖著色問題
給定無向連通圖G=(V,E),求圖G的最小色數k,使得用k種顏色對G中的頂點著色,可使任意兩個相鄰頂點著色不同。
貪心策略為:選擇一種顏色,以任意頂點作為開始頂點,依次考察圖中的未被著色的每個頂點,如果一個頂點可以用顏色1著色,換言之,該頂點的鄰接點都還未被著色,則用顏色1為該頂點著色,當沒有頂點能以這種顏色著色時,選擇顏色2和一個未被著色的頂點作為開始頂點,用第二種顏色為盡可能多的頂點著色,如果還有未著色的頂點,則選取顏色3并為盡可能多的頂點著色,以此類推。
這種策略和選擇頂點進行著色的順序有很大關系,而且很難確認是最優解,我也不知道為啥作者講這道題。
最小生成樹問題
設G=(V,E)是一個無向連通圖,生成樹上各邊的權值之和稱為該生成樹的代價,在G的所有生成樹中,代價最小的生成樹稱為最小生成樹。
這兩個算法的證明,其實可以用反證法,如果說不是最優的,那么說明存在一個點到其他各個點的距離要小于當前邊,但這個是不存在的,所以說明是最優的。
樂扣的貪心算法系列里,沒有圖相關的算法,所以這里先不做習題了。
組合問題中的貪心法
背包問題
給定n中物品和一個容量為C的背包,物品i的重量是wi,其價值為vi,背包問題是如何選擇裝入背包的物品,使得裝入背包中物品的總價值最大?
這個背包問題不是0/1背包問題,因為物品可以部分裝入,所以可以使用貪心法,貪心策略為:每次從物品集合中選擇單位重量價值最大的物品,單位價值=vi/wi。
活動安排問題
設有n個活動集合E={1,2,……,n},其中每個活動都要求使用同一資源(如演講會場),而在同一時間內只有一個活動能使用這一資源。每個活動i都有一個要求使用該資源的起始時間si和一個結束時間fi,且si<fi。如果選擇了活動i,則它在半開時間區間[si,fi)內占用資源。若區間[si,fi)與區間[sj,fj)不相交,則稱活動i與活動j是相容的。也就是說,當si>=fj或者sj>=fi時,活動i與活動j相容。活動安排問題要求在所給的活動集合中選出最大的相容活動子集。
其中合理的貪心策略為:最早結束時間,這樣可以使下一個活動盡早開始。
將所有活動按照最早結束時間排序,從頭開始選擇不相交的活動,便是最終結果。
麻煩的點在于如何證明該貪心策略能夠計算出正確結果:
- 整體最優解從貪心選擇開始:設E={1,2……,n}為n個活動的集合,且E中的活動按結束時間非減序排列,所以,活動1具有最早的結束時間。首先證明活動安排問題有一個最優解以貪心選擇開始,即該最優解中包含活動1。設A是E的子集且是活動安排問題的一個最優解,且A中的活動也按結束時間非減序排列,A中的第一個活動是活動k。若k=1,則A就是以貪心選擇開始的最優解;若k>1,則設B=A-{k}+1,即在最優解A中用活動1取代活動k。由于f1<=fk,所以B中的活動也是相容的,且B中活動個數與A中活動個數相同,故B也是最優解。由此可見,總存在以貪心選擇開始的最優活動安排方案。
- 作出貪心選擇后,原問題簡化為規模較小的類似子問題:選擇活動1后,原問題簡化為對E中所有與活動1相容的活動安排子問題。也就是說,若A是原問題的最優解,則A’是活動安排子問題E’={si>=f1,si屬于E}的最優解。如果不然,假設B’是E’的最優解,則B‘比A’包含更多的活動,將活動1加入B‘中將產生E的一個解B,且B比A包含更多的活動,這與A是原問題的最優解相矛盾。因此每一步貪心選擇陡降問題簡化為一個規模較小的與原問題具有相同形式的子問題。
- 對貪心選擇次數應用數學歸納法可證,貪心法求解活動安排問題最終產生原問題的最優解。
多機調度問題
設有n個獨立的作業{1,2,……,n},由m臺相同的機器{M1,M2,……,Mm}進行加工處理,作業i鎖需的處理時間為ti(1<=i<=n),每個作業均可在任何一臺機器上加工處理,但不可間斷、拆分。多機調度問題要求給出一種作業調度方案,使所給的n個作業在盡可能短的時間內由m臺機器加工處理完成。
多機調度問題問題是NP難問題,到目前為止還沒有有效的解法。對于這類問題,用貪心法求解有時可以得到較好的近似解。貪心法求解多機調度問題的貪心策略是最長處理時間作業優先,即把處理時間最長的作業分配給最先空閑的機器,這樣可以保證處理時間長的作業優先處理,從而在整體上獲得盡可能短的處理時間。
其實看貪心法這一章的時候,一直沒明白為什么老師在這章里的很多題目,使用貪心法是無法計算出正確結果的。現在我多少有點明白了,因為本書的關鍵并不是在于計算出正確結果,而是讓我們理解貪心法能做什么、不能做什么、能做到什么程度。真實社會中,可能也不需要最準確的結果,因為一些其他因素可能比結果是否最準確影響更大。
總結
本來以為DP的題麻煩,后來發現貪心法其實更麻煩。主要在于使用貪心法需要證明能夠取得最優解
貪心法的證明比動態規劃證明更加復雜一些,而且本章中做的習題,沒有動態規劃法做的更加順暢。建議大家多多練習一下貪心法。
最后
大家如果喜歡我的文章,可以關注我的公眾號(程序員麻辣燙)
我的個人博客為:https://shidawuhen.github.io/
往期文章回顧:
算法
技術
讀書筆記
思考
總結
- 上一篇: java中常见的类
- 下一篇: matlab变压器空载合闸,变压器空载合