week1——算法分析

聲明

本文是博主在Coursera學習時所寫的學習筆記,如有錯誤疏漏還望各位指正。

歡迎交流討論

如果大家轉載,請註明本文地址!


簡介

1.分析算法的必要性

  • 預測算法的性能
  • 用於算法之間的比較
  • 提供擔保(當數據量較大時,對性能的保證)
  • 學習理論基礎
  • 避免bug

2.如何分析算法

方法:

  1. 觀察特徵
  2. 基於觀察結果假設出數學模型
  3. 對假設出的模型進行預測
  4. 通過進一步的觀察證實假設
  5. 修改模型,直至假設與觀察結果一致

原則:
- 實驗必須是可重複的
- 假設必須是可證僞的


觀察

通過一個例子來介紹這部分

例子

問題:給定N個確定的數字,找出三個數字之和爲0的組合的個數
例如:
輸入:30,-20,-40,-10,40,0,10,5
因爲符合要求的組合爲4個
1. 30 -40 10
2. 30 -20 -10
3. -40 40 0
4. -10 0 10
所以輸出爲 4

解決算法

public static int count(int[] a)
 {
    int N = a.length;
    int count = 0;
    for (int i = 0; i < N; i++)
        for (int j = i+1; j < N; j++)
            for (int k = j+1; k < N; k++)
                if (a[i] + a[j] + a[k] == 0)
                    count++;
    return count;
 }

這是算法採用的方式暴力破解,通過三重循環遍歷所有組合並檢測其和是否爲0

測試算法運行時間

不同輸入結果的運行時間
這裏寫圖片描述

分析

通過對數運算對結果進行縮放,lg(T(N))=blgN+a
其中T(N) 是時間關於N的函數,T(N)=aNb , a,b 是常數

假設

講觀察結果和分析進行結合,做出假設
假設:運行時間 T=1.006×1010×N2.999 s

預測

N = 8000,T = 51.0s
N = 16000, T = 408.1s

觀察

這裏寫圖片描述

加倍法預測

通過加倍法預測可以快速估算b
這裏寫圖片描述
其中b = log(ratio) ,可以觀測出b的值趨近於3
注:此方法不可以確定加速因子

計算a:
取較大的N,進行測試得到a
這裏寫圖片描述

影響因素

獨立因素:

  • 輸入數據
  • 算法

相關因素:
- 硬件:cpu,內存…
- 軟件:編譯器,解釋器…
- 系統:網絡,操作系統…


數學模型

影響一個算法運行時間的因素有很多,但歸根結底還執行的指令數與執行每條指令所需要的時間。分析算法時應該分析當算法運行時執行的指令數,並當輸入數據增多時,執行指令數的增長速率是怎樣的。

分析指令

int count = 0;
    for (int i = 0; i < N; i++)
        for (int j = i+1; j < N; j++)
            if (a[i] + a[j] == 0)
                count++;

上述代碼所需要執行的指令

  • 賦值語句:N+2
  • 變量聲明:N+2
  • 小於比較:12(N+1)(N+2)
  • 等於比較:12N(N1)
  • 數組訪問:N(N1)
  • 增量運算:12N(N1) ~ N(N1)

簡化

但是這種分析是很繁瑣且沒有意義的,下面我們對其進行簡化

  • 建立代價模型:使用一些基本預算作爲計算運行時間的基礎。在此例中我們可以使用數組訪問作爲這種基本操作,換言之,當數組訪問次數越多時,我們就認爲運行時間越長。
  • Tilde notation:忽略低階項,只保留最高項。
    • 當N很大時,低階項何以忽略不計
    • 我們不考慮當N很小時的算法性能
    • ex:
      • N3+20N+16 ~N3
      • N3+N2+N/2 ~N3

經過簡化以後,對上述的雙重循環估算就可以表示爲
N(N1) ~ N2
這樣就極大的提高了我們分析算法的效率


增長模型

常見的增長模型

1,logN,N,NlogN,N2,N3,2N

各個模型的增長速率

舉例:
這裏寫圖片描述


算法原理

Theory of algorithms

  • Best case. Lower bound on cost.
  • Worst case. Upper bound on cost.
  • Average case. “Expected” cost.

Commonly-used notations

  • Θ(N2)
    表示算法的一般成本在N2 左右
    例如:10N2,5N2+22NlogN+3N,100N
  • O(N2)
    表示算法的上界成本是N2
    例如:100N,22NlogN
  • Ω(N2
    表示算法的下界成本是N2
    例如N2+22NlogN

內存

在程序運行時數據以二進制的形式存在於內存中,每個二進制位(bit)的值只能爲0或1,8個二進制位稱爲一個字節(byte)
1GB(Gigabyte) = 230 bytes
1MB(Megabyte) = 220 bytes

各類數據在內存中佔用的字節數

typebooleanbytecharintfloatlongdoublebytes1124488

一維數組:
typechar[]int[]double[]bytes2N+44N+48N+24

二維數組:
typechar[][]int[]double[]bytes2MN4MN8MN

對象:
  • object overhead:16bytes
  • pading:填充適量空白字節使每個對象所佔的字節數爲8的倍數
    舉個例子:
public class MysteryBox {                           //   16 (object overhead)
    private final int x0, x1, x2, x3;               //   16 (4 int)
    private final boolean y0, y1, y2, y3;           //    4 (4 boolean)
    private final long z0, z1;                      //   16 (2 long)
    private final double[] a = new double[72];      //    8 (reference to array)
                                                    //  600 (double array of size 72)
                                                     //4 (padding to round up to a multiple of 8)
}                                                      ----


共664字節                                                    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章