貪心算法

轉自https://www.cnblogs.com/gavanwanggw/p/7141358.htmlhtml

怎麼理解

 

  貪心法在解決這個問題的策略上目光短淺,僅僅依據當前已有的信息就作出選擇,而且一旦作出了選擇。不管未來有什麼結果,這個選擇都不會改變。算法

 

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

 

 

怎樣推斷

 

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

  咱們可以依據貪心法的2個重要的性質去證實:貪心選擇性質和最優子結構性質htm

  一、貪心選擇

  什麼叫貪心選擇?從字義上就是貪心也就是目光短線。貪圖眼前利益。在算法中就是僅僅依據當前已有的信息就作出選擇,而且之後都不會改變此次選擇。(這是和動態規劃法的主要差異)  對象

  因此對於一個詳細問題。要肯定它是否具備貪心選擇性質,必須證實每作一步貪心選擇是否終於致使問題的整體最優解。blog

  二、最優子結構

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

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

 

 

 

區分動態規劃

 

   動態規劃算法一般以自底向上的方式解各子問題,是遞歸過程。class

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

 

  以二叉樹遍歷爲例:

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

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

 

 

通常求解過程

 

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

  一、候選集合(C)

    經過一個候選集合C做爲問題的可能解。(終於解均取自於候選集合C)

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

 

  二、解集合(S)

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

  三、解決函數(solution)

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

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

  四、選擇函數(select)

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

(這個選擇函數一般和目標函數有關)

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

  五、可行函數(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;

}
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息