對於算法一些概念的小總結

        本學期上了算法設計與分析這門課程,簡單的對其中的一些概念進行一下總結。基本都是我的一些宏觀上的理解。

        時間複雜度,空間複雜度是算法重要的衡量標準。有很多算法問題都是多項式時間無法解決的。在算法面試中,如果你寫出了O(n^2)的算法,基本都是可以進行優化的。一般認爲,一個算法的空間複雜度不會超過其時間複雜度。我個人的理解是:如果產生這麼多的空間複雜度,那麼時間最少也是與空間複雜度相同的,比如讀入一個A[n][n]的數組,讀取它也必須得O(n^2)的時間。我們首先可以討論一下算法和程序的區別,很久之前就看到程序是這樣定義的:程序=算法+數據結構。對於算法來說,它是解決一個問題的方法和過程,一個輸入對應其一個輸出。算法是給人看到。程序則是利用特定的計算機語言,來描述一個算法,是給機器看的。
     

    理解漸進表達式

     一般採用漸進表達式來衡量算法的時間複雜度和空間複雜度,忽略了常數。首先要理解,指數增長是極其恐怖的,在算法運行時間中應當儘量避免。很多算法都可以用指數時間的窮舉算法來實現,但是否存在多項式時間算法是計算機科學的核心問題。

   在下面的討論中,對所有n,f(n) >=  0,g(n) >= 0。

  (1)漸近上界記號大O

        O(g(n)) = { f(n) | 存在正常數c和n0使得對所有n>=n0有:0 <= f(n) <= cg(n) }

 (2)漸近下界記號 Ω

       Ω(g(n)) = { f(n) | 存在正常數c和n0使得對所有n>=n0有:0 <= cg(n) <= f(n) }

(3)緊漸近界記號Θ

       Θ(g(n)) = { f(n) | 存在正常數c1,c2n0使得對所有n>=n0有:c1g(n) <= f(n)  <= c2g(n) }

例如:  f(n)= 32n2+ 17n + 32.

               f(n)屬於O(n2),O(n3),Ω(n2),Ω(n),and Θ(n2).

               f(n)不屬於 O(n),Ω(n3),Θ(n),or Θ(n3).

    對於非漸進記號,用小寫符號表示,式子的<=, >= 變爲< >。

    理解遞歸表達式的求解

      遞歸是我們算法中非常重要的一個概念與方法。在很多算法中,比如:分治,對於子問題的求解一般用遞歸來求解。要會求解遞歸表達式,從而得到算法的時間複雜度。

對於遞歸表達式的求解,有遞歸樹求解方法,但是最簡單的方法是利用主方法進行求解。
     例如歸併排序:將一個有n規模的問題分成n/2。得到遞歸表達式:T(n)= 2T(n/2) +Θ(n)

    先介紹一個主方法:

      T(n)= aT(n/b) + f(n),分三種情況:


     則,歸併排序的時間複雜度利用主方法進行求解,符合case2。則其時間複雜度爲:O(nlgn)。注意:在算法中:lg=log2(以2爲底)。

    貪心算法(Greedy)/分治算法(Divide-and-conquer)/動態規劃(Dynamic Programming)

      貪心/分治/DP是常用的算法。下邊我簡單的說一下對於這三種算法的簡單理解:

     貪心算法:

       顧名思義,就是選擇當前最好的選擇。其關鍵是貪心的策略的選擇。比如任務調度問題,
        此問題是求在規定的時間內,可最多安排的任務數。可利用貪心算法來求解,按照任務的完成時間進行排序,貪心策略就是按照任務的完成時間從小到大進行安排,同時要保證任務不衝突。
      此問題用貪心是可以得到最優解的,可以利用反證法證明此貪心策略的有效性。假設利用此貪心策略得到的解S不是最優,假設S*最優,然後依次比較任務,假設第r+1個任務不同,這時我們會發現,利用此貪心策略,是可以將S中的r+1任務來替換S*中的J+1任務的,這時S*依然是最優的,此時兩者的r+1任務也相同了。所以這與我們的假設只有r+1任務不同矛盾,證明了從貪心策略。       

        Other greedy algorithms.  Kruskal,Prim, Dijkstra,Huffman, …


       分治算法:

        分治算法的思想就是將問題劃分爲規模較小的子問題,對每個問題進行遞歸求解,然後合併子問題。列出遞歸表達式。很多算法,比如歸併排序、快速排序都是利用了分治的思想。
這裏就不對分治算法就不展開進行分析了。

      動態規劃DP

       動態規劃與分治算法最大的區別就是:動態規劃存在大量的子問題,對子問題的重複求解,浪費了大量的時間。動態規劃就是通過記錄子問題的解或者從底向上求解遞歸表達式,從而避免重疊子問題,是一種以空間換時間的算法。
       動態規劃算法的求解步驟就是:
               1. 定義子問題;
2.寫出遞歸表達式,和邊界條件。
3. 從底向上求解遞歸表達式。
     下邊,利用動態規劃的經典問題:揹包問題進行分析:

      揹包容量:11,求能裝的最大價值的物品。
1. 定義子問題:
        OPT(i,w):代表前i個物品在揹包容量爲w時的最大價值。
2. 定義遞歸表達式:


      3. 從底向上求解:

    
       利用從底向上求解,或者遞歸求解,利用一個二維數組記錄每一個子問題的解。最後一個[n][w]就是揹包問題的解。

      注意:此算法的時間複雜度爲O(nw)。這是一個僞多項式時間,可能輸入不是多項式的。


     多項式規約/NP/EXP/NPC/NPC問題證明/NP-hard/近似算法

這裏再簡單介紹一個標題的這些概念。

       多項式規約:是指經過多項式個步驟將一個問題A轉化爲另一個問題B,多項式調用解決B問題的算法可以解決問題A。多項式規約,是證明一個問題是NPC的基礎。
       NP:NP問題的定義是:一個算法存在多項式檢驗算法,也就是給定一個解可以驗證其是否正確。(多項式時間是屬於NP的)
       EXP:存在指數時間算法。
      NPC:現在沒有驗證,問題是否存在一個多項式算法。
      NP-EXP-NPC問題都是對於判斷問題而言的(算法結果是:YES,NO)。
       證明一個問題是否是NPC問題:
1. 改問題是NP問題;
2.存在一個一致的NPC問題可以多項式規約到此問題。
        如果該問題不是NP的,但可以進行多項式規約,則此問題是NP-hard。
        電路滿足問題,3滿足問題,點覆蓋問題,集合覆蓋,獨立集問題。。。都是NPC問題,NPC問題都是可以進行互相規約的。
       近似算法:用來解決NP問題,與最優解存在p倍關係。




















發佈了53 篇原創文章 · 獲贊 119 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章