1. 程式人生 > >算法設計與分析

算法設計與分析

如何 頻率 -a 劃算 序列 做出 開始 構造 ras

  • 開始跟著雲課堂學習《算法設計與分析》入門篇和進階篇,開始系統的學習一下
  1. P問題,非P類問題,NP問題,NPC問題

    • P問題:如果一個問題可以找到一個能在多項式的時間(n在底數上面)裏解決的算法,那麽這個問題就是P問題。

    • NP問題:可以在多項式時間裏驗證一個解的問題。NP問題的另一個定義是,可以在多項式時間裏猜出一個解的問題。

    • NPC問題(NP-完全問題):

      存在這樣一個NP問題,所有的NP問題都可以規約化為它,換句話說,只要解決了這個問題,那麽所有的NP問題就都可以得到解決了。
      1. 他是一個NP問題
      2. 所有的NP問題都可以規約化得到它。
    • NP難問題,只滿足NPC的第二個特征,而不滿足第一個特征.

    P問題是一個NP問題,但是一個NP問題不一定是一個P問題。因為有NPC問題的存在,是的人們確信P問題 和NP問題不是相等的

    規約:一個問題A可以規約為問題B的含義是,可以用問題B的解法解決問題A。問題B的時間復雜度高於問題A的時間復雜度。

    我們所說的可約化問題指的是在多項時間內,找到一個變化法則,對於人一個程序A的輸入,都都能按照程序B的輸入,使兩個程序的輸出相同,那麽我們說問題A可以約化為問題B。

    總之,P屬於NP,NP屬於NPC。

    • NPC問題的例子有:
      • 邏輯電路問題:給定一個邏輯電路,問是否存在一種輸入使輸出為True.
      • 哈密頓回路問題:
      • 旅行商問題

分治法

  1. 思想

    1.  將一個規模為n的問題分解為k個規模較小的子問題,這些子問題互相獨立且與原問題相同。遞歸地解這些子問題,然後將各子問題的解合並得到原問題的解。
    
    2.  divide-and-conquer(P)
    {
        if(|P| <= n0)adhoc(P);
        divide P into samller subinstances P1,P2...,Pk;
        for(int i = 1;i < k;i++)
        {
            yi = divide-and-conquer(Pi);
        }
        
    return merge(y1,y2...,yn); } 3.如何劃分子問題 - 集合論,找到一個原來集合問題的一個劃分,子問題之間不相交,同時子問題的規模類型相同 - 最優子結構(子問題類型相同) - 最好使子問題的規模大致相同,即將一個問題的大小分成相等規模的k個子問題的處理方法是行之有效的。。
  2. 例子

    1.  fibonacci 數列        
    2.  排列問題
    3.  整數劃分問題
    4.  Hanoi 塔問題
    5.  二分搜索
    6.  大整數乘法
    7.  Strassen 矩陣乘法
    8.  合並排序
    9.  快速排序
  3. 復雜度分析

    主定理:T(n) = aT(n/b)+f(n),a>=1,b>1,f(n)是給定的多項式函數,刻畫了一個分值算法,生成a個子問題,每個問題的規模是原來的1/b,分解合並步驟共消耗f(n). T(n)的復雜度的分析如下:
    1.  若f(n)<n^(log(a/b)) 則T(n) = n^(log(a/b))
    2.  若f(n)=n^(log(a/b)) 則T(n) = n^(log(a/b))logn
    3.  若f(n)>n^(log(a/b)) 則T(n) = f(n)

動態規劃

  1. 思想

    用一個表來記錄所有以解決問題子問題的答案,不管該子問題以後是否會用到,只要它被計算過,就將其結果存入到表中,這就是動態規劃法的基本思想。
    基本要素:
    1. 最優子結構:當一個問題的最優解包含了其子問題的最優解時,稱該問題具有最優子結構性質。
    2. 重疊子問題: 在使用遞歸算法的時候有很多子問題是重疊的,那麽我們使用一個表將已經求解過的子問題的結果保存下來
    備忘錄方法
    1. 與動態規劃一樣:備忘錄方法也是使用一張表來保存子問題的答案,下次需要解此子問題的時候,我們只需要簡單查看該子問題的答案即可,而不是重新計
    算。
    2. 與動態規劃不同:備忘錄方法的遞歸方式是自頂向下的,而動態規劃是自底向上的。 備忘錄方法與直接控制的遞歸結構是相同的,但是他不用重復求解相同子問題。
    3. 當一個問題的所有子問題都要至少解一次時,使用動態規劃算法比備忘錄方法好。 當子問題空間中部分子問題不必求解時,用備忘錄方法則較為有利,備忘錄方法只用來求解那些需要求解的子問題。
  2. 基本步驟
    1. 找出最優解的性質,並刻畫其結構特征
    2. 遞歸地定義最優值
    3. 以自底向上的方式計算出最優值
    4. 根據計算最優值時得到的信息,構造最優解
  3. 例子
    矩陣連乘
    最長公共子序列
    0-1背包問題

貪心算法

  1. 思想

    貪心算法總是做出當前看來最好的選擇,也就是說貪心算法並不從整體最優考慮,它做出的選擇只是在某種意義上的局部最優選擇。
    貪心選擇的基本要素:
    1.  貪心選擇性質: 所求問題的整體最優解可以通過一系列局部最優的選擇,即貪心選擇來達到。
    2.  最優子結構: 一個問題的最優解包含其子問題的最優解時,此問題具有最優子結構性質
  2. 貪心算法VS動態規劃

    1.  貪心算法擁有貪心選擇性質,動態化算法沒有。動態規劃算法中,每步所作出的選擇往往依賴於相關子問題的解。因而只有在解出相關子問題後,才能作出選擇; 而貪心算法中,僅在當前狀態下作出最好選擇,即局部最優選擇。然後去解作出這個選擇後產生相應的子問題。 貪心選擇依賴於過往所做選擇,但是不以利於將來將要作出的選擇,也不依賴於子問題的解。
    2. 動態規劃算法通常以自底向上的方式解各子問題,貪心算法則是自頂向下方式叠代進行貪心選擇,每一次貪心選擇將所求問題簡化為規模更小的子問題
  3. 例子

    1. 活動安排問題 (最早截止時間優先)
    2. 背包問題 (權重空間比值最大者優先)
    3. 哈夫曼編碼 (頻率大者優先)
    4. 單源最短路徑 (局部最短路徑優先)
    5. 最小生成樹
        -prim (與源集合相連的權值最小邊優先)
        -kruskal-(集合中邊權值最小優先)
    6.  多級調度問題(長作業優先)

回溯法

算法設計與分析