演算法分析 如何分析乙個演算法的效率好壞?

2021-09-07 16:27:28 字數 3096 閱讀 1511

什麼是演算法分析

當我們說演算法分析的時候我們在說什麼?(狹義的技術層面的定義):

演算法分析指的是:對演算法在執行時間和儲存空間這兩種資源的利用效率進行研究。

即時間效率和空間效率。

時間效率指演算法執行有多快;

空間效率指演算法執行時需要多少額外的儲存空間。

(時間效率也叫時間複雜度;空間效率也叫空間複雜度。)

在計算機時代早期,時間和空間這兩種資源都是及其昂貴的。但經過半個多世紀的發展,計算機的速度和儲存容量都已經提公升了好幾個數量級。

現在空間效率已經不是我們關注的重點了,但時間效率的重要性並沒有減弱到這種可以忽略的程度。

所以,當我們分析乙個演算法的的時候,我們只關注它的時間效率。

演算法分析通用思路:

當我們遇到乙個演算法時,我們可以用這樣乙個通用的思路去分析它:

1. 輸入規模

首先第一步考慮這個演算法的輸入規模是什麼?即輸入引數,再換句話說也就是待解決的問題有多大?

從這裡入手是因為乙個顯而易見的規律就是,

不管使用什麼演算法,輸入規模越大,執行效率肯定會更長。

輸入規模的確定要根據具體要解決的實際問題的細節來決定,相同的問題不同的細節,輸入規模是不一樣的。比如:乙個拼寫檢查的演算法,

如果演算法關注的是單獨的字元檢查,那麼字元的數量就是輸入規模的大小;

如果演算法關注的是片語搭配的檢查,那麼這個輸入規模就要比單獨的字元檢查的輸入規模要小,這裡輸入規模就是詞的數量了。

2. 執行時間的度量單位

接下來第二步考慮這個演算法的執行時間,即這個演算法執行地快慢。

我們可以簡單地用計時的方法,即某個演算法執行了多少毫秒。

但這個方式有乙個缺陷就是在不同計算機上,相同演算法的執行時間是不一樣,因為有的電腦快有的電腦慢。

所以有沒有一種度量方法可以排除這些無關因素?

答案是肯定的,我們可以

關注演算法執行了多少步,即操作的執行次數。而且為了簡化問題我們只需關注最重要的操作步驟,即所謂的基本操作,因為基本操作已經足夠可以決定這個演算法的品質。

比如乙個演算法通常是最內層的迴圈中是最費時的操作,那我們就只需要把它迴圈了多少次作為基本操作進行研究。

3. 增長次數

這裡需要延伸的一點是在大規模的輸入情況下考慮執行次數的增長次數。因為針對小規模的輸入,在執行時間的差別上不太明顯。比如只對100個數字進行排序,不管你用什麼排序演算法,時間效率都差不多。只有在輸入規模變大的時候,演算法的差異才變得既明顯又重要了起來。

簡單來說,

如果乙個演算法在輸入規模變大時,但執行時間平緩增長,那麼我們就可以說它就是乙個效率高的演算法;

而如果乙個演算法在輸入規模變大時,它的執行時間成指數級增長,那就可以說這個演算法的效率很差。

總而言之就是,

對基本操作的大規模輸入情況下的變化的研究才更具有深遠意義。

4. 演算法的最優、最差和平均效率

當我們了解了輸入規模對演算法時間效率的會產生影響,但演算法的執行效率卻不僅僅只受輸入規模的影響,某些情況下,

演算法的執行效率更取決於輸入引數的細節。

比如:乙個簡單的順序查詢的演算法,在陣列裡查詢數字 9:

在陣列 list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9] 裡查詢數字 9 和在相同的輸入規模的另乙個陣列 list2 = [9, 1, 2, 3, 4, 5, 6, 7, 8]裡查詢數字 9,在陣列 list2 的執行效率肯定更高。

上面小例子中的兩個陣列就體現了兩個極端:輸入最優情況和輸入最壞情況。

相對應的,

在輸入最優情況下的演算法就叫最優效率;

在輸入最壞情況下的演算法就叫最差效率;

在這裡有兩個經驗性的規則:

最優效率的分析遠遠不如最差效率分析重要(因為最差效率可以確定演算法執行時間的上界);

如果乙個演算法的最優效率都不能滿足我們的要求,那麼我們就可以立即拋棄它。

在現實情況下,輸入是「隨機」的,既不會是最優輸入也不會是最壞輸入。所以這裡又要引出乙個概念,即:平均效率。

首先指出,我們

絕不能用「最優效率」和「最差效率」的平均數求得平均效率,即便有時間這個平均數和真正的平均效率巧合地一致。

正確的步驟是:我們要對輸入規模 n 做一些假設。

對於上面的順序查詢演算法的例子,標準的假設有兩個:

輸入裡包含目標數字,那麼演算法會成功查詢到目標數字,此時,成功查詢概率是 p(0 <= p <= 1);

對於任意數字 i,匹配發生在列表的第 i 個位置的概率是相同的。

基於這兩個假設求平均效率可得:

成功查詢到目標的情況下,對於任意 i,第一次匹配發生在第 i 個位置的概率都是 p/n,此時,演算法所做的比較次數是 i;

輸入陣列裡不包含目標數字,那麼演算法不成功查詢,比較次數是 n,在這種情況下,可能性是 (1-p)。

由此,平均效率 c(n) = p(n+1) / 2 + n(1-p)

c(n) = [1 * p/n + 2 * p/n + ... + i * p/n + ... + n * p/n] + n*(1-p)

=  p/n[1 + 2 + ... + i + ... + n] + n(1-p)

= p/n * n(n+1)/2 + n(1-p)

= p(n+1) / 2 + n(1-p)               

由此可知,

如果 p = 1,也就是說成功率是 100%,查詢一定能成功,代入公式可得 (n+1)/2,即大約要查詢陣列中一半的元素;

如果 p = 0,也就是說成功率是 0%,查詢必定失敗,代入公式可得 n,即演算法會對所有元素全部查詢一遍。

從這個例子可以發現,平均效率的研究要比最差效率和最優效率的研究困難很多:

我們要將輸入規模 n 劃分為幾種型別,對於同型別的輸入,使得演算法的執行次數是相同的。

結束:

利用python進行資料分析 基礎系列隨筆彙總

分享一張學校圖書館的**:

演算法分析 演算法的漸進效率分析

一般用於界定函式集合的上界,漸進表示式o g n 的含義就是,c為正常數,函式集合o中的元素的最大值不會超過c.g n f n o g n 的含義是,函式f n 的屬於集合o g n 因為函式集合o中的最大值為c.g n 所以f n 的最大值為c.g n 由於只是漸進的上界,所以當函式g n 的階數...

演算法時間效率分析

求效率函式的一般方法 big o 表示式 演算法的複雜度分析包括空間複雜度分析和時間複雜度分析。對於現代計算機,記憶體已經比較足夠,對演算法效率影響最大的是時間複雜度。在時間複雜度的分析中,拋開具體機器,我們主要研究的是執行的語句數量。執行的語句數量取決於需要處理的元素個數和演算法的迴圈結構。引入函...

排序演算法效率分析

目錄 排序方法 時間複雜度 平均 時間複雜度 最壞 時間複雜度 最好 空間複雜度 穩定性氣泡排序 o n2 o n2 o n o 1 穩定選擇排序 o n2 o n2 o n2 o 1 不穩定插入排序 o n2 o n2 o n o 1 穩定希爾排序 o n1.3 o n2 o n o 1 不穩定快...