貪婪法,又稱貪心演算法,是尋找最優解問題的常用方法,這種方法模式一般將求解過程分成若干個步驟,但每個步驟都應用貪心原則,選取當前狀態下最好的或最優的選擇(區域性最有利的選擇),並以此希望最後堆疊出的結果也是最好或最優的解。
貪婪法的每次決策都以當前情況為基礎並根據某個最優原則進行選擇,不從整體上考慮其他各種可能的情況。
貪婪法與其他方法最大的不同在於,貪婪法每一步選擇完區域性最優解之後就確定了,不再進行回溯處理,也就是說,每乙個步驟的區域性最優解確定以後,就不再修改,直到演算法結束。
因為不進行回溯處理,貪婪法只在很少的情況下可以得到真正的最優解,比如最短路徑問題、圖的最小生成樹問題。在大多數情況下,由於選擇策略的「短視」,貪婪法會錯過真正的最優解,而得不到問題的真正答案。
但是貪婪法簡單、高效,省去了為找最優解可能需要的窮舉操作,可以得到與最優解比較接近的近似最優解,通常作為其他演算法的輔助演算法來使用。
貪婪法的基本設計思想有以下三個步驟:
舉個例子:某國發行的貨幣有 25 分、10 分、5 分和 1 分四種硬幣,如果你是售貨員且要找給客戶 41 分錢的硬幣,如何安排才能找給客人的錢既正確且硬幣的個數又最少?
這個問題的子問題定義就是從四種幣值的硬幣中選擇一枚,使這個硬幣的幣值和其他已經選擇的硬幣的幣值總和不超過 41 分錢。
子問題的最優解結構就是在之前的步驟已經選擇的硬幣再加上當前選擇的一枚硬幣,當然,選擇的策略是貪婪策略,即在幣值總和不超過 41 的前提下選擇幣值最大的那種硬幣。按照這個策略,第一步會選擇 25 分的硬幣一枚,第二步會選擇 10 分的硬幣一枚,第三步會選擇 5 分的硬幣一枚,第四步會選擇 1 分的硬幣一枚,總共需要 4 枚硬幣。
上面的例子得到的確實是乙個最優解,但是很多情況下貪婪法都不能得到最優解。同樣以找零錢為例,假如,某國貨幣發行為 25 分、20 分、5 分和 1 分四種硬幣,這時候找 41 分錢的最優策略是 2 枚 20 分的硬幣加上 1 枚 1 分硬幣,一共 3 枚硬幣,但是用貪婪法得到的結果卻是 1 枚 25 分硬幣、3 枚 5 分硬幣和 1 枚 1 分硬幣,一共 5 枚硬幣。
貪婪法的經典例子—— 0-1 揹包問題:有 n 件物品和乙個承重為 c 的揹包(也可定義為體積),每件物品的重量是 wi,價值是 pi,求解將哪幾件物品裝入揹包可使這些物品在重量總和不超過 c 的情況下價值總和最大。
揹包問題(knapsack problem)是此類組合優化的 np 完全問題的統稱,如貨箱裝載問題、貨船載物問題等,因問題最初**於如何選擇最合適的物品裝在揹包中而得名,這個問題隱含了乙個條件,每個物品只有一件,也就是限定每件物品只能選擇 0 個或 1 個,因此又被稱為 0-1 揹包問題。
來看乙個具體的例子,有乙個揹包,最多能承載重量為 c=150 的物品,現在有 7 個物品(物品不能分割成任意大小),編號為 1~7,重量分別是 wi=[35,30,60,50,40,10,25],價值分別是 pi=[10,40,30,50,35,40,30],現在從這 7 個物品中選擇乙個或多個裝入揹包,要求在物品總重量不超過 c 的前提下,所裝入的物品總價值最高。
常見的貪婪策略:
根據物品價值選擇,每次都選價值最高的物品;
根據物品重量選擇,每次都選擇重量最輕的物品;
定義乙個價值密度的概念,每次選擇都選價值密度最高的物品,物品的價值密度 si 定義為 pi/wi;
常用演算法設計方法 六 貪婪法
貪婪法是一種不追求最優解,只希望得到較為滿意解的方法。貪婪法一般可以快速得到滿意的解,因為它省去了為找最優解要窮盡所有可能而必須耗費的大量時間。貪婪法常以當前情況為基礎作最優選擇,而不考慮各種可能的整體情況,所以貪婪法不要回溯。例如平時購物找錢時,為使找回的零錢的硬幣數最少,不考慮找零錢的所有各種發...
演算法設計思想(1) 窮舉法
本文系 王曉華 老師 gitchat 演算法應該怎麼玩 課程筆記。窮舉法又稱窮舉搜尋法,是一種在問題域的解空間中對所有可能的解窮舉搜尋,並根據條件選擇最優解的方法的總稱。數學上也把窮舉法稱為列舉法,就是在乙個由有限個元素構成的集合中,把所有元素一一枚舉研究的方法。窮舉法一般用來找出符合條件的所有解,...
常見演算法思想之動態規劃 貪婪演算法
最近總是跟動態規劃打交道,索性就將其弄明白一點。所謂的動態規劃並不是一種具體的演算法,而是一種演算法的思想。思想總是抽象的,縹緲的。所以在學習動態規劃的時候會有一種很尷尬的情況,就是感覺這個東西很簡單,但是又不知道自己是不是真的學會了。簡單的來說,動態規劃就是將乙個大問題分解為子問題,然後根據子問題...