1. 程式人生 > >動態規劃和貪心演算法的區別

動態規劃和貪心演算法的區別

不同點:
貪心演算法:
1.貪心演算法中,作出的每步貪心決策都無法改變,因為貪心策略是由上一步的最優解推導下一步的最優解,而上一部之前的最優解則不作保留。
2.由(1)中的介紹,可以知道貪心法正確的條件是:每一步的最優解一定包含上一步的最優解。

動態規劃演算法:
1.全域性最優解中一定包含某個區域性最優解,但不一定包含前一個區域性最優解,因此需要記錄之前的所有最優解
2.動態規劃的關鍵是狀態轉移方程,即如何由以求出的區域性最優解來推導全域性最優解
3.邊界條件:即最簡單的,可以直接得出的區域性最優解

貪心演算法與動態規劃
貪心法的基本思路:

從問題的某一個初始解出發逐步逼近給定的目標,以儘可能快的地求得更好的解。當達到某演算法中的某一步不能再繼續前進時,演算法停止。
該演算法存在問題:
1. 不能保證求得的最後解是最佳的;
2. 不能用來求最大或最小解問題;
3. 只能求滿足某些約束條件的可行解的範圍。實現該演算法的過程:
從問題的某一初始解出發;

while 能朝給定總目標前進一步 do
求出可行解的一個解元素;
由所有解元素組合成問題的一個可行解

貪心演算法最經典的例子,給錢問題。
比如中國的貨幣,只看元,有1元2元5元10元20、50、100

如果我要16元,可以拿16個1元,8個2元,但是怎麼最少呢?
如果用貪心算,就是我每一次拿那張可能拿的最大的。
比如16,我第一次拿20拿不起,拿10元,OK,剩下6元,再拿個5元,剩下1元
也就是3張 10、5、1。

每次拿能拿的最大的,就是貪心。

但是一定注意,貪心得到的並不是最優解,也就是說用貪心不一定是拿的最少的張數
貪心只能得到一個比較好的解,而且貪心演算法很好想得到。
再注意,為什麼我們的錢可以用貪心呢?因為我們國家的錢的大小設計,正好可以使得貪心演算法算出來的是最優解(一般是個國家的錢幣都應該這麼設計)。如果設計成別的樣子情況就不同了
比如某國的錢幣分為 1元3元4元
如果要拿6元錢 怎麼拿?貪心的話 先拿4 再拿兩個1 一共3張錢
實際最優呢? 兩張3元就夠了

求最優解的問題,從根本上說是一種對解空間的遍歷。最直接的暴力分析容易得到,最優解的解空間通常都是以指數階增長,因此暴力窮舉都是不可行的。
最優解問題大部分都可以拆分成一個個的子問題,把解空間的遍歷視作對子問題樹的遍歷,則以某種形式對樹整個的遍歷一遍就可以求出最優解,如上面的分析,這是不可行的。
貪心和動態規劃本質上是對子問題樹的一種修剪。兩種演算法要求問題都具有的一個性質就是“子問題最優性”。即,組成最優解的每一個子問題的解,對於這個子問題本身肯定也是最優的。如果以自頂向下的方向看問題樹(原問題作根),則,我們每次只需要向下遍歷代表最優解的子樹就可以保證會得到整體的最優解。形象一點說,可以簡單的用一個值(最優值)代表整個子樹,而不用去求出這個子樹所可能代表的所有值。
動態規劃方法代表了這一類問題的一般解法。我們自底向上(從葉子向根)構造子問題的解,對每一個子樹的根,求出下面每一個葉子的值,並且以其中的最優值作為自身的值,其它的值捨棄。動態規劃的代價就取決於可選擇的數目(樹的叉數)和子問題的的數目(樹的節點數,或者是樹的高度?)。
貪心演算法是動態規劃方法的一個特例。貪心特在,可以證明,每一個子樹的根的值不取決於下面葉子的值,而只取決於當前問題的狀況。換句話說,不需要知道一個節點所有子樹的情況,就可以求出這個節點的值。通常這個值都是對於當前的問題情況下,顯而易見的“最優”情況。因此用“貪心”來描述這個演算法的本質。由於貪心演算法的這個特性,它對解空間樹的遍歷不需要自底向上,而只需要自根開始,選擇最優的路,一直走到底就可以了。這樣,與動態規劃相比,它的代價只取決於子問題的數目,而選擇數目總為1。