2演算法複雜度詳解

2021-09-28 07:24:46 字數 4171 閱讀 1993

(1)時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數多,它花費時間就多。乙個演算法中的語句執行次數稱為語句頻度或時間頻度。記為t(n)。

(2)時間複雜度 在剛才提到的時間頻度中,n稱為問題的規模,當n不斷變化時,時間頻度t(n)也會不斷變化。但有時我們想知道它變化時呈現什麼規律。為此,我們引入時間複雜度概念。 一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式,用t(n)表示,若有某個輔助函式f(n),使得當n趨近於無窮大時,t(n)/f(n)的極限值為不等於零的常數,則稱f(n)是t(n)的同數量級函式。記作t(n)=o(f(n)),稱o(f(n)) 為演算法的漸進時間複雜度,簡稱時間複雜度。

另外,上面公式中用到的 landau符號其實是由德國數論學家保羅·**曼(paul bachmann)在其2023年的著作《解析數論》首先引入,由另一位德國數論學家艾德蒙·朗道(edmund landau)推廣。landau符號的作用在於用簡單的函式來描述複雜函式行為,給出乙個上或下(確)界。在計算演算法複雜度時一般只用到大o符號,landau符號體系中的小o符號、θ符號等等比較不常用。這裡的o,最初是用大寫希臘字母,但現在都用大寫英語字母o;小o符號也是用小寫英語字母o,θ符號則維持大寫希臘字母θ。

t (n) = ο(f (n)) 表示存在乙個常數c,使得在當n趨於正無窮時總有 t (n) ≤ c * f(n)。簡單來說,就是t(n)在n趨於正無窮時最大也就跟f(n)差不多大。也就是說當n趨於正無窮時t (n)的上界是c * f(n)。其雖然對f(n)沒有規定,但是一般都是取盡可能簡單的函式。例如,o(2n2+n +1) = o (3n2+n+3) = o (7n2 + n) = o ( n2 ) ,一般都只用o(n2)表示就可以了。注意到大o符號裡隱藏著乙個常數c,所以f(n)裡一般不加係數。如果把t(n)當做一棵樹,那麼o(f(n))所表達的就是樹幹,只關心其中的主幹,其他的細枝末節全都拋棄不管。

在各種不同演算法中,若演算法中語句執行次數為乙個常數,則時間複雜度為o(1),另外,在時間頻度不相同時,時間複雜度有可能相同,如t(n)=n2+3n+4與t(n)=4n2+2n+1它們的頻度不同,但時間複雜度相同,都為o(n2)。 按數量級遞增排列,常見的時間複雜度有:常數階o(1),對數階o(log2n),線性階o(n), 線性對數階o(nlog2n),平方階o(n2),立方階o(n3),…, k次方階o(nk),指數階o(2n)。隨著問題規模n的不斷增大,上述時間複雜度不斷增大,演算法的執行效率越低。

從圖中可見,我們應該盡可能選用多項式階o(nk)的演算法,而不希望用指數階的演算法。

常見的演算法時間複雜度由小到大依次為:ο(1)<ο(log2n)<ο(n)<ο(nlog2n)<ο(n2)<ο(n3)<…<ο(2n)<ο(n!)

一般情況下,對乙個問題(或一類演算法)只需選擇一種基本操作來討論演算法的時間複雜度即可,有時也需要同時考慮幾種基本操作,甚至可以對不同的操作賦予不同的權值,以反映執行不同操作所需的相對時間,這種做法便於綜合比較解決同一問題的兩種完全不同的演算法。

3)求解演算法的時間複雜度的具體步驟是:

⑴ 找出演算法中的基本語句;

演算法中執行次數最多的那條語句就是基本語句,通常是最內層迴圈的迴圈體。

⑵ 計算基本語句的執行次數的數量級;

只需計算基本語句執行次數的數量級,這就意味著只要保證基本語句執行次數的函式中的最高次冪正確即可,可以忽略所有低次冪和最高次冪的係數。這樣能夠簡化演算法分析,並且使注意力集中在最重要的一點上:增長率。

⑶ 用大ο記號表示演算法的時間效能。

將基本語句執行次數的數量級放入大ο記號中。

如果演算法中包含巢狀的迴圈,則基本語句通常是最內層的迴圈體,如果演算法中包含並列的迴圈,則將並列迴圈的時間複雜度相加。例如:

1.for (i=1; i<=n; i++)

2. x++;

3.for (i=1; i<=n; i++)

4.  for (j=1; j<=n; j++)

5. x++;

第乙個for迴圈的時間複雜度為ο(n),第二個for迴圈的時間複雜度為ο(n2),則整個演算法的時間複雜度為ο(n+n2)=ο(n2)。

ο(1)表示基本語句的執行次數是乙個常數,一般來說,只要演算法中不存在迴圈語句,其時間複雜度就是ο(1)。其中ο(log2n)、ο(n)、 ο(nlog2n)、ο(n2)和ο(n3)稱為多項式時間,而ο(2n)和ο(n!)稱為指數時間。計算機科學家普遍認為前者(即多項式時間複雜度的演算法)是有效演算法,把這類問題稱為p(polynomial,多項式)類問題,而把後者(即指數時間複雜度的演算法)稱為np(non-deterministic polynomial, 非確定多項式)問題。

一般來說多項式級的複雜度是可以接受的,很多問題都有多項式級的解——也就是說,這樣的問題,對於乙個規模是n的輸入,在n^k的時間內得到結果,稱為p問題。有些問題要複雜些,沒有多項式時間的解,但是可以在多項式時間裡驗證某個猜測是不是正確。比如問4294967297是不是質數?如果要直接入手的話,那麼要把小於4294967297的平方根的所有素數都拿出來,看看能不能整除。還好尤拉告訴我們,這個數等於641和6700417的乘積,不是素數,很好驗證的,順便麻煩轉告費馬他的猜想不成立。大數分解、hamilton迴路之類的問題,都是可以多項式時間內驗證乙個「解」是否正確,這類問題叫做np問題。
(4)在計算演算法時間複雜度時有以下幾個簡單的程式分析法則:

(1).對於一些簡單的輸入輸出語句或賦值語句,近似認為需要o(1)時間

(2).對於順序結構,需要依次執行一系列語句所用的時間可採用大o下"求和法則"

求和法則:是指若演算法的2個部分時間複雜度分別為 t1(n)=o(f(n))和 t2(n)=o(g(n)),則 t1(n)+t2(n)=o(max(f(n), g(n)))

特別地,若t1(m)=o(f(m)), t2(n)=o(g(n)),則 t1(m)+t2(n)=o(f(m) + g(n))

(3).對於選擇結構,如if語句,它的主要時間耗費是在執行then字句或else字句所用的時間,需注意的是檢驗條件也需要o(1)時間

(4).對於迴圈結構,迴圈語句的執行時間主要體現在多次迭代中執行迴圈體以及檢驗迴圈條件的時間耗費,一般可用大o下"乘法法則"

乘法法則: 是指若演算法的2個部分時間複雜度分別為 t1(n)=o(f(n))和 t2(n)=o(g(n)),則 t1*t2=o(f(n)*g(n))

(5).對於複雜的演算法,可以將它分成幾個容易估算的部分,然後利用求和法則和乘法法則技術整個演算法的時間複雜度

另外還有以下2個運算法則:(1) 若g(n)=o(f(n)),則o(f(n))+ o(g(n))= o(f(n));(2) o(cf(n)) = o(f(n)),其中c是乙個正常數

類似於時間複雜度的討論,乙個演算法的空間複雜度(space complexity)s(n)定義為該演算法所耗費的儲存空間,它也是問題規模n的函式。漸近空間複雜度也常常簡稱為空間複雜度。
空間複雜度(space complexity)是對乙個演算法在執行過程中臨時占用儲存空間大小的量度。乙個演算法在計算機儲存器上所占用的儲存空間,包括儲存演算法本身所占用的儲存空間,演算法的輸入輸出資料所占用的儲存空間和演算法在執行過程中臨時占用的儲存空間這三個方面。演算法的輸入輸出資料所占用的儲存空間是由要解決的問題決定的,是通過參數列由呼叫函式傳遞而來的,它不隨本演算法的不同而改變。儲存演算法本身所占用的儲存空間與演算法書寫的長短成正比,要壓縮這方面的儲存空間,就必須編寫出較短的演算法。演算法在執行過程中臨時占用的儲存空間隨演算法的不同而異,有的演算法只需要占用少量的臨時工作單元,而且不隨問題規模的大小而改變,我們稱這種演算法是「就地"進行的,是節省儲存的演算法,如這一節介紹過的幾個演算法都是如此;有的演算法需要占用的臨時工作單元數與解決問題的規模n有關,它隨著n的增大而增大,當n較大時,將占用較多的儲存單元,例如將在第九章介紹的快速排序和歸併排序演算法就屬於這種情況。

如當乙個演算法的空間複雜度為乙個常量,即不隨被處理資料量n的大小而改變時,可表示為o(1);當乙個演算法的空間複雜度與以2為底的n的對數成正比時,可表示為0(10g2n);當乙個演算法的空i司複雜度與n成線性比例關係時,可表示為0(n).若形參為陣列,則只需要為它分配乙個儲存由實參傳送來的乙個位址指標的空間,即乙個機器字長空間;若形參為引用方式,則也只需要為其分配儲存乙個位址的空間,用它來儲存對應實參變數的位址,以便由系統自動引用實參變數。

演算法複雜度詳解

一 定義 一般情況下,演算法中 基本操作重複執行的次數是問題規模n的某個函式,用t n 表示,若有某個輔助函式f n 使得當n趨近於無窮大時,t n f n 的極限值為不等 於零的常數,則稱f n 是t n 的同數量級函式。記作t n o f n 稱o f n 為演算法的漸進時間複雜度 o是數量級的...

2 演算法複雜度

演算法的目標 演算法複雜度 大o函式 常見大o函式 1 演算法的目標 演算法是對問題的解決方案,但乙個問題會有很多種演算法,通常乙個好的演算法需要具備以下目標 2 演算法複雜度 演算法複雜度用來衡量演算法的高效性,簡單的說就是 然而,執行時間和語言 機器 機器的狀態 資料量的大小都有關係,不好橫向比...

演算法複雜度O nlogn 詳解

首先看以下程式段 for int i 1 i n i for int j 1 j n j i 複雜度為o 1 求該程式段的時間複雜度。可以看出 1 當i 1時,需要執行n次 2 當i 2時,需要執行n 2次 3 當i 3時,需要執行n 3次 4 當i n 1時,需要執行n n 1次 5 當i n時,...