Ⅰ 動態規劃和貪心演算法的區別
動態規劃和貪心演算法的區別
1、動態規劃演算法中,每步所做的選擇往往依賴於相關子問題的解,因而只有在解出相關子問題時才能做出選擇。而貪心演算法,僅在當前狀態下做出最好選擇,即局部最優選擇,然後再去解做出這個選擇後產生的相應的子問題。
2、動態規劃演算法通常以自底向上的方式解各子問題,而貪心演算法則通常自頂向下的方式進行。
Ⅱ 關於編程的貪心法
定義
所謂貪心演算法(又稱貪婪演算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,他所做出的僅是在某種意義上的局部最優解。 貪心演算法不是對所有問題都能得到整體最優解,但對范圍相當廣泛的許多問題他能產生整體最優解或者是整體最優解的近似解。
[編輯本段]貪心演算法的基本思路
1.建立數學模型來描述問題。 2.把求解的問題分成若干個子問題。 3.對每一子問題求解,得到子問題的局部最優解。 4.把子問題的解局部最優解合成原來解問題的一個解。 實現該演算法的過程: 從問題的某一初始解出發; while 能朝給定總目標前進一步 do 求出可行解的一個解元素; 由所有解元素組合成問題的一個可行解。 下面是一個可以試用貪心演算法解的題目,貪心解的確不錯,可惜不是最優解。
[編輯本段]例題分析
[背包問題]有一個背包,背包容量是M=150。有7個物品,物品不可以分割成任意大小。 要求盡可能讓裝入背包中的物品總價值最大,但不能超過總容量。 物品 A B C D E F G 重量 35 30 60 50 40 10 25 價值 10 40 30 50 35 40 30 分析: 目標函數: ∑pi最大 約束條件是裝入的物品總重量不超過背包容量:∑wi<=M( M=150) (1)根據貪心的策略,每次挑選價值最大的物品裝入背包,得到的結果是否最優? (2)每次挑選所佔重量最小的物品裝入是否能得到最優解? (3)每次選取單位重量價值最大的物品,成為解本題的策略。 值得注意的是,貪心演算法並不是完全不可以使用,貪心策略一旦經過證明成立後,它就是一種高效的演算法。 貪心演算法還是很常見的演算法之一,這是由於它簡單易行,構造貪心策略不是很困難。 可惜的是,它需要證明後才能真正運用到題目的演算法中。 一般來說,貪心演算法的證明圍繞著:整個問題的最優解一定由在貪心策略中存在的子問題的最優解得來的。 對於例題中的3種貪心策略,都是無法成立(無法被證明)的,解釋如下: (1)貪心策略:選取價值最大者。 反例: 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,則答案錯誤。 【注意:如果物品可以分割為任意大小,那麼策略3可得最優解】 對於選取單位重量價值最大的物品這個策略,可以再加一條優化的規則:對於單位重量價值一樣的,則優先選擇重量小的!這樣,上面的反例就解決了。 但是,如果題目是如下所示,這個策略就也不行了。 W=40 物品:A B C 重量:28 20 15 價值:28 20 15 附:本題是個NP問題,用貪心法並不一定可以求得最優解,以後了解了動態規劃演算法後本題就有了新的解法。
[編輯本段]備注
貪心演算法當然也有正確的時候。求最小生成樹的Prim演算法和Kruskal演算法都是漂亮的貪心演算法。 所以需要說明的是,貪心演算法可以與隨機化演算法一起使用,具體的例子就不再多舉了。(因為這一類演算法普及性不高,而且技術含量是非常高的,需要通過一些反例確定隨機的對象是什麼,隨機程度如何,但也是不能保證完全正確,只能是極大的幾率正確)
[編輯本段]附貪心演算法成功案例之一
馬踏棋盤的貪心演算法 123041-23 XX 【問題描述】 馬的遍歷問題。在8×8方格的棋盤上,從任意指定方格出發,為馬尋找一條走遍棋盤每一格並且只經過一次的一條最短路徑。 【初步設計】 首先這是一個搜索問題,運用深度優先搜索進行求解。演算法如下: 1、 輸入初始位置坐標x,y; 2、 步驟 c: 如果c> 64輸出一個解,返回上一步驟c-- (x,y) ← c 計算(x,y)的八個方位的子結點,選出那此可行的子結點 循環遍歷所有可行子結點,步驟c++重復2 顯然(2)是一個遞歸調用的過程,大致如下: void dfs(int x,int y,int count) { int i,tx,ty; if(count> N*N) { output_solution();//輸入一個解 return; }
Ⅲ 簡述貪心,遞歸,動態規劃,及分治演算法之間的區別和聯系
聯系:都是問題求解之時的一種演算法。
區別:
一、作用不同
1、貪心演算法:把子問題的解局部最優解合成原來解問題的一個解。
2、遞歸演算法:問題解法按遞歸演算法實現。如Hanoi問題;數據的結構形式是按遞歸定義的。如二叉樹、廣義表等。
3、動態規劃:動態規劃演算法通常用於求解具有某種最優性質的問題。
4、分治演算法:可以再把它們分成幾個更小的子問題,以此類推,直至可以直接求出解為止。
二、方法不同
1、貪心演算法:在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,演算法得到的是在某種意義上的局部最優解。
2、遞歸演算法:通過重復將問題分解為同類的子問題而解決問題。
3、動態規劃:將過程分成若干個互相聯系的階段,在它的每一階段都需要作出決策,從而使整個過程達到最好的活動效果。
4、分治演算法:將一個規模為N的問題分解為K個規模較小的子問題。
三、特點不同
1、貪心演算法:根據題意選取一種量度標准。
2、遞歸演算法:遞歸就是在過程或函數里調用自身。
3、動態規劃:雖然動態規劃主要用於求解以時間劃分階段的動態過程的優化問題,但是一些與時間無關的靜態規劃(如線性規劃、非線性規劃),只要人為地引進時間因素,把它視為多階段決策過程,也可以用動態規劃方法方便地求解。
4、分治演算法:原問題可以分解為多個子問題;原問題在分解過程中,遞歸地求解子問題;在求解並得到各個子問題的解後。
Ⅳ 數據結構之貪心演算法
貪婪演算法(Greedy)的定義:是一種在每一步選中都採取在當前狀態下最好或最優的選擇,從而希望導致結果是全局最好或最優的演算法。
貪婪演算法:當下做局部最優判斷,不能回退
(能回退的是回溯,最優+回退是動態規劃)
由於貪心演算法的高效性以及所求得答案比較接近最優結果,貪心演算法可以作為輔助演算法或解決一些要求
結果不特別精確的問題
注意:當下是最優的,並不一定全局是最優的。舉例如下:
有硬幣分值為10、9、4若干枚,問如果組成分值18,最少需要多少枚硬幣?
採用貪心演算法,選擇當下硬幣分值最大的:10
18-10=8
8/4=2
即:1個10、2個4,共需要3枚硬幣
實際上我們知道,選擇分值為9的硬幣,2枚就夠了
18/9=2
如果改成:
背包問題是演算法的經典問題,分為部分背包和0-1背包,主要區別如下:
部分背包:某件物品是一堆,可以帶走其一部分
0-1背包:對於某件物品,要麼被帶走(選擇了它),要麼不被帶走(沒有選擇它),不存在只帶走一部分的情況。
部分背包問題可以用貪心演算法求解,且能夠得到最優解。
假設一共有N件物品,第 i 件物品的價值為 Vi ,重量為Wi,一個小偷有一個最多隻能裝下重量為W的背包,他希望帶走的物品越有價值越好,可以帶走某件物品的一部分,請問:他應該選擇哪些物品?
假設背包可容納50Kg的重量,物品信息如下表:
將物品按單位重量 所具有的價值排序。總是優先選擇單位重量下價值最大的物品
按照我們的貪心策略,單位重量的價值排序: 物品A > 物品B > 物品C
因此,我們盡可能地多拿物品A,直到將物品1拿完之後,才去拿物品B,然後是物品C 可以只拿一部分.....
在不考慮排序的前提下,貪心演算法只需要一次循環,所以時間復雜度是O(n)
優點:性能高,能用貪心演算法解決的往往是最優解
缺點:在實際情況下能用的不多,用貪心演算法解的往往不是最好的
針對一組數據,我們定義了限制值和期望值,希望從中選出幾個數據,在滿足限制值的情況下,期望值最大。
每次選擇當前情況下,在對限制值同等貢獻量的情況下,對期望值貢獻最大的數據(局部最優而全局最優)
大部分能用貪心演算法解決的問題,貪心演算法的正確性都是顯而易見的,也不需要嚴格的數學推導證明
在實際情況下,用貪心演算法解決問題的思路,並不總能給出最優解