❶ 貪心演算法的例題分析
例題1、
[0-1背包問題]有一個背包,背包容量是M=150。有7個物品,物品不可以分割成任意大小。
要求盡可能讓裝入背包中的物品總價值最大,但不能超過總容量。
物品 A B C D E F G
重量 35kg 30kg 6kg 50kg 40kg 10kg 25kg
價值 10$ 40$ 30$ 50$ 35$ 40$ 30$
分析:
目標函數:∑pi最大
約束條件是裝入的物品總重量不超過背包容量:∑wi<=M(M=150)
⑴根據貪心的策略,每次挑選價值最大的物品裝入背包,得到的結果是否最優?
⑵每次挑選所佔重量最小的物品裝入是否能得到最優解?
⑶每次選取單位重量價值最大的物品,成為解本題的策略。
值得注意的是,貪心演算法並不是完全不可以使用,貪心策略一旦經過證明成立後,它就是一種高效的演算法。
貪心演算法還是很常見的演算法之一,這是由於它簡單易行,構造貪心策略不是很困難。
可惜的是,它需要證明後才能真正運用到題目的演算法中。
一般來說,貪心演算法的證明圍繞著:整個問題的最優解一定由在貪心策略中存在的子問題的最優解得來的。
對於例題中的3種貪心策略,都是無法成立(無法被證明)的,解釋如下:
⑴貪心策略:選取價值最大者。
反例:
W=30
物品:A B C
重量:28 12 12
價值:30 20 20
根據策略,首先選取物品A,接下來就無法再選取了,可是,選取B、C則更好。
⑵貪心策略:選取重量最小。它的反例與第一種策略的反例差不多。
⑶貪心策略:選取單位重量價值最大的物品。
反例:
W=30
物品:A B C
重量:28 20 10
價值:28 20 10
根據策略,三種物品單位重量價值一樣,程序無法依據現有策略作出判斷,如果選擇A,則答案錯誤。
【注意:如果物品可以分割為任意大小,那麼策略3可得最優解】
對於選取單位重量價值最大的物品這個策略,可以再加一條優化的規則:對於單位重量價值一樣的,則優先選擇重量小的!這樣,上面的反例就解決了。
但是,如果題目是如下所示,這個策略就也不行了。
W=40
物品:A B C
重量:25 20 15
價值:25 20 15
附:本題是個DP問題,用貪心法並不一定可以求得最優解,以後了解了動態規劃演算法後本題就有了新的解法。
例題2、
馬踏棋盤的貪心演算法
123041-23 XX
【問題描述】
馬的遍歷問題。在8×8方格的棋盤上,從任意指定方格出發,為馬尋找一條走遍棋盤每一格並且只經過一次的一條路徑。
【初步設計】
首先這是一個搜索問題,運用深度優先搜索進行求解。演算法如下:
⒈ 輸入初始位置坐標x,y;
⒉ 步驟 c:
如果c> 64輸出一個解,返回上一步驟c--
(x,y) ← c
計算(x,y)的八個方位的子結點,選出那些可行的子結點
循環遍歷所有可行子結點,步驟c++重復2
顯然⑵是一個遞歸調用的過程,大致如下:
C++程序: #defineN8voiddfs(intx,inty,intcount){inti,tx,ty;if(count>N*N){output_solution();//輸出一個解return;}for(i=0;i<8;i++){tx=hn[i].x;//hn[]保存八個方位子結點ty=hn[i].y;s[tx][ty]=count;dfs(tx,ty,count+1);//遞歸調用s[tx][ty]=0;}}Pascal程序: ProgramYS;ConstFXx:array[1..8]of-2..2=(1,2,2,1,-1,-2,-2,-1);FXy:array[1..8]of-2..2=(2,1,-1,-2,-2,-1,1,2);VarRoad:array[1..10,1..10]ofinteger;x,y,x1,y1,total:integer;ProcereFind(x,y:integer);varNx,Ny,i:integer;BeginFori:=1to8dobegin{8個方向}If(x+FXx[i]in[1..8])and(y+FXy[i]in[1..8])Then{確定新坐標是否越界}IfRoad[x+Fxx[i],y+Fxy[i]]=0Thenbegin{判斷是否走過}Nx:=x+FXx[i];Ny:=y+FXy[i];Road[Nx,Ny]:=1;{建立新坐標}If(Nx=x1)and(Ny=y1)Theninc(total)elseFind(Nx,Ny);{遞歸}Road[Nx,Ny]:=0{回朔}endendEnd;BEGIN{Main}Total:=0;FillChar(Road,sizeof(road),0);Readln(x,y);{讀入開始坐標}Readln(x1,y1);{讀入結束坐標}If(x>10)or(y>10)or(x1>10)or(y1>10)Thenwriteln('Error'){判斷是否越界}ElseFind(x,y);Writeln('Total:',total){打出總數}END.這樣做是完全可行的,它輸入的是全部解,但是馬遍歷當8×8時解是非常之多的,用天文數字形容也不為過,這樣一來求解的過程就非常慢,並且出一個解也非常慢。
怎麼才能快速地得到部分解呢?
【貪心演算法】
其實馬踏棋盤的問題很早就有人提出,且早在1823年,J.C.Warnsdorff就提出了一個有名的演算法。在每個結點對其子結點進行選取時,優先選擇『出口』最小的進行搜索,『出口』的意思是在這些子結點中它們的可行子結點的個數,也就是『孫子』結點越少的越優先跳,為什麼要這樣選取,這是一種局部調整最優的做法,如果優先選擇出口多的子結點,那出口少的子結點就會越來越多,很可能出現『死』結點(顧名思義就是沒有出口又沒有跳過的結點),這樣對下面的搜索純粹是徒勞,這樣會浪費很多無用的時間,反過來如果每次都優先選擇出口少的結點跳,那出口少的結點就會越來越少,這樣跳成功的機會就更大一些。這種演算法稱為為貪心演算法,也叫貪婪演算法或啟發式演算法,它對整個求解過程的局部做最優調整,它只適用於求較優解或者部分解,而不能求最優解。這樣的調整方法叫貪心策略,至於什麼問題需要什麼樣的貪心策略是不確定的,具體問題具體分析。實驗可以證明馬遍歷問題在運用到了上面的貪心策略之後求解速率有非常明顯的提高,如果只要求出一個解甚至不用回溯就可以完成,因為在這個演算法提出的時候世界上還沒有計算機,這種方法完全可以用手工求出解來,其效率可想而知。
❷ 程序員演算法基礎——貪心演算法
貪心是人類自帶的能力,貪心演算法是在貪心決策上進行統籌規劃的統稱。
比如一道常見的演算法筆試題---- 跳一跳 :
我們自然而然能產生一種解法:盡可能的往右跳,看最後是否能到達。
本文即是對這種貪心決策的介紹。
狹義的貪心演算法指的是解最優化問題的一種特殊方法,解決過程中總是做出當下最好的選擇,因為具有最優子結構的特點,局部最優解可以得到全局最優解;這種貪心演算法是動態規劃的一種特例。 能用貪心解決的問題,也可以用動態規劃解決。
而廣義的貪心指的是一種通用的貪心策略,基於當前局面而進行貪心決策。以 跳一跳 的題目為例:
我們發現的題目的核心在於 向右能到達的最遠距離 ,我們用maxRight來表示;
此時有一種貪心的策略:從第1個盒子開始向右遍歷,對於每個經過的盒子,不斷更新maxRight的值。
貪心的思考過程類似動態規劃,依舊是兩步: 大事化小 , 小事化了 。
大事化小:
一個較大的問題,通過找到與子問題的重疊,把復雜的問題劃分為多個小問題;
小事化了:
從小問題找到決策的核心,確定一種得到最優解的策略,比如跳一跳中的 向右能到達的最遠距離 ;
在證明局部的最優解是否可以推出全局最優解的時候,常會用到數學的證明方式。
如果是動態規劃:
要湊出m元,必須先湊出m-1、m-2、m-5、m-10元,我們用dp[i]表示湊出i元的最少紙幣數;
有 dp[i]=min(dp[i-1], dp[i-2], dp[i-5], dp[i-10]) + 1 ;
容易知道 dp[1]=dp[2]=dp[5]=dp[10]=1 ;
根據以上遞推方程和初始化信息,可以容易推出dp[1~m]的所有值。
似乎有些不對? 平時我們找零錢有這么復雜嗎?
從貪心演算法角度出發,當m>10且我們有10元紙幣,我們優先使用10元紙幣,然後再是5元、2元、1元紙幣。
從日常生活的經驗知道,這么做是正確的,但是為什麼?
假如我們把題目變成這樣,原來的策略還能生效嗎?
接下來我們來分析這種策略:
已知對於m元紙幣,1,2,5元紙幣使用了a,b,c張,我們有a+2b+5c=m;
假設存在一種情況,1、2、5元紙幣使用數是x,y,z張,使用了更少的5元紙幣(z<c),且紙幣張數更少(x+y+z<a+b+c),即是用更少5元紙幣得到最優解。
我們令k=5*(c-z),k元紙幣需要floor(k/2)張2元紙幣,k%2張1元紙幣;(因為如果有2張1元紙幣,可以使用1張2元紙幣來替代,故而1元紙幣只能是0張或者1張)
容易知道,減少(c-z)張5元紙幣,需要增加floor(5*(c-z)/2)張2元紙幣和(5*(c-z))%2張紙幣,而這使得x+y+z必然大於a+b+c。
由此我們知道不可能存在使用更少5元紙幣的更優解。
所以優先使用大額紙幣是一種正確的貪心選擇。
對於1、5、7元紙幣,比如說要湊出10元,如果優先使用7元紙幣,則張數是4;(1+1+1+7)
但如果只使用5元紙幣,則張數是2;(5+5)
在這種情況下,優先使用大額紙幣是不正確的貪心選擇。(但用動態規劃仍能得到最優解)
如果是動態規劃:
前i秒的完成的任務數,可以由前面1~i-1秒的任務完成數推過來。
我們用 dp[i]表示前i秒能完成的任務數 ;
在計算前i秒能完成的任務數時,對於第j個任務,我們有兩種決策:
1、不執行這個任務,那麼dp[i]沒有變化;
2、執行這個任務,那麼必須騰出來(Sj, Tj)這段時間,那麼 dp[i] = max(dp[i], dp[ S[j] ] ) + 1 ;
比如說對於任務j如果是第5秒開始第10秒結束,如果i>=10,那麼有 dp[i]=max(dp[i], dp[5] + 1); (相當於把第5秒到第i秒的時間分配給任務j)
再考慮貪心的策略,現實生活中人們是如何安排這種多任務的事情?我換一種描述方式:
我們自然而然會想到一個策略: 先把結束時間早的兼職給做了!
為什麼?
因為先做完這個結束時間早的,能留出更多的時間做其他兼職。
我們天生具備了這種優化決策的能力。
這是一道 LeetCode題目 。
這個題目不能直接用動態規劃去解,比如用dp[i]表示前i個人需要的最少糖果數。
因為(前i個人的最少糖果數)這種狀態表示會收到第i+1個人的影響,如果a[i]>a[i+1],那麼第i個人應該比第i+1個人多。
即是 這種狀態表示不具備無後效性。
如果是我們分配糖果,我們應該怎麼分配?
答案是: 從分數最低的開始。
按照分數排序,從最低開始分,每次判斷是否比左右的分數高。
假設每個人分c[i]個糖果,那麼對於第i個人有 c[i]=max(c[i-1],c[c+1])+1 ; (c[i]默認為0,如果在計算i的時候,c[i-1]為0,表示i-1的分數比i高)
但是,這樣解決的時間復雜度為 O(NLogN) ,主要瓶頸是在排序。
如果提交,會得到 Time Limit Exceeded 的提示。
我們需要對貪心的策略進行優化:
我們把左右兩種情況分開看。
如果只考慮比左邊的人分數高時,容易得到策略:
從左到右遍歷,如果a[i]>a[i-1],則有c[i]=c[i-1]+1;否則c[i]=1。
再考慮比右邊的人分數高時,此時我們要從數組的最右邊,向左開始遍歷:
如果a[i]>a[i+1], 則有c[i]=c[i+1]+1;否則c[i]不變;
這樣講過兩次遍歷,我們可以得到一個分配方案,並且時間復雜度是 O(N) 。
題目給出關鍵信息:1、兩個人過河,耗時為較長的時間;
還有隱藏的信息:2、兩個人過河後,需要有一個人把船開回去;
要保證總時間盡可能小,這里有兩個關鍵原則: 應該使得兩個人時間差盡可能小(減少浪費),同時船回去的時間也盡可能小(減少等待)。
先不考慮空船回來的情況,如果有無限多的船,那麼應該怎麼分配?
答案: 每次從剩下的人選擇耗時最長的人,再選擇與他耗時最接近的人。
再考慮只有一條船的情況,假設有A/B/C三個人,並且耗時A<B<C。
那麼最快的方案是:A+B去, A回;A+C去;總耗時是A+B+C。(因為A是最快的,讓其他人來回時間只會更長, 減少等待的原則 )
如果有A/B/C/D四個人,且耗時A<B<C<D,這時有兩種方案:
1、最快的來回送人方式,A+B去;A回;A+C去,A回;A+D去; 總耗時是B+C+D+2A (減少等待原則)
2、最快和次快一起送人方式,A+B先去,A回;C+D去,B回;A+B去;總耗時是 3B+D+A (減少浪費原則)
對比方案1、2的選擇,我們發現差別僅在A+C和2B;
為何方案1、2差別里沒有D?
因為D最終一定要過河,且耗時一定為D。
如果有A/B/C/D/E 5個人,且耗時A<B<C<D<E,這時如何抉擇?
仍是從最慢的E看。(參考我們無限多船的情況)
方案1,減少等待;先送E過去,然後接著考慮四個人的情況;
方案2,減少浪費;先送E/D過去,然後接著考慮A/B/C三個人的情況;(4人的時候的方案2)
到5個人的時候,我們已經明顯發了一個特點:問題是重復,且可以由子問題去解決。
根據5個人的情況,我們可以推出狀態轉移方程 dp[i] = min(dp[i - 1] + a[i] + a[1], dp[i - 2] + a[2] + a[1] + a[i] + a[2]);
再根據我們考慮的1、2、3、4個人的情況,我們分別可以算出dp[i]的初始化值:
dp[1] = a[1];
dp[2] = a[2];
dp[3] = a[2]+a[1]+a[3];
dp[4] = min(dp[3] + a[4] + a[1], dp[2]+a[2]+a[1]+a[4]+a[2]);
由上述的狀態轉移方程和初始化值,我們可以推出dp[n]的值。
貪心的學習過程,就是對自己的思考進行優化。
是把握已有信息,進行最優化決策。
這里還有一些收集的 貪心練習題 ,可以實踐練習。
這里 還有在線分享,歡迎報名。
❸ 貪心演算法及其應用
求解一個問題時有多個步驟,每個步驟都選擇當下最優的那個解,而不用考慮整體的最優解。通常,當我們面對的問題擁有以下特點的時候,就可以考慮使用貪心演算法。
比如,我們舉個例子,倉庫裡面總共有五種豆子,其對應的重量和總價值如下,現在我們有一個可以裝100KG重量的袋子,怎麼裝才能使得袋子中的豆子價值最大?
我們首先看看這個問題是否符合貪心演算法的使用場景?限制值是袋子100KG,期望值是袋子裡面的價值最高。所以是符合的。那麼我們嘗試著應用下貪心演算法的方法,每一個步驟都尋找當下的最優解,怎麼做呢?
把倉庫裡面的每種豆子價值除以重量,得出每種豆子的單價,那麼當下的最優解,肯定是盡可能最多地裝單價最貴的,也就是先把20KG的黃豆都裝上,然後再把30KG的綠豆都裝上,再裝50KG的紅豆,那麼此時正好裝滿袋子,總價值將是270元,這就是通過貪心演算法求解的答案。
貪心演算法的應用在這個問題上的求解是否是最優解需要一個很復雜的數學論證,我們不用那樣,只要心裡舉幾個例子,驗證下是否比它更好即可,如果舉不出例子,那麼就可以認為這就是最優解了。
雖然貪心演算法雖然在大部分實踐場景中都能得到最優解,但是並不能保證一定是最優解。比如在如下的有向帶權圖中尋找從S到T的最短路徑,那麼答案肯定就是S->A->E->T,總代價為1+4+4=9;
然而,實際上的最短路徑是S->B->D->T,總代價為6。
所以,不能所有這類問題都迷信貪心演算法的求解,但其作為一種演算法指導思想,還是很值得學習的。
除了以上袋子裝豆子的問題之外,還有很多應用場景。這種問題能否使用貪心演算法來解決的關鍵是你能否將問題轉換為貪心演算法適用的問題,即找到問題的限制值和期望值。
我們有m個糖果要分給n個孩子,n大於m,註定有的孩子不能分到糖果。其中,每個糖果的大小都不同,分別為S1,S2,S3...,Sm,每個孩子對糖果的需求也是不同的,為N1,N2,N3...,Nn,那麼我們如何分糖果,才能盡可能滿足最多數量孩子的需求?
這個問題中,限制值是糖果的數量m,期望值滿足最多的孩子需求。對於每個孩子,能用小的糖果滿足其需求,就不要用大的,避免浪費。所以我們可以給所有孩子的需求排個序,從需求最小的孩子開始,用剛好能滿足他的糖果來分給他,以此來分完所有的糖果。
我們有1元、5元、10元、20元、50元、100元紙幣各C1、C5、C10、C20、C50、C100張,現在要購買一個價值K元的東西,請問怎麼才能適用最少的紙幣?
這個問題應該不難,限制值是各個紙幣的張數,期望值是適用最少的紙幣。那麼我們就先用面值最大的100元去付錢,當再加一張100元就超過K時,就更換小面額的,直至正好為K元。
對於n個區間[L1,R1],[L2,R2]...[Ln,Rn],我們怎麼從中選出盡可能多的區間,使它們不相交?
我們需要把這個問題轉換為符合貪心演算法特點的問題,假設這么多區間的最左端點是Lmin,最右端點是Rmax,那麼問題就是在[Lmin,Rmax]中,選擇盡可能多的區間往裡面塞,並且保證它們不相交。這里,限制值就是區間[Lmin,Rmax],期望值就是盡可能多的區間。
我們的解決辦法就是每次從區間中選擇那種左端點>=已經覆蓋區間右邊端點的,且該區間右端點盡可能高小的。如此,我們可以讓未覆蓋區間盡可能地大,才能保證可以塞進去盡可能多的區間。
貪心演算法最重要的就是學會如何將要解決的問題抽象成適合貪心演算法特點的模型,找到限制條件和期望值,只要做好這一步,接下來的就比較簡單了。在平時我們不用刻意去記,多多練習類似的問題才是最有效的學習方法。
❹ 活動選擇(貪心演算法)
參考: 【演算法導論】貪心演算法之活動選擇問題
貪心演算法(Greedy Algorithm)在每一步都做出當時看起來最佳的選擇,寄希望這樣的選擇能導致全局最優解。
這種演算法並不能保證得到最優解,但對很多問題確實可以求得最優解。
假定有一個n個活動的集合S={a1,a2,a3,...,an},這些活動 使用同一個資源 ,而這個資源在某個時刻 只能給一個活動使用 。每個活動都有一個 開始時間si 和一個 結束時間fi ,其中0<=si<fi<=∞。
如果活動ai被選中,則此活動發生在 半開區間[si,fi) 中。
若兩個活動ai和aj的 時間區間不重疊 ,則稱這兩個活動是 兼容 的
在活動選擇問題中,我們希望選出一個最大兼容活動集。
假定活動已經按照 結束時間遞增順序 排好序
f1<=f2<=f3<=...<=fn
考慮如下例子:
可以看到,{a3,a9,a11}是由相互兼容的活動組成。但它不是一個最大集,{a1,a4,a8,a11}更大,是一個最大集。(最大集不唯一)
假設:Sij表示在ai結束之後,在aj開始之前的活動的 集合 。Aij表示Sij的一個最大相互兼容的活動子集。
那麼只要Sij非空,則Aij至少會包含一個活動,假設為ak。那麼可以將Aij分解為:Aij = Aik+ak+Akj。
假設Cij為Aij的大小,那麼有Cij=cik+ckj+1。
於是,我們可以利用動態規劃得到這個問題的遞歸解
我們當然可以利用動態規劃自底向上地求解這個問題,但是我們可以利用貪心演算法更快地求解問題答案。
我們選擇活動 結束時間最早 的那個活動,這樣能夠給其他活動盡可能的騰出多餘的時間,而後每一步都在剩下的活動中選取最早的活動,這樣就可以獲得一個最優解。
為什麼貪心選擇——最早結束的活動ai——總是最優解的一部分呢?
假設Aij是Sij的某個最大兼容活動集,假設Aij中,最早結束的活動是an。(an是最優解中最早結束的,不一定是原先活動中最早結束的)我們要證明我們選擇的a1(原先活動集中最早結束的)也在最優解中。
分兩種情況:
①如果an=a1,則得證
②如果an不等於a1,則an的結束時間一定會 晚於 a1的結束時間,我們用a1去 替換 Aij中的an,於是得到A',由於a1比an結束的早,而Aij中的其他活動都比an的結束時間開始 的要晚,所以A'中的 其他活動 都與a1不相交 ,所以A'中的所有活動是兼容的,所以A`也是Sij的一個最大兼容活動集。
(簡單說,就是用a1 替換 an,得到另一個解A',由於a1最早結束,當然與其他活動不相交,於是A'也兼容且個數和A一樣,所以A'也是最優解)
於是證明了命題。
通過以上分析,我們可以反復地選擇最先結束的活動,保留於此活動兼容的活動,重復執行,直到不再有剩餘活動。
貪心演算法通常是 自頂向下 地設計:做出一個選擇,然後求解剩下的那個子問題
為了方便初始化,我們添加一個虛擬活動a0,其結束時間為f0=0
由於我們之前就已經將活動按結束時間排好序,每一次找元素都只對元素訪問一次,所以貪心演算法的時間復雜度是大theta(n)
❺ [演算法] 貪心演算法證明思路
動態規劃和貪心演算法都需要問題具有最優子結構,但不同的是貪心 自頂向下 ,先做選擇再求解一個結果子問題,而動態規劃自底向上求解子問題,需要先求出子問題的最優解再做選擇。這是因為,動態規劃最優解有兩個子問題時,求解子問題 時有j-i-1種選擇,但貪心選擇特徵能夠使 其中一個子問題必定為空 ,這種子問題和選擇數目的減少使得子問題能夠自頂向下被解決。
a) 定義子問題空間,做出一個選擇從而產生一個或多個子問題。子問題空間的定義結合需要求解的目標和選擇後子問題的描述刻畫來考慮。
b) 利用「剪切-粘貼」證明作為最優解的組成部分的每個子問題的解也是它本身的最優解。如果子問題的解不是最優解,將其替換為對應的最優解從而一定能得到原問題一個更優的解,這與最初的解是原問題的最優解的前提假設矛盾,因此最優子結構得證。
貪心的本質是局部最優解能產生全局最優解,即產生兩個子問題 和 時,可以直接解決子問題 (在子問題 中,使用貪心策略選擇a作為局部最優解)然後對子問題 進行分解,最終可以合並為全局最優解。
因此,要證明貪心選擇性質只需要證明 存在一個最優解是通過當前貪心選擇策略得到的 ,反過來,即證明**通過非貪心策略得到的原問題的最優解中也一定包含局部最優解a。
定義通過非貪心策略的選擇可以得到的一個最優解A,將最優解中的元素和當前貪心策略會選擇的元素逐個交換後得到的解A'並不比
A差(假設貪心策略會選擇的元素在當前最優解中未被選擇,通過「剪切-粘貼」證明得到的仍是最優解),可以證明存在原問題的最優解可以通過貪心選擇得到。
❻ 劉汝佳的演算法藝術與信息學竟賽13頁1.2.2節貪心法例一:釣魚!分析部分第一段話怎樣理解
貪心法(Greedy algorithm)是一種在每一步選擇中都採取在當前狀態下最好/優的選擇,從而希望導致結果是最好/優的演算法。比如在旅行推銷員問題中,如果旅行員每次都選擇最近的城市, 那這就是一種貪心演算法。
貪心演算法在有最優子結構的問題中尤為有效。最優子結構的意思是局部最優解能決定全局最優解。簡單地說,問題能夠分解成子問題來解決,子問題的最優解能遞推到最終問題的最優解。
貪心演算法與動態規劃的不同在於它每對每個子問題的解決方案都做出選擇,不能回退。動態規劃則會保存以前的運算結果,並根據以前的結果對當前進行選擇,有回退功能。
貪心法可以解決一些最優性問題,如:求圖中的最小生成樹、求哈夫曼編碼……對於其他問題,貪心法一般不能得到我們所要求的答案。一旦一個問題可以通過貪心法來解決,那麼貪心法一般是解決這個問題的最好辦法。由於貪心法的高效性以及其所求得的答案比較接近最優結果,貪心法也可以用作輔助演算法或者直接解決一些要求結果不特別精確的問題。
貪心法解題特點
貪心法有一個共同的點就是在最優求解的過程中都採用一種局部最優策略,把問題范圍和規模縮小最後把每一步的結果合並起來得到一個全局最優解。
貪心法解題的一般步驟
(1)從問題的某個初始解出發;
(2)採用循環語句,當可以向求解目標前進一部時,就根據局部最優策略,得到一個部分解,縮小問題的范圍和規模;
(3)將所有部分解綜合起來,得到問題最終解。
❼ 貪心演算法幾個經典例子
[背包問題]有一個背包,背包容量是M=150。有7個物品,物品可以分割成任意大小。
要求盡可能讓裝入背包中的物品總價值最大,但不能超過總容量。
貪心演算法是很常見的演算法之一,這是由於它簡單易行,構造貪心策略簡單。但是,它需要證明後才能真正運用到題目的演算法中。一般來說,貪心演算法的證明圍繞著整個問題的最優解一定由在貪心策略中存在的子問題的最優解得來的。
對於本例題中的3種貪心策略,都無法成立,即無法被證明。