本學期上了算法設計與分析這門課程,簡單的對其中的一些概念進行一下總結。基本都是我的一些宏觀上的理解。
時間複雜度,空間複雜度是算法重要的衡量標準。有很多算法問題都是多項式時間無法解決的。在算法面試中,如果你寫出了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,c2和n0使得對所有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倍關係。