在計算機科學中，演算法分析是分析執行一個給定演算法需要消耗的計算資源數量（例如計算時間，儲存器使用等）的過程。演算法的效率或複雜度在理論上表示為一個函式。其定義域是輸入資料的長度（通常考慮任意大的輸入，沒有上界），值域通常是執行步驟數量（時間複雜度）或者儲存器位置數量（空間複雜度）。演算法分析是計算複雜度理論的重要組成部分。 理論分析常常利用漸近分析估計一個演算法的複雜度，並使用大 O 符號、大 Ω 符號和大 Θ 符號作為標記。舉例，二分查詢所需的執行步驟數量與查詢列表的長度之對數成正比，記為 O log n，簡稱為「對數時間」。通常使用漸近分析的原因是，同一演算法的不同具體實現的效率可能有差別。但是，對於任何給定的演算法，所有符合其設計者意圖的實現，它們之間的效能差異應當僅僅是一個係數。 精確分析演算法的效率有時也是可行的，但這樣的分析通常需要一些與具體實現相關的假設，稱為計算模型。計算模型可以用抽象機器來定義，比如圖靈機。或者可以假設某些基本操作在單位時間內可完成。 假設二分查詢的目標列表總共有 n 個元素。如果我們假設單次查詢可以在一個時間單位內完成，那麼至多隻需要 log n 1 單位的時間就可以得到結果。這樣的分析在有些場合非常重要。 演算法分析在實際工作中是非常重要的，因為使用低效率的演算法會顯著降低系統性能。在對執行時間要求極高的場合，耗時太長的演算法得到的結果可能是過期或者無用的。低效率演算法也會大量消耗計算資源。 時間資源消耗 時間複雜度分析和如何定義「一步操作」有緊密聯絡。作為演算法分析成立的一項基本要求，單步操作必須能夠在確定的常量時間內完成。 實際情況很複雜。舉例，有些分析方法假定兩個數相加是單個步驟，但這假定可能不成立。若被分析的演算法可以接受任意大的數，則無法保證相加操作能夠在確定的時間內完成。 通常有兩種定義消耗的方法： section 13 單一消耗：每一步操作的消耗定義為一個常量，與參與運算的資料的大小無關。 對數消耗：每一步操作的消耗，均與參與運算的資料的長度（位數）成正比。 後者更難以應用，所以只在必要時使用。一個例子是對接受任意精度資料的演算法（比如密碼學中用到的一些演算法）的分析。 人們常常忽略一點：演算法的效率的理論界限，通常建立在比實際情況更加嚴格的假定之上。因此在實際中，演算法效率是有可能突破理論的界限的。Examples of the price of abstraction cstheorystackexchangecom 經驗分析的缺陷 演算法是平臺無關的，也即一個演算法可以在任意計算機、任意作業系統上、用任意程式語言實現。因此，演算法效能的相對好壞，不能僅僅透過基於執行記錄的經驗來判斷。 舉例：一個程式在大小為 n 的有序陣列中搜索元素。假設該程式在一臺先進的電腦 A 上用線性搜尋實現，在一臺老舊的電腦 B 上用二分搜尋實現。效能測試的結果可能會如下： 陣列長度 n 計算機 A 的執行時間（以納秒計） 計算機 B 的執行時間（以納秒計） 15 7 100000 65 32 150000 250 125 200000 1000 500 250000 透過這些資料，很容易得出結論說計算機 A 執行的演算法比計算機 B 的演算法要高效得多。但假如輸入的陣列長度顯著增加的話，很容易發現這個結論的錯誤。 以下是另一組資料： 陣列長度 n 計算機 A 的執行時間（以納秒計） 計算機 B 的執行時間（以納秒計） 15 7 100000 65 32 150000 250 125 200000 1000 500 250000 1000000 500000 500000 4000000 2000000 550000 16000000 8000000 600000 63072 1012 31536 1012 納秒，約等於 1 年 1375000 納秒，或 1375 毫秒 計算機 A 執行的線性搜尋演算法具有線性時間。它的執行時間直接與輸入規模成正比。輸入大小若加倍，執行時間同樣加倍。而計算機 B 執行的二分搜尋演算法具有對數時間。輸入大小若加倍，執行時間僅僅增加一個常量，在此例中是 25000 納秒。即使計算機 A 明顯效能更強，在輸入不斷增加的情況下，計算機 B 的執行時間終究也會比計算機 A 更短，因為它執行的演算法的增長率小得多。 增長的階 非正式地，如果一個關於 n 的函式 f n，乘以一個係數以後，能夠為某個演算法在輸入資料大小 n 足夠大的情況下的執行時間提供一個上界，那麼稱此演算法按該函式的階增長。一個等價的描述是，當輸入大小 n 大於某個 n_0 時，存在某個常數 c，使得演算法的執行時間總小於 ctimes f n。常用大 O 符號對此進行描述。比如，插入排序的執行時間隨資料大小二次增長，那麼插入排序具有 O n2 的時間複雜度。大 O 符號通常用於表示某個演算法在最差情況下的執行時間，但也可以用來表述平均情況的執行時間。比如，快速排序的最壞執行時間是 O n2，但是平均執行時間則是 O n log n。在演算法分析的場合裡，常用 log 或 lg 作為 log_2 的簡稱。 執行時間複雜度的分析 分析一個演算法的最壞執行時間複雜度時，人們常常作出一些簡化問題的假設，並分析該演算法的結構。以下是一個例子： 1 從輸入值中獲取一個正數 2 if n 10 3 print 耗時可能較長，請稍候 4 for i 1 to n 5 for j 1 to i 6 print i j 7 print 完成！ 一臺給定的電腦執行每一條指令的時間是確定但這對量子計算機不成立。的，並可以用 DTIME 描述。 假設第 1 步操作需時 T1，第 2 步操作需時 T2，如此類推。 步驟 1、2、7 只會執行一次。應當假設在最壞情況下，步驟 3 也會執行。步驟 1 至 3 和步驟 7 的總執行時間是： T_1 T_2 T_3 T_7 步驟 4、5、6 中的迴圈更為複雜。步驟 4 中的最外層迴圈會執行 n 1 次（需要一次執行來結束 for 迴圈，因此是 n 1 次而非 n 次），因此會消耗 T4 n 1 單位時間。內層迴圈則由 i 的值控制，它會從 1 迭代到 n。 第一次執行外層迴圈時，j 從 1 迭代到 1，因此內層迴圈也執行一次，總共耗時 T6 時間。以及內層迴圈的判斷語句消耗 3T5 時間。 所以，內層迴圈的總共耗時可以用一個等差級數表示： T_6 2T_6 3T_6 cdots n1 T_6 n T_6 上式可被因式分解可用數學歸納法證明 1 2 3 cdots n1 n frac n n12 為： T_6 left 1 2 3 cdots n1 n right T_6 left frac 12 n2 n right 類似地，可以分析內層迴圈的判斷語句： 2T_5 3T_5 4T_5 cdots n1 T_5 n T_5 n 1 T_5 T_5 2T_5 3T_5 4T_5 cdots n1 T_5 nT_5 n1 T_5 T_5 上式可被分解為： T_5 left 123cdots n1 n n 1 right T_5 left frac 12 n2 n right T_5 n 1 T_5 T_5 T_5 left frac 12 n2 n right n T_5 left frac 12 n2 3n right T_5 因此該演算法的總執行時間為： f n T_1 T_2 T_3 T_7 n 1 T_4 left frac 12 n2 n right T_6 left frac 12 n23n right T_5 改寫一下： f n left frac 12 n2 n right T_6 left frac 12 n2 3n right T_5 n 1 T_4 T_1 T_2 T_3 T_7 通常情況下，一個函式的最高次項對它的增長率起到主導作用。在此例裡，n² 是最高次項，所以有結論 f n O n2。 嚴格證明如下：證明 left frac 12 n2 n right T_6 left frac 12 n2 3n right T_5 n 1 T_4 T_1 T_2 T_3 T_7 le cn2 n ge n_0 left frac 12 n2 n right T_6 left frac 12 n2 3n right T_5 n 1 T_4 T_1 T_2 T_3 T_7 le n2 n T_6 n2 3n T_5 n 1 T_4 T_1 T_2 T_3 T_7 n geq 0 令 k 為一個常數，其大於從 T1 到 T7 所有的數。 T_6 n2 n T_5 n2 3n n 1 T_4 T_1 T_2 T_3 T_7 le k n2 n k n2 3n kn 5k 2kn2 5kn 5k le 2kn2 5kn2 5kn2 n geq 1 12kn2 因此有 left frac 12 n2 n right T_6 left frac 12 n2 3n right T_5 n 1 T_4 T_1 T_2 T_3 T_7 le cn2 n ge n_0，其中 c 12k n_0 1 還可以假定所有步驟全部消耗相同的時間，它的值比 T1 到 T7 中任意一個都大。這樣的話，這個演算法的執行時間就可以這樣來分析：比起上面的方法，這個方法忽略了結束迴圈的判斷語句所消耗的時間，但很明顯可以證明這種忽略不影響最後結果。 4sum_i1n ileq 4sum_i1n n4n2leq5n2 n geq 1 O n2 其他運算資源的增長率分析 運用與分析時間相同的方法可以分析其他運算資源的消耗情況，比如儲存器空間的消耗。例如，考慮以下一段管理一個檔案的記憶體使用的虛擬碼： while 檔案開啟 令 n 檔案大小 for n 每增長 100kb 為該檔案分配多一倍的記憶體空間 在這個例子裡，當檔案大小 n 增長的時候，記憶體消耗會以指數增長，或 O 2n。這個速度非常快，很容易使得資源消耗失去控制。 參見 平攤分析 漸近分析 漸近時間複雜度 計算時間 大 O 符號 計算複雜性理論 主定理 NP 完全 數值分析 多項式時間 程式最佳化 效能分析 可擴放性 平滑分析 時間複雜度，包括常見演算法的增長率列表 註釋 來源 書籍 Category 計算複雜性理論