1. 程式人生 > >遞迴、分治策略、動態規劃以及貪心演算法之間的關係

遞迴、分治策略、動態規劃以及貪心演算法之間的關係

引言

最近集中研究計算智慧,其中涉及到遞迴和動態規劃,動態規劃實現中又用到了遞迴,忽然發現這兩個概念的差別分得不太清楚。索性把遞迴、分治策略、動態規劃、貪婪選擇之間的聯絡與區別都一併搞清楚吧。

1、分治策略(Divide and Conquer)

將原問題分解為若干個規模較小但類似於原問題的子問題(Divide),遞迴的求解這些子問題(Conquer),然後再合併這些子問題的解來建立原問題的解。因為在求解大問題時,需要遞迴的求小問題,因此一般用遞迴的方法實現,即自頂向下。

2、動態規劃(Dynamic Programming)

動態規劃其實和分治策略是類似的,也是將一個原問題分解為若干個規模較小的子問題,遞迴的求解這些子問題,然後合併子問題的解得到原問題的解。區別在於這些子問題會有重疊,一個子問題在求解後,可能會再次求解,於是我們想到將這些子問題的解儲存起來,當下次再次求解這個子問題時,直接拿過來就是。其實就是說,動態規劃所解決的問題是分治策略所解決問題的一個子集,只是這個子集更適合用動態規劃來解決從而得到更小的執行時間。

即用動態規劃能解決的問題分治策略肯定能解決,只是執行時間長了。因此,分治策略一般用來解決子問題相互對立的問題,稱為標準分治,而動態規劃用來解決子問題重疊的問題

動態規劃一般由兩種方法來實現,一種為自頂向下的備忘錄方式,用遞迴實現,一種為自底向上的方式,用迭代實現。

3、貪心演算法(Greedy Algorithm)

貪心演算法在每一步都做出最優的選擇,希望這樣的選擇能導致全域性最優解。對,只是寄希望,因此貪心演算法並不保證得到最優解,但是它對很多問題確實可以得到最優解,而且執行時間更短。由此可見,貪心演算法是帶有啟發性質的演算法。那什麼時候可以用貪心演算法呢?當該問題具有貪心選擇性質的時候,我們就可以用貪心演算法來解決該問題。
貪心選擇性質:我們可以通過做出區域性最優(貪心)來構造全域性最優。

只要我們能夠證明該問題具有貪心選擇性質,就可以用貪心演算法對其求解。比如對於0-1揹包問題,我們用貪心演算法可能得不到最優解(當然,也可能會得到最優解),但對於部分揹包問題,則可以得到最優解,貪心演算法可以作為0-1揹包問題的一個近似演算法。

動態規劃與遞迴的比較

就效能而言,我用遞迴和動態規劃實現了斐波納契數列計算,遞迴如果超過40的時候就已經需要很長時間了,40次大概需要1秒左右,但是用動態規劃要一億次,才需要4秒,這個相差的可不是幾個數量級的問題。事實上,遞迴實現的斐波那契數列計算時間複雜度為O(2ⁿ),動態規劃實現時間複雜度為O(n)所以,在以後的開發中,儘量避免使用遞迴。
就具體實現上而言,動態規劃比普通遞迴僅僅是多了一步儲存子問題計算結果的操作。
例如,斐波那契數列的遞迴實現如下:

 int F(int i)
    {
             if(i < 1)  return 0;
             if(i == 1) return 1;
              return F(i-1) + F(i - 2);
    }

而用動態規劃演算法實現是這樣:

 int F(int i)
{
     if(knownF[i] != unknown){
        return knownF[i];
     }
     if(i == 0) t = 0;
     if(i == 1) t = 1;
     if(i > 1)  t = F(i - 1) + F(i - 2);
     return knownF[i] = t;
}

4、總結

  1. 分治策略用於解決原問題與子問題結構相似的問題,對於各子問題相互獨立的情況,一般用遞迴實現;
  2. 動態規劃用於解決子問題有重複求解的情況,既可以用遞迴實現,也可以用迭代實現;
  3. 貪心演算法用於解決具有貪心選擇性質的一類問題,既可以用遞迴實現,也可以用迭代實現,因為很多遞迴貪心演算法都是尾遞迴,很容易改成迭代貪心演算法;
  4. 遞迴是實現手段,分治策略是解決問題的思想,動態規劃很多時候會使用記錄子問題運算結果的遞迴實現。

相關推薦

分治策略動態規劃以及貪心演算法之間關係

引言 最近集中研究計算智慧,其中涉及到遞迴和動態規劃,動態規劃實現中又用到了遞迴,忽然發現這兩個概念的差別分得不太清楚。索性把遞迴、分治策略、動態規劃、貪婪選擇之間的聯絡與區別都一併搞清楚吧。 1、分治策略(Divide and Conquer)

分治策略——找峰頂問題

問題 給定含有n個不同元素的陣列L=<x1,x2,…,xn>,如果L中存在xi,使得x1<x2<…<xi-1xi+1>…>xn ,則稱L是單峰序列,並稱xi是L的峰頂。假設L是單峰的,設計一個演算法找到L的峰頂,並從理論上分析演算法的

計算機演算法設計與分析之分治策略——二分搜尋技術

遞迴與分治策略 二分搜尋技術   我們所熟知的二分搜尋演算法是運用分治策略的典型例子,針對這個演算法,先給出一個簡單的案例。   目的:給定已排好序的n個元素a[0:n-1],現要在這n個元素中找出一特定的元素x。   我們首先想到的最簡單的是用順序搜尋方法,逐個比較a[0:n-1]中元素,直至找出元

第2章 分治策略,二分搜尋技術(查詢不成功時,返回區間位置)

當要查詢的數x不在有序陣列a中時,返回第一個大於x的數的位置或第一個小於x的數的位置 lowend,midend,highend表示查詢結束時各遊標的值,low,mid,high表示使查詢結束的最後一次操作時,各遊標的值。 查詢結束的條件是lowend>highe

從一個小例子來初步認識,迭代,動態規劃

問題:有n步臺階,一次只能上1步或者2步,共有多少種走法? 思路: a 遞迴 步驟1:找到走完前n步臺階和前n-1步臺階之間的關係。 為了走上n步臺階,只有兩種方法:從n-1步臺階爬1步走到或從n-2步臺階處爬兩步走到。如果f(n)是爬到第n臺階的方法數,則f(n) = f

演算法設計與分析筆記之(2):分治策略

宣告 1)本文僅供學術交流,非商用。具體引用的資料請看參考文獻。如果某部分不小心侵犯了大家的利益,請聯絡博主刪除。 2)本人才疏學淺,整理總結的時候難免出錯,還望各位前輩不吝指正,謝謝。 聯

萬惡的期末考試---演算法複習---分治策略(二分搜尋與大數乘法與矩陣對角線相加,strassen矩陣乘法,棋盤覆蓋)

已經考過三科了,還有三科,明天下午就要考演算法了,心慌慌,抓緊寫個部落格做演算法複習,靜靜心 呃呃呃  說好的只是複習下,自己拓展到了天外 ,第二章還沒結束....程式碼如下 大數乘法過程如下: 二分搜尋與大數乘法與矩陣對角線相加 package chap2_dgfz

演算法設計與分析之分治策略

 分治法:     將一個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。 (1)可行性:如果原問題可分割成k個子問題(1<k<=n),且這些子問題都可解,並可利用這些子問題的解求出原問題的解,那麼分治法就是可行的。 (2)分治法與

Java語言描述:分治策略之合併排序與快速排序

合併排序: package DivideAndConquer; public class MergeSort { //一定要多傳入一個多餘的temp陣列用於存放排序的中間結果 public static<AnyType extends Comparable&l

計算機演算法設計與分析——分治策略(一)

遞迴: 直接或者間接地呼叫自身的演算法稱為遞迴。用函式自身給出定義的函式成為遞迴函式。 使用遞迴技術往往使函式的定義和演算法的描述簡潔且易於理解。有些資料結構,如二叉樹等,由於其本身固有的遞迴特性,特別適合用遞迴的形式來描述。另外,還有一些問題,雖然其本身沒

第二章 分治策略(排列的字典序問題)

一. 遞迴 1.概念 直接或間接地呼叫自身的演算法。用函式自身給出定義的函式稱為遞迴函式。 2.說明 (1)每個遞迴函式都必須有非遞迴定義的初始值,否則,遞迴函式就無法計算。 (2)遞迴式的主

分治策略-2.11迴圈賽日程表

設有n=2^k個運動員要進行網球迴圈賽,現要設計一個滿足以下要求的比賽日程表: (1)每個選手必須與其他n-1個選手各賽一次; (2)每個選手一天只能賽一次; (3)迴圈賽一共進行n-1天。 按

五大常見演算法策略之——分治策略

遞迴與分治策略 遞迴與分治策略是五大常見演算法策略之一,分治策略的思想就是分而治之,即先將一個規模較大的大問題分解成若干個規模較小的小問題,再對這些小問題進行解決,得到的解,在將其組合起來得到最終的解。而分治與遞迴很多情況下都是一起結合使用的,能發揮出奇效(1+1>2),這篇文章我們將先從遞迴說起,再逐

面試題14:剪繩子(動態規劃貪心演算法

一、題目: 一根長度為n的繩子,剪成m段,m,n都大於1,且都為整數,每段長度記為k[0],k[1]…,k[m].求k[0]*k[1]…*k[m]可能的最大乘積 1.1解法: 兩種不同的方法解決這個問題,先用常規的需要O(n²)時間和O(n)空間的動態規劃,接著用只需要O(1)的

動態規劃貪心演算法

貪心演算法: 典型的應用有Huffman樹,直接構造兩個最小的連續相加,得到目標樹。 目標函式f=sum(li*wi);就是權重乘以葉節點的深度求和再求最小值。 如果目標函式修改為f=sum(li+wi)或max(li+wi)或任意函式g(li,wi),是否可以求解呢?

動態規劃貪心演算法之揹包問題理解

一.揹包問題 引用書上關於0-1揹包和部分揹包的闡述: 二.貪心與動態規劃區別 關於紅色矩形部分解釋為什麼0-1不能使用貪心演算法,是因為當你選擇一個物品時,整個物品的大小都需要計算,然而揹包的的大小又是固定的,那麼剩下的揹包大小與剩下的物品之間

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

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

動態規劃or貪心演算法--剪繩子/切割杆

需求一: 剪繩子,將長度為n的繩子剪成若干段,求各段長度乘積的最大值分析: 1、動態規劃    設f(n)代表長度為n的繩子剪成若干段的最大乘積,如果第一刀下去,第一段長度是i,那麼剩下的就需要剪n-i,那麼f(n)=max{f(i)f(n-i)}。而f(n)的最優解對應著f

分治法,動態規劃貪心演算法區別

轉自:http://hxrs.iteye.com/blog/1055478 分治法,動態規劃法,貪心演算法這三者之間有類似之處,比如都需要將問題劃分為一個個子問題,然後通過解決這些子問題來解決最終問題。但其實這三者之間的區別還是蠻大的。 1.分治法     分治法(di

從最短路徑談動態規劃貪心演算法

一言以蔽之:動態規劃,從全域性最優考慮;最短路徑,從當前最優考慮。 先考慮下面的圖 可以很容易地看出,如果使用貪心演算法,從a到e的路線將是:a->b->c->d->e,而採用動態的規劃的路線則是:a->c->e。 貪心演算法的優點是程