五大算法思想—貪心算法


怎么理解


  貪心法在解決這個問題的策略上目光短淺,僅僅依據當前已有的信息就做出選擇,並且一旦做出了選擇。無論將來有什么結果,這個選擇都不會改變。

  一句話:不求最優,僅僅求可行解。


怎樣推斷


    對於一個詳細的問題,怎么知道是否可用貪心算法解此問題,以及是否能得到問題的最優解?

  我們能夠依據貪心法的2個重要的性質去證明:貪心選擇性質和最優子結構性質

  1、貪心選擇

  什么叫貪心選擇?從字義上就是貪心也就是目光短線。貪圖眼前利益。在算法中就是僅僅依據當前已有的信息就做出選擇,並且以后都不會改變這次選擇。(這是和動態規划法的主要差別)  

  所以對於一個詳細問題。要確定它是否具有貪心選擇性質,必須證明每做一步貪心選擇是否終於導致問題的總體最優解。

  2、最優子結構

  當一個問題的最優解包括其子問題的最優解時,稱此問題具有最優子結構性質。

  這個性質和動態規划法的一樣,最優子結構性質是可用動態規划算法或貪心算法求解的關鍵特征。

 



區分動態規划


   動態規划算法通常以自底向上的方式解各子問題,是遞歸過程。

  貪心算法則通常以自頂向下的方式進行,以迭代的方式作出相繼的貪心選擇,每作一次貪心選擇就將所求問題簡化為規模更小的子問題。


  以二叉樹遍歷為例:

   貪心法是從上到下僅僅進行深度搜索。也就是說它從根節點一口氣走到黑的,它的代價取決於子問題的數目,也就是樹的高度,每次在當前問題的狀態上作出的選擇都是1。不進行廣度搜索。所以終於它得出的解不一定是最優解。非常有可能是近似最優解。

  而動態規划法在最優子結構的前提下,從樹的葉子節點開始向上進行搜索,而且在每一步都依據葉子節點的當前問題的狀況作出選擇,從而作出最優決策。所以她的代價是子問題的個數和可選擇的數目。它求出的解一定是最優解。



一般求解過程


  使用貪心法求解能夠依據下面幾個方面進行(終於也相應着每步代碼的實現),以找零錢為例:

  1、候選集合(C)

    通過一個候選集合C作為問題的可能解。(終於解均取自於候選集合C)

    比如。在找零錢問題中,各種面值的貨幣構成候選集合。

  2、解集合(S)

    每完畢一次貪心選擇,將一個解放入S。終於獲得一個完整解S

  3、解決函數(solution)

    檢查解集合S是否構成問題的完整解。

    比如,在找零錢問題中。解決函數是已付出的貨幣金額恰好等於應付款。

  4、選擇函數(select)

    即貪心策略。這是貪心法的關鍵,選擇出最有希望構成問題的解的對象。

(這個選擇函數通常和目標函數有關)

          比如,在找零錢問題中,貪心策略就是在候選集合中選擇面值最大的貨幣。

  5、可行函數(feasible)

    檢查解集合中增加一個候選對象是否可行。(增加下一個對象后是不是滿足約束條件)

    比如。在找零錢問題中,可行函數是每一步選擇的貨幣和已付出的貨幣相加不超過應付款。

       


 

C的實現:(一般試題就是在這個基礎上加入詳細的實現)

  
Greedy(C)  //C是問題的輸入集合即候選集合

{

    S={ }; //初始解集合為空集

    while (not solution(S))  //集合S沒有構成問題的一個解

    {

       x=select(C);    //在候選集合C中做貪心選擇

       if feasible(S, x)  //推斷集合S中增加x后的解是否可行

          S=S+{x};

          C=C-{x};

    }

    return S;

}



小結


  像找零問題,背包問題。近期臨點都是非常經典的貪心算法。並且都是實際的問題。理解上不太難,對於算法題,在理解算法思想的基礎上,多做題,查找規律,多總結一些C實現中重要的代碼段。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM