1. 程式人生 > >【斯坦福演算法分析和設計02】漸進分析

【斯坦福演算法分析和設計02】漸進分析

目錄

  • 1. The Gist
    • 1.1 為什麼要學它(Motivation)
    • 1.2 High level idea
    • 1.3 4個例子
  • 2. Big-Oh Notation
    • 2.1 文字定義
    • 2.2 圖形定義
    • 2.3 數學定義
  • 3. 2個例子
    • 3.1 k階多項式是O(n^k)
    • 3.2 k階多項式不是O(n^(k-1))
  • 4. Big Omega and Theta
    • 4.1 Big-Omega表示法
    • 4.2 Big-theta表示法
    • 4.3 Little-O表示法
    • 4.4 漸進性表示法的來源
  • 5. 幾個額外的例子【可選】
    • 5.1 在指數中新增一個常數
    • 5.2 指數乘以一個常數
    • 5.2 最大值和求和

 

1. The Gist

1.1 為什麼要學它(Motivation)

我們的目的是尋找一種對演算法進行衡量的最有效力度,我們希望忽略不重要的細節,例如常數因子和低階項,把注意力集中在演算法的執行時間是怎樣隨著輸入長度的增長而增長的,這些任務是通過大O表示法(包括它的近親表示法)的形式完成的,每個程式設計師都應該掌握這個概念。

它是行業術語漸進性表示法提供了討論演算法設計與分析的基本術語,當我們聽到某個程式設計師談論他的某段程式碼以"n的大O時間執行",而另一段程式碼,以"n平方的大O時間執行"時,我們需要知道其中的意思。它是區別不同演算法的"sweet spot"它有粗放和精細的兩個特徵。粗放:忽略了所以我們想要忽略的細節,比如說計算機體系結構,具體選擇的程式語言以及編譯器等方面的細節。精細:可以在不同層次對解決這個問題不同演算法進行比較,尤其在巨大輸入情況下,輸入的規模越大,就越需要精妙的演算法。

1.2 High level idea

一句話概括漸進性表示法的話,就是忽略常數因子和它的低階項。

 

 

為什麼我們要忽略常數因子和它的低階項?根據定義,我們把注意力放在大規模的輸入時低階項的作用就幾乎可以忽略了,而大規模的輸入才是需要精妙演算法的時候,同時常數因子一般高度依賴於環境的細節,如果我們分析演算法時並不想固定於某種特定語言計算機體系結構和編譯器,那麼使用不在意的常數因子就會非常合理。不是說忽略的就不重要,什麼時候它重要?忽略的意思並不是說常數因子是完全無關緊要的,只不過當我們想要對解決同一個問題的一些不同方法進行比較的時候,漸進性表示法往往是正確的工具,它能幫助我們理解哪種演算法的效能最佳,尤其是當輸入規模非常大時,但我們確定了某個問題的最佳高階演算法後,可能還想進一步優化常數因子和低階項。

1.3 4個例子

這裡有4個比較簡單的例子,如果是第一次接觸這個概念的朋友可以自己試著做一下,求每個例子的漸進性執行時間。後臺回覆【漸進性表示法】檢視答案。Algorithm 1陣列A中包含整數t嗎?

1: for i = 1 to n do  
2:   if A[i] == t then  
3:       Return TRUE  
4: Return FALSE
Algorithm 2給定陣列A,B和整數t,A或B中包含t嗎?
1:  for i = 1 to n do
2:     if A[i] == t then
3:         Return TRUE
4:  for i = 1 to n do
5:     if B[i] == t then
6:         Return TRUE
7:  Return FALSE
Algorithm 3陣列A,B有相同的元素嗎?

1: for i = 1 to n do
2:    for j = 1 to n do
3:       if A[i] == B[j] then
4:           Return TRUE
5: Return FALSE

Algorithm 4陣列A中有重複的元素嗎?

1: for i = 1 to n do
2:    for j = i+1 to n do
3:       if A[i] == A [j] then
4:           Return TRUE
5: Return FALSE

  

2. Big-Oh Notation

2.1 文字定義

大O表示法關注的是定義在正整數n = 1,2,3..上的函式T(n),T(n)總是表示某個演算法的最壞情況執行時間的上界,那麼當我們說T(n)=O(f(n))的時候表示什麼意思呢?

T(n)=O(f(n))當且僅當T(n)的最終上界是f(n)的一個常數積。

2.2 圖形定義

由下圖我們看到T(n)的上界並不是由f(n)決定的,是由f(n)乘以3所形成的上面那個虛線決定的,當n的值足夠大時超過n0這個分界點,之後它的值就會大於T(n),所以T(n)實際上最終是由f(n)的常數積確定上界,我們就可以說T(n)=O(f(n))。

這裡的常數c滿足f(n)的常數倍,常數n0滿足最終。

2.3 數學定義

T(n)=O(f(n))表示當且僅當存在正常數c和n0,對所有的,不等式都成立。這個數學公式實際上是對文字定義的直接翻譯。“對所有的n大於等於n0”表示這個不等式只需要當n足夠大的時候(n0確定了具體的大小)最終能夠成立,而在圖中常數c對應的是3,n0對應的是函式T(n)和cf(n)之間的分界值.warning:一個警告,當我們說c和n0是常數,意思是它並不依賴於n,比如說圖中的c和n0是固定的數字,像是300,1000,如果我們在證明中看到n0=n,或者c=log(n)這樣的說法,它就是與n有關的,就不是常數值了。

3. 2個例子

3.1 k階多項式是O(n^k)

這個命題表示在多項式的大O表示法中,我們需要關注的是出現在多項式的最高階。因此大O表示法確實忽略了常數因子和低階項。簡化版的證明過程如下

以下是詳細版本的解釋。根據大O表示法的數學定義,我們需要的是找到一對正整數c和n0,我們先假設這兩個常量的值: n0=1,c等於所有係數的絕對值之和:。這兩個數都與n無關,現在我們需要證明選擇的這兩個常量滿足不等式,即對所有,都有。首先我們看看T(n)的定義:如果我們在右邊取每個係數的絕對值,這個表示式只會變得更大。(只會比更大,由於是正數,只會比更大),於是:既然係數是非負數,我們也可以用類似的技巧讓n的不同乘方轉換成n的公共乘方。由於,對於每個,只會比更大,由於是非負正數,所以只會比更大。就意味著:對於每個,這個不等式是成立的,這就是我們想要的證明結果。

3.2 k階多項式不是O(n^k-1)

它表示不同階的多項式的大O表示法是不同的。我們可以用反證法,假設結論的相反結論是對的,並在這個假設上進行一系列的邏輯正確的步驟,最後推匯出出錯。簡單的證明過程如下

以下是詳細的文字解釋。因此假設=,那麼它意味著什麼呢?的最終上界是的一個常數積確定的。也就是說,存在常數c和,對於所有的,都存在由於n是正數,我們可以從兩邊消去,於是對於所有的,都存在。相當於說c比每個正整數都要大,這是明顯錯誤的(可以取n的值是c+1向上取最接近的整數),這就說明原來的假設是錯誤的。

4. Big Omega and Theta

4.1 Big-Omega表示法

文字表示法就是,當且僅當T(n)的下界是由f(n)的一個常數積所確定,那麼T(n)就是另一個函式f(n)的大。數學定義如下:

當且僅當存在正常數c和,使得對於每一個,都有。對應的圖形式如下:

f(n)並沒有確定T(n)的下界,但是如果把它乘以常數,那麼就是在臨界點的右邊確定了T(n)的下界。

4.2 Big-theta表示法

它可以類比於“等於”,相當於同時滿足和,相當於T(n)被夾在f(n)的兩個不同的常數積之間。數學定義如下:

當且僅當存在正常數,使得當的時候,有。


4.3 Little-O表示法

T(n)=o(f(n))表示當且僅當對所有c>0的常數,存在常數n0,對所有的,不等式都成立。

4.4 漸進性表示法的來源

漸進表示法不是由電腦科學家發明的,是開始於數論。

5. 幾個額外的例子【可選】

5.1 在指數中新增一個常數

這個例子是說,一個函式的指數與一個常數相加,並不會改變這個函式的漸進性時間增長率。簡化的證明過程:

更詳細的解釋:要證明這個,我們需要找到合適的正常數c和,使得對於所有的,T(n)的最大值是,我們來對它進行反向工程。

我們在尋找一個推導方式,不斷的放大T(n)使得它是的常數倍,我們看到T(n)的指數裡有個10,很自然的想著把它分出去:我們發現右邊就是的常數倍,這就提醒我們c取1024。假設選擇這個c,那麼對於所有的都有,因此我們取,那麼就證明出來了。

5.2 指數乘以一個常數

這個命題的意思是,把一個指數函式的指數和一個常數相乘改變了它的漸進性增長率。簡化的證明過程:

 

更詳細的文字:這個用反證法來證明,它的相反結論是對的,就是。根據大O的定義,存在正常數c和,對於所有的,都有,因為是個正數,所以我們可以兩邊去掉,就得,這個是錯誤的,因為右邊是個固定的數,而左邊是隨著n增加而無限增加的,說明我們的假設是錯誤的,這就證明得了原問題。

5.2 最大值和求和

這個例子表示從漸進性的角度,取兩個非負數的逐點最大值和取她們的和沒有什麼差別。簡化的證明過程:

的含義表示T(n)最終位於f(n)的兩個不同常數倍之間。我們需要三個常數:,,,後面兩個對應較大倍數和較小倍數。我們對幾個數進行反向工程。任何一個正整數都存在以下關係:因為不等式的右邊就是左邊的數加上另一個非負數(f(n)和g(n)中較小的那個數)。類似的因為不等式的左邊是f(n)和g(n)中較大那個的兩倍,把兩個不等式合在一起就是,對每個,都有確實位於兩個不同倍數之間,相當於今日互動

歡迎在評論區留下不懂