經典貪心演算法 貪心演算法概述

2022-05-12 07:38:59 字數 1390 閱讀 4754

貪心演算法具有最優子問題結構,它的特點是「短視」,每次選擇對當前局面最有利的決策,來一步步獲得最優解。

我個人認為,貪心不是乙個具體的方法,而是一類方法,貪心演算法的關鍵不在於想到,而在於正確性的證明。要證明乙個貪心演算法是正確的,需要證明我們可以把乙個最優解逐步轉化為我們用貪心演算法所得到的解,而解不會更差,從而證明貪心演算法得到的解和最優解是一樣好的(顯然,最優解不可能更好)。而要證明乙個貪心演算法是錯誤的,只需要找到乙個反例就可以了。

通常情況下,證明貪心演算法是正確的或者找到貪心演算法的乙個反例都不那麼容易。

而且即使對於同乙個問題,從不同角度的貪心演算法的正確性也不盡相同。例如dijkstra演算法是著名的求單源圖最短路徑的貪心演算法。

如果我們也給出乙個貪心演算法,從源頭開始每次選擇最短的邊繼續走,直到走到,直到經過全部點或者無路可走。按照我們的演算法,在上圖中,a到c的最短路是a-b-c,它的長度是5,顯然a-d-c才是真正的最短路。我們的貪心演算法是錯的。

乙個問題即使不能使用某個貪心演算法,也可以通過貪心演算法給出乙個「還說得過去」的解,這也是貪心演算法在現實中存在的意義之一。

基本的演算法中貪心著名的貪心演算法包括: dijskstr單源圖最短路徑演算法、prim和kruskal最小生成樹演算法、huffman編碼簡單壓縮演算法等。

如果給貪心演算法乙個抽象地描述,我認為可以這樣講: 假設一些物件的集合s, 每個物件x對應乙個收益payoff(x),對於任意s的子集t,我們有乙個函式可以判斷它是否合法isvalid(t) ——它返回布林值。並且這個函式通常有個性質,空集是合法的;如果 t合法,它的任意子集都合法;如果它非法,它的任意超集都非法。我們的目標是從 s中選取若干個物件,形成乙個集合v,使得isvalid(v) == true並且payoff(v)盡可能大。其中payoff(v)定義為v中所有物件的收益之和。貪心演算法是這麼解決這個問題的,從空集合開始,每次選乙個payoff最大並且合法的物件x加入到v裡面, v = vu。

可見具備上述性質的問題實際上還是比較特殊的,而上述性質通常成為貪心選擇性。

可見貪心選擇是比較「短視」的,選取最優的乙個元素,即使有多個,任選乙個。而動態規劃演算法是從所有能達到當前狀態的狀態和決策中選取,所以從某種角度上講,動態規劃是列舉——只是聰明點的列舉罷了,它列舉的是所有狀態以及該狀態下的決策。而貪心只是單一的選擇,盲目選擇當前最優的決策。

貪心和動態規劃演算法的比較可見下表:

本章主要講述貪心演算法,讓我們一起來領略它的風采吧。

所以一般對於乙個問題來說,我們只講這樣乙個貪心演算法是錯誤的,而不說這個問題不能採用貪心演算法——因為可能從別的角度設計出的貪心演算法是正確。

演算法 貪心演算法

把乙個複雜問題分解為一系列較為簡單的區域性最優選擇,每乙個選擇都是對當前解的乙個擴充套件,知道獲得問題的完整解。在解決問題的策略上目光短淺,只根據當前已有的資訊做出選擇,而且一旦做出了選擇,不管將來有什麼結果這個選擇都不會改變。換言之,貪心法並不是從整體最優考慮,它所做出的選擇只是在某種意義上的區域...

演算法 貪心演算法

集合覆蓋問題 旅行商問題等都屬於np完全問題,在數學領域上並沒有快速得到最優解的方案,非常適合用貪婪演算法。判斷方法 1.元素較少時,一般執行速度很快,但隨著元素數量增多,速度會變得非常慢 2.涉及到需要計算比較 所有的組合 情況的通常是np完全問題 3.無法分割成小問題,必須考慮各種可能的情況。這...

演算法 貪心演算法

貪心演算法,又稱貪婪演算法 greedy algorithm 是指在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優解出發來考慮,它所做出的僅是在某種意義上的區域性最優解。貪婪演算法是一種分階段的工作,在每乙個階段,可以認為所做決定是最好的,而不考慮將來的後果。這種 眼下能夠拿到...