演算法評測

broadviewbj發表於2011-08-18

演算法評測

演算法評測—複雜度記法

剛才說過,線性查詢的計算量為O(n),二分查詢的複雜度為O(log n)。大多情況下,演算法的複雜度可以這樣定量評測。演算法評測一般使用複雜度記法(Order記法)。

複雜度記法表示的含義是,當演算法的輸入大小為n時,大致需要這麼多的計算量。

花費時間與n的大小無關,能在固定時間內完成的處理,其複雜度為O(1)。例如從雜湊中查詢資料,雖然要計算雜湊函式,但雜湊函式計算不依賴於n,所以複雜度為O(1)。而雜湊搜尋中,給定鍵的值(幾乎)是唯一的,因此透過鍵搜尋值的處理也是O(1)(也依賴於具體實現)。因此,雜湊搜尋整體複雜度為O(1)[1]

如前所見,線性查詢要從開頭開始查詢,最大要查詢n次。

些情況下只需一次就能找到,但複雜度記法並不考慮這種特殊情況,而是表示平均值或最大值。因此記為O(n)。二分查詢為O(log n)

像這樣用複雜度記法表示各種演算法,即可比較演算法的效能。線性查詢和二分查詢分別為O(n)O(log n),因此二分查詢的計算量比較少[2]

各種演算法的複雜度記法

各種演算法的複雜度記法中,下述幾種計算量經常出現。

O(1) < O(log n) < O(n) < O(nlog n) < O(n2) < O(n3) < O(nk) < O(2n)

越往右,複雜度越大。處理大規模資料時,也就是說n比較大時,實用演算法也就到O(n logn)附近。再高,複雜度就會隨著n的增加而急劇增大,經常導致計算無法結束。

感覺上而言,O(log n)O(n)要快很多,O(n)O(n log n)的差距不是很大,O(n)O(n2)之間的鴻溝決定著著計算能否完成……。

關於速度問題,如果相當複雜的演算法能用O(n2)的計算完成,那也可以說“相當快”了,畢竟速度取決於演算法中的計算本身。例如,一般的基於比較的排序演算法無論怎麼最佳化,也不可能比O(n logn)快,這一點在理論上可以證明。因此,排序演算法能達到O(n logn),就可以認為是高速演算法。

複雜度的概念不僅用於表示計算的時間,也可以用於表示空間。也就是說,複雜度記法不僅可以表示執行時間、操作步驟數,還可以表示記憶體使用量等。

 

 

上面講述了演算法評測。更為詳細的內容,請參考講解演算法的書籍。

演算法評測

複雜度記法

複雜度

時間複雜度(執行時間、操作步驟數)

空間複雜度(記憶體使用量)

紙巾能摺疊幾次?O(logn)O(n)的差距

剛才說過,線性查詢和二分查詢相比,資料量變大後,計算時間就會出現巨大差距。這裡的重點不是複雜度記法本身,而是利用複雜度記法比較演算法時,對演算法間差距的感覺。就是說要掌握O(log n)O(n)n增大時,對於複雜度差距的感覺。

再看個身邊的例子。準備一張紙巾,然後將其多次對摺。到底能對摺多少次呢?第一次只需對半摺疊即可,完全沒問題。第二次、第三次、第四次直到第五次應該也沒問題。但第六次就比較難折了,第七次和第八次完全折不動而不得不放棄。可能有人會想“折100次肯定沒問題!”,而實際上7次就是極限了。為什麼呢?

摺紙所需的勞動量,依賴於要折的紙張的厚度。假設這個厚度最初為1mm,那麼第一次摺疊之後就是2mm。兩次摺疊後是3mm……不對,是4mm

這樣,厚度是12481632…這樣增加的。可以認為,設摺疊次數為n,計算量就按照2n增長。剛才看到,O(2n)是個相當大的複雜度,因此紙巾在n=8時無法摺疊也就可以理解了。

另外有文章介紹過,厚度為0.11mm的衛生紙摺疊25次後會達到富士山的高度[3]。要摺疊富士山那麼高的紙……一般方法絕對做不到吧。

對演算法中指數增加、對數增加的感覺

計算量按照指數增加的演算法,只需一點點資料量,計算量就會變得龐大無比。與指數相反,只以對數增加的O(log n)的演算法,即使資料量變得非常大,也只需一點計算量就能解決,這點也能直觀地理解吧。

在思考演算法複雜度時,這種感覺是最重要的。例如要操作的資料有1000萬條,如果能選擇對數演算法,那麼只需幾十次計算就可以了。相反,如果選錯了演算法,使用O(n2)O(2n)的演算法實現的話,寫出的程式即使只有幾百條資料,也要浪費相當多資源。

 演算法評測

本文節選自《大規模WEB服務開發技術》一書

圖書詳細資訊:http://space.itpub.net/?uid-13164110-action-viewspace-itemid-705176


 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13164110/viewspace-705280/,如需轉載,請註明出處,否則將追究法律責任。

相關文章