轉自https://www.cnblogs.com/gavanwanggw/p/7141358.htmlhtml
貪心法在解決這個問題的策略上目光短淺,僅僅依據當前已有的信息就作出選擇,而且一旦作出了選擇。不管未來有什麼結果,這個選擇都不會改變。算法
一句話:不求最優,僅僅求可行解。函數
對於一個詳細的問題,怎麼知道是否可用貪心算法解此問題,以及是否能獲得問題的最優解?code
咱們可以依據貪心法的2個重要的性質去證實:貪心選擇性質和最優子結構性質。htm
什麼叫貪心選擇?從字義上就是貪心也就是目光短線。貪圖眼前利益。在算法中就是僅僅依據當前已有的信息就作出選擇,而且之後都不會改變此次選擇。(這是和動態規劃法的主要差異) 對象
因此對於一個詳細問題。要肯定它是否具備貪心選擇性質,必須證實每作一步貪心選擇是否終於致使問題的整體最優解。blog
當一個問題的最優解包括其子問題的最優解時,稱此問題具備最優子結構性質。遞歸
這個性質和動態規劃法的同樣,最優子結構性質是可用動態規劃算法或貪心算法求解的關鍵特徵。io
動態規劃算法一般以自底向上的方式解各子問題,是遞歸過程。class
貪心算法則一般以自頂向下的方式進行,以迭代的方式做出相繼的貪心選擇,每做一次貪心選擇就將所求問題簡化爲規模更小的子問題。
貪心法是從上到下僅僅進行深度搜索。也就是說它從根節點一口氣走到黑的,它的代價取決於子問題的數目,也就是樹的高度,每次在當前問題的狀態上做出的選擇都是1。不進行廣度搜索。因此終於它得出的解不必定是最優解。很是有多是近似最優解。
而動態規劃法在最優子結構的前提下,從樹的葉子節點開始向上進行搜索,並且在每一步都依據葉子節點的當前問題的情況做出選擇,從而做出最優決策。因此她的代價是子問題的個數和可選擇的數目。它求出的解必定是最優解。
使用貪心法求解可以依據下面幾個方面進行(終於也相應着每步代碼的實現),以找零錢爲例:
經過一個候選集合C做爲問題的可能解。(終於解均取自於候選集合C)
好比。在找零錢問題中,各類面值的貨幣構成候選集合。
每完畢一次貪心選擇,將一個解放入S。終於得到一個完整解S
檢查解集合S是否構成問題的完整解。
好比,在找零錢問題中。解決函數是已付出的貨幣金額剛好等於應付款。
即貪心策略。這是貪心法的關鍵,選擇出最有但願構成問題的解的對象。
(這個選擇函數一般和目標函數有關)
好比,在找零錢問題中,貪心策略就是在候選集合中選擇面值最大的貨幣。
檢查解集合中增長一個候選對象是否可行。(增長下一個對象後是否是知足約束條件)
好比。在找零錢問題中,可行函數是每一步選擇的貨幣和已付出的貨幣相加不超過應付款。
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; }