⑴ 貪心演算法的特性
貪婪演算法可解決的問題通常大部分都有如下的特性:
⑴隨著演算法的進行,將積累起其它兩個集合:一個包含已經被考慮過並被選出的候選對象,另一個包含已經被考慮過但被丟棄的候選對象。
⑵有一個函數來檢查一個候選對象的集合是否提供了問題的解答。該函數不考慮此時的解決方法是否最優。
⑶還有一個函數檢查是否一個候選對象的集合是可行的,也即是否可能往該集合上添加更多的候選對象以獲得一個解。和上一個函數一樣,此時不考慮解決方法的最優性。
⑷選擇函數可以指出哪一個剩餘的候選對象最有希望構成問題的解。
⑸最後,目標函數給出解的值。
⑹為了解決問題,需要尋找一個構成解的候選對象集合,它可以優化目標函數,貪婪演算法一步一步的進行。起初,演算法選出的候選對象的集合為空。接下來的每一步中,根據選擇函數,演算法從剩餘候選對象中選出最有希望構成解的對象。如果集合中加上該對象後不可行,那麼該對象就被丟棄並不再考慮;否則就加到集合里。每一次都擴充集合,並檢查該集合是否構成解。如果貪婪演算法正確工作,那麼找到的第一個解通常是最優的。
⑵ 貪心演算法的本質
1. 貪心法(Greedy Algorithm)定義
求解最優化問題的演算法通常需要經過一系列的步驟,在每個步驟都面臨多種選擇;
貪心法就是這樣的演算法:它在每個決策點作出在當時看來最佳的選擇,即總是遵循某種規則,做出局部最優的選擇,以推導出全局最優解(局部最優解->全局最優解)
2. 對貪心法的深入理解
(1)原理:一種啟發式策略,在每個決策點作出在當時看來最佳的選擇
(2)求解最優化問題的兩個關鍵要素:貪心選擇性質+最優子結構
①貪心選擇性質:進行選擇時,直接做出在當前問題中看來最優的選擇,而不必考慮子問題的解;
②最優子結構:如果一個問題的最優解包含其子問題的最優解,則稱此問題具有最優子結構性質
(3)解題關鍵:貪心策略的選擇
貪心演算法不是對所有問題都能得到整體最優解的,因此選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。
(4)一般步驟:
①建立數學模型來描述最優化問題;
②把求解的最優化問題轉化為這樣的形式:對其做出一次選擇後,只剩下一個子問題需要求解;
③證明做出貪心選擇後:
1°原問題總是存在全局最優解,即貪心選擇始終安全;
2°剩餘子問題的局部最優解與貪心選擇組合,即可得到原問題的全局最優解。
並完成2°
3. 貪心法與動態規劃
最優解問題大部分都可以拆分成一個個的子問題,把解空間的遍歷視作對子問題樹的遍歷,則以某種形式對樹整個的遍歷一遍就可以求出最優解,大部分情況下這是不可行的。貪心演算法和動態規劃本質上是對子問題樹的一種修剪,兩種演算法要求問題都具有的一個性質就是子問題最優性(組成最優解的每一個子問題的解,對於這個子問題本身肯定也是最優的)。動態規劃方法代表了這一類問題的一般解法,我們自底向上構造子問題的解,對每一個子樹的根,求出下面每一個葉子的值,並且以其中的最優值作為自身的值,其它的值舍棄。而貪心演算法是動態規劃方法的一個特例,可以證明每一個子樹的根的值不取決於下面葉子的值,而只取決於當前問題的狀況。換句話說,不需要知道一個節點所有子樹的情況,就可以求出這個節點的值。由於貪心演算法的這個特性,它對解空間樹的遍歷不需要自底向上,而只需要自根開始,選擇最優的路,一直走到底就可以了。
⑶ 貪心演算法的介紹
貪心演算法(又稱貪婪演算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,他所做出的是在某種意義上的局部最優解。貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。
⑷ 五大常用演算法之一:貪心演算法
所謂貪心選擇性質是指所求問題的整體最優解可以通過一系列局部最優的選擇,換句話說,當考慮做何種選擇的時候,我們只考慮對當前問題最佳的選擇而不考慮子問題的結果。這是貪心演算法可行的第一個基本要素。貪心演算法以迭代的方式作出相繼的貪心選擇,每作一次貪心選擇就將所求問題簡化為規模更小的子問題。 對於一個具體問題,要確定它是否具有貪心選擇性質,必須證明每一步所作的貪心選擇最終導致問題的整體最優解。
當一個問題的最優解包含其子問題的最優解時,稱此問題具有最優子結構性質。問題的最優子結構性質是該問題可用貪心演算法求解的關鍵特徵。
值得注意的是,貪心演算法並不是完全不可以使用,貪心策略一旦經過證明成立後,它就是一種高效的演算法。比如, 求最小生成樹的Prim演算法和Kruskal演算法都是漂亮的貪心演算法 。
貪心演算法還是很常見的演算法之一,這是由於它簡單易行,構造貪心策略不是很困難。
可惜的是,它需要證明後才能真正運用到題目的演算法中。
一般來說,貪心演算法的證明圍繞著:整個問題的最優解一定由在貪心策略中存在的子問題的最優解得來的。
對於例題中的3種貪心策略,都是無法成立(無法被證明)的,解釋如下:
貪心策略:選取價值最大者。反例:
W=30
物品:A B C
重量:28 12 12
價值:30 20 20
根據策略,首先選取物品A,接下來就無法再選取了,可是,選取B、C則更好。
(2)貪心策略:選取重量最小。它的反例與第一種策略的反例差不多。
(3)貪心策略:選取單位重量價值最大的物品。反例:
W=30
物品:A B C
重量:28 20 10
價值:28 20 10
根據策略,三種物品單位重量價值一樣,程序無法依據現有策略作出判斷,如果選擇A,則答案錯誤。但是果在條件中加一句當遇見單位價值相同的時候,優先裝重量小的,這樣的問題就可以解決.
所以需要說明的是,貪心演算法可以與隨機化演算法一起使用,具體的例子就不再多舉了。(因為這一類演算法普及性不高,而且技術含量是非常高的,需要通過一些反例確定隨機的對象是什麼,隨機程度如何,但也是不能保證完全正確,只能是極大的幾率正確)。
⑸ 貪心思想
在學習數據結構的時候,我們已經見過了貪心思想在Prim和Kruskal中的完美應用,貪心思想因為其的簡潔在演算法中經常會被用到,有的時候在生活中,我們也會無意中使用到l貪心演算法。比如在去shopping時,經常需要進行找零錢的過程,我們總是不自覺的先把大的找出來。
那麼什麼是貪心思想?
貪心演算法總是作出在當前看來最好的選擇,也就是說貪心演算法並不從整體最優考慮,它所作出的選擇只是在某種意義上的局部最優選擇。
只有在滿足最優子結構的情況下貪心演算法得到的結果才是最優結果。
比如找錢的問題,我要給你一百,那麼我盡可能每一次給你最多的。
或者比如磁碟的最優存儲問題,所謂貪心選擇性質是指所求問題的整體最優解可以通過一系列局部最優的選擇,即貪心選擇來達到。
Prim和kruskal演算法都是每次選擇最小的邊納入生成樹。
所謂貪心選擇性質是指所求問題的整體最優解可以通過一系列局部最優的選擇,即貪心選擇來達到。這也是貪心問題和動態規劃問題的主要區別。
在n行m列的正整數矩陣中,要求從每一行中選一個數,使得選出的n個數的和最大。
可運用貪心策略,選n次,每一次選相應行中的最大值即可。
但是,在一個n*m的方格陣中,每一格子賦予一個數,規定每次移動時只能向上或向右,現試找出一條路徑,使其從左下角至右上角所經過的權值之和最大。
同樣考慮貪心策略,從左下角向右上角移動,每次移動選擇權值較大的一個方向。
以2*3矩陣為例,採用貪心的策略得到的是1,3,4,6和為14但是實際的最優結果為1,2,100,6和為109.
所以說貪心演算法並不是總是可行,證明當前問題存在貪心選擇性質(全局最優解可以通過局部最優貪心選擇達到)和最優子結構性質(問題的最優解包含了其子問題的最優解)。所以貪心問題如果當前的選擇不會干擾之後的選擇,則不會出現問題。
其他的情況就需要進行證明,證明的最好辦法就是將最小子問題進行一步步的合並,直到最後還原為最後的原問題,若所得到的解是總體最優的則可以使用貪心思想,否則不可以。
比如上面的問題,我們的走一步的最優解為1,3,然後我們判斷一次走兩步的最優解是否任然為1,3這個路徑,答案顯然不是,變為 1,2,100這個路徑,所以顯然不能使用貪心思想。
假設1元、2元、5元、10元、20元、50元、100元的紙幣分別有c0, c1, c2, c3, c4, c5, c6張。現在要用這些錢來支付K元,至少要用多少張紙幣?用貪心演算法的思想,很顯然,每一步盡可能用面值大的紙幣即可。在日常生活中我們自然而然也是這么做的。
有n個需要在同一天使用同一個教室的活動a1,a2,…,an,教室同一時刻只能由一個活動使用。每個活動ai都有一個開始時間si和結束時間fi 。一旦被選擇後,活動ai就占據半開時間區間[si,fi)。如果[si,fi]和[sj,fj]互不重疊,ai和aj兩個活動就可以被安排在這一天。該問題就是要安排這些活動使得盡量多的活動能不沖突的舉行。
部分背包問題, 有n個物體,第i個物體重量為wi,價值為vi,在總重量不超過C的情況下,讓總價值盡可能的高。每個物體都可以只取一部分。
我們可以考慮重量和價值的比值作為單價。