620 likes | 749 Views
演算法與問題之分析. 2. 演算法分析. 透過演算法的分析,我們可以判斷出一個演算法的好壞、改進它們 並且從一個問題的現有許多演算法中挑選出我們所需要的 在分析一個演算法的時候,我們主要關心的,是將來以程式語言來實作它並且執行該程式時所需要的記憶體量與時間 這其中我們尤其關心它所需要的時間. 演算法分析. 我們並不要求對於演算法的效率分析非常精準 一個“大概”的分析結果反而是比較受歡迎的 換句話說,演算法的分析只要八九不離十就可以了 差太多當然也不行!. 效率分析. 一個需要使用大量記憶體的程式它的執行時間通常也絕對不低
E N D
演算法與問題之分析 2 演算法 _ 第二章
演算法分析 • 透過演算法的分析,我們可以判斷出一個演算法的好壞、改進它們 • 並且從一個問題的現有許多演算法中挑選出我們所需要的 • 在分析一個演算法的時候,我們主要關心的,是將來以程式語言來實作它並且執行該程式時所需要的記憶體量與時間 • 這其中我們尤其關心它所需要的時間 演算法 _ 第二章
演算法分析 • 我們並不要求對於演算法的效率分析非常精準 • 一個“大概”的分析結果反而是比較受歡迎的 • 換句話說,演算法的分析只要八九不離十就可以了 • 差太多當然也不行! 演算法 _ 第二章
效率分析 • 一個需要使用大量記憶體的程式它的執行時間通常也絕對不低 • 因為每一個由程式所使用到的記憶體至少都需要程式去讀/寫它 • 即使一個程式使用非常少的記憶體,它也有可能需要非常高的計算時間 • 執行時間的分析才是關鍵之所在。 演算法 _ 第二章
效率分析策略 • 要分析一個演算法,我們可以針對該問題或演算法的基本運算做分析,而忽略掉起始工作、迴圈控制、以及其他一些例行程序等 • 對許多演算法來說,這種基本運算有可能只在主要的迴圈中出現一次 演算法 _ 第二章
效率分析策略 • 幾個常見問題的基本運算 • 這些基本運算通常也構成演算法的執行瓶頸 • 挑選好基本運算而且整個執行的運算數目也大致跟基本運算的執行次數成正比,那麼我們就有了一個估算演算法效率的好準據 演算法 _ 第二章
效率分析策略 • 演算法複雜度 • 演算法的時間複雜度 演算法 _ 第二章
效率分析策略 • 我們必須有一個估算一個問題的輸入資料量的準據 演算法 _ 第二章
效率分析策略 • 定義:一個演算法的時間複雜度是執行該程式直到執行完畢所需要的計算機時間,並且將這個數目表示成這個演算法的輸入資料量的一個函數 • 例如,2n, n2, n log n等,其中 n 代表輸入資料的長度 演算法 _ 第二章
最好、最壞、與平均複雜度 • 假設我們的輸入資料量固定為 n • 令 Dn 是針對一個問題的所有大小為 n 的可能輸入所成的集合 • 令 I 是 Dn的一個元素,換句話說,I 代表一組大小為 n 的輸入資料 • 令 t(I) 是演算法處理輸入 I 所執行的基本運算數目。 演算法 _ 第二章
最好、最壞、與平均複雜度 • B(n) = min{t(I)IDn} • 演算法處理任何大小為 n的輸入 I所可能執行的最小基本運算數目-最好情況的複雜度 • W(n) = max{t(I)IDn} • 演算法處理任何大小為 n 的輸入 I 所可能執行的最大基本運算數目-最壞情況的複雜度 • 即時應用 演算法 _ 第二章
平均時間複雜度 • 令 p(I) 是輸入資料 I 的出現機率 • 定義該演算法所執行的平均運算量-平均時間複雜度,如下: 演算法 _ 第二章
近似符號 演算法 _ 第二章
近似符號 演算法 _ 第二章
近似符號 • 當n 2時,3n + 2 4n成立,因此3n + 2 = O(n) • 當n 100時,1000n2 + 100n – 6 1001n2成立,因此1000n2 + 100n - 6 = O(n2) • 當n 2時,10n2 + 4n + 2 10n4成立,因此,10n2 + 4n + 2 = O(n4) 演算法 _ 第二章
近似符號 • 當n 1時,3n + 2 3n成立,因此3n + 2 = (n) • 當n 1時,10n2 + 4n + 2 n2成立,因此10n2 + 4n + 2 = (n2) • 當n 1時,6*2n + n2 2n成立,因此6*2n + n2 = (2n) 演算法 _ 第二章
近似符號 • 當n 2時,3n + 2 3n成立,而且當n 2時,3n + 2 4n成立,因此c1 = 3, c2 = 4, n0 = 2, 且3n + 2 = (n) • 10n2 + 4n + 2 = (n2) • 6*2n + n2 = (2n) • 10*log n + 4 = (log n) 演算法 _ 第二章
常見的演算法複雜度 演算法 _ 第二章
常見的演算法複雜度 演算法 _ 第二章
常見的演算法複雜度 • O(1) < O(log log n) < O(log n) < O(n) < O(n log n) < O(na) < O(2n) 演算法 _ 第二章
一些常用到的性質 演算法 _ 第二章
一些常用到的性質 • 一個根據 O(n3) 的演算法所編寫出的程式是否一定執行得比一個根據 O(n) 的演算法所編寫出的程式慢? • 不一定 ! • 0.1n3 vs. 1000n • 但是,只要 n 夠大,我們可以保證根據O(n) 的演算法所編寫出的程式一定跑得比較快 演算法 _ 第二章
因此 • 當輸入資料量很少(n很小)時,我們不見得要挑選複雜度最低的演算法 • 就以排序為例,如果 n 很大,那麼我們當然要選用O(n log n)的快速排序法 • 但是,如果 n 很小,那麼我們選用 O(n2)的氣泡排序法就可以了 演算法 _ 第二章
複雜度分析範例 • 二元搜尋-a[1]…a[n] • 令 left 和 right 分別表示我們要搜尋的序列之左端與右端 • 一開始 left = 1 而 right = n • 令middle = ( left + right )/2為此序列的中端 演算法 _ 第二章
二元搜尋 • 把 a [middle] 和 x 做比較,我們可以得到以下三種結果的一種: • x < a [middle]:在這種情況下,將 right 設成middle-1 • x = a[middle]:在這種情況下,回傳middle • x > a[middle]:在這種情況下,將 left 設成middle+1 演算法 _ 第二章
二元搜尋 演算法 _ 第二章
二元搜尋 • B(n)=O(1) • W(n)=O(log n) • T(n) = T(n/2) + O(1) = O(log n) • 事實上,我們可以證明二元搜尋的的平均計算時間也是 O(log n) 演算法 _ 第二章
選擇排序 演算法 _ 第二章
選擇排序 演算法 _ 第二章
選擇排序 • 第 4 行至第 6 行的迴圈會找出陣列 a[i : n]中最小元素的索引值 j • 這固定需要 n-(i+1)+1 = n-I 次的比較運算(第6行) • 第 4 行至第 6 行的迴圈被第 1 行至第 8 行的外迴圈所包圍 • i=0,n-1(n-i) = n-l + n-2 + … + 1 = (n-l)n/2 = O(n2) = B(n) = A(n) = W(n) 演算法 _ 第二章
插入排序 演算法 _ 第二章
插入排序 演算法 _ 第二章
插入排序 • 第 5 行至第 8 行的內迴圈在最好的情況下只需要做 1 次的比對運算就知道 a [j] 的插入位置 • 在最差的情況下需要做 j-1 次的比較運算後才能把 a [j] 插入到適當的位置 • 平均起來需要做 (j-1)/2 次的比較運算後才能把 a [j] 插入到適當的位置 演算法 _ 第二章
插入排序 • B(n) = j=2,n(1) = O(n) • W(n) = j=2,n(j-1) = 1 + 2 + … + n-2 + n-1 = (n-l)n/2 = O(n2) • A(n) = j=2,n (j-1)/2= (1 + 2 + … + n-2 + n-1)/2 = (n-l)n/4 = O(n2) 演算法 _ 第二章
演算法之最佳化與問題之複雜度 演算法 _ 第二章
最佳化的演算法 • 憑什麼說某一個演算法是所有可能用來解相同問題的演算法中最好的一個? • “最佳的”指的不是“已知中最好的”;而是“所有可能中最好的” • 問題的複雜度 演算法 _ 第二章
我們可以搜尋、排序得多快? • 證明解一個問題所需要的最少運算量 • 要找出一個好的演算法,我們必須做兩件事: • 找出解決該問題的下限,L(n),其中n代表輸入的大小 • 發展或找出一個高效率演算法A,並且分析它的最壞情況複雜度,W(n) • 如果W(n) = L(n),則我們說A是一個最佳化的演算法 • 否則,我們可能可以發展出更好的演算法,或者找出更好的問題下限,或者兩者都可以 演算法 _ 第二章
問題的複雜度下限 • 為了確定一個問題的複雜度下限為(g(n)),我們必須證明: 「解決該問題的每一個可能演算法它們的複雜度都是(g(n))。」 演算法 _ 第二章
決策樹與一些問題的下限分析 • 5 個元素序列的循序搜尋之決策樹 演算法 _ 第二章
決策樹與一些問題的下限分析 • 8 個元素序列的二元搜尋之決策樹 演算法 _ 第二章
決策樹與一些問題的下限分析 • 如果一棵樹有 n 個頂點,那麼這棵樹的高度必然大於等於 log2 n • 其中當樹本身是平衡樹時其高度等於 log2 n 演算法 _ 第二章
決策樹與一些問題的下限分析 演算法 _ 第二章
決策樹與一些問題的下限分析 • 3 個元素序列的排序之決策樹 演算法 _ 第二章
決策樹與一些問題的下限分析 • 樹葉代表著最後的可能結果,即 n 個元素的各種排列情況 • 總共有 n! 種排列情況 • 因此如果決策樹的樹葉數目是 p 的話,那麼 p n! • 最壞的情況指的是樹的高度 演算法 _ 第二章
決策樹與一些問題的下限分析 • 但是,我們知道如果樹的高度是 d,那麼p 2d,即 log2pd • 或者由於 p 是整數,我們可以寫成 d = log2p • 我們得到 d = log2p log2n! 演算法 _ 第二章
決策樹與一些問題的下限分析 演算法 _ 第二章
決策樹與一些問題的下限分析 • 史特林(Stirling)的近似公式: • 因此 演算法 _ 第二章
決策樹與一些問題的下限分析 • 換句話說,任何一個排序演算法,只要它的基本運算是兩個值的比較,那麼它的計算複雜度在最壞的情況下至少需要大約 n log n 次的比較 • 換句話說,排序問題的計算複雜度在最壞的情況下至少需要 (n log n) 次的比較 演算法 _ 第二章
決策樹與一些問題的下限分析 • 但是,合併排序演算法的最壞情況複雜度便是 O(n log n) • 因此我們說合併排序演算法是一個最佳化的排序演算法 • (n log n) 已經是最佳化的下限了 • 排序問題的平均情況計算複雜度下限也是 (n log n) 演算法 _ 第二章
決策樹與一些問題的下限分析 • 劣幣問題的計算複雜度下限 • xiH 代表 xi 是劣幣而且它比真幣重、xiL代表 xi 是劣幣而且它比真幣輕 • 平衡樹高度是log3 64 = 4 • 這意味著這個問題的下限是4,至少需要使用4次天秤 演算法 _ 第二章