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