yishun:可計算性理論的理解zhuanlan.zhihu.com
現在,我們來討論演算法執行的時間複雜度。
表示以下函式集合:
o(g(n))表示以下函式集合:
表示以下函式集合:
f(n)=
或 o(g(n)),表示f(n)是
或 o(g(n))的成員。
首先要明確輸入規模的概念,一般來說,它指編碼演算法輸入所需的位元組數,比如說,排序乙個n個數字的陣列,每個數字需要m個位元組來編碼,那麼輸入規模是m*n。但這種方法並不適用於所有情況,比如說,求大於0小於n的所有素數,輸入為n,演算法執行所需的時間取決於n的大小,而不是編碼它所需的位元組數。
輸入規模的定義取決於具體問題,也取決於輸入的編碼方式。
「執行時間」指乙個演算法在特定輸入上執行所需執行的指令數。有很多演算法,在輸入規模相同的情況下,不同的輸入所需的執行時間也是不同的。比如插入排序,如果輸入陣列是已經排序好的話,插入排序的執行時間與輸入規模是線性關係。一般來說,我們僅分析某個輸入規模下,可能的最大執行時間,在某些特殊情況下,我們也會研究平均執行時間,比如快速排序。在本文中,我們僅研究演算法在給定輸入規模上的最大執行時間。
可以發現,演算法的在給定輸入規模的情況下,其最大執行時間是輸入規模的函式,如下面的插入排序例子所示:
插入排序**及其分析
插入排序的執行代價,令所有c均為1則得到」執行時間」
可以發現插入排序的最大執行時間是輸入規模的二次函式。
在比較不同演算法的執行效率時,我們比較關注的是執行時間隨輸入規模增長的增長量級,這是因為不同量級帶來的效能差異相當巨大,佔主要矛盾。
我們用第一節的o漸近符號來表示執行時間的增長量級,比如說,對於插入排序,其執行時間滿足:
。我們稱用o表示的執行時間增長量級為乙個演算法的
時間複雜度,對於插入排序,其時間複雜度為
。本節將討論如何計算分治法的時間複雜度。世間演算法太多,不太可能存在乙個通用正規化去分析所有演算法,特別是對於一些隨機化演算法。
我們先盡可能簡單的介紹一下分治法:把輸入劃分為若干個與原問題相同但規模更小的子問題(直到問題規模足夠小,可以直接求解),遞迴呼叫自身獲取子問題的解,並將其合併獲取原問題的解。
令t(n)為某分治演算法在輸入規模為n時的的執行時間,且當n<=c時可以在常數時間
內直接求解問題。假設把原問題分解為a個子問題,且每個子問題的規模為n/b。假設分解問題時間為d(n),合併子問題的解所需時間為c(n)。那麼我們可以獲取t(n)的遞迴式如下:
求解遞迴式即可得到演算法的時間複雜度。求解遞迴式的方法有以下3種:
遞迴樹法:將遞迴式轉化為一棵樹,其節點代表不同層次遞迴計算的執行時間,然後採用邊界和技術求解遞迴式。
主方法:即代公式。
首先介紹遞迴樹法,下圖為歸併排序的遞迴式:
其遞迴樹如下所示:
下面介紹主方法:
令a 0和b>1是常數,f(n)是乙個函式,有遞迴式t(n)=at(n/b)+f(n),那麼t(n)有如下漸近界:
若對某個常數m>0,有
,則 。
若 ,則
。若對某個常數m>0,有
,且對某個常數c<1和所有足夠大的n有af(n/b)
cf(n),則
。不難發現,歸併排序的遞迴式滿足應用情況2,可以代入後直接獲得漸近界。主定理的證明比較麻煩,感興趣的同學可以直接去參考《演算法導論》。
一般情況下,我們認為多項式時間內可解(時間複雜度為o(n^k))的問題是易於處理的,超多項式複雜度的問題是不易處理的。那麼是否所有問題都可以在多項式時間內解決?答案是否定的!本節將研究一類稱為「np完全」的有趣問題,由於此類問題的分析有一定難度,所以本節的論述大多不會給出證明。
p類問題指在多項式時間內可以解決的問題,np類問題指可以在多項式時間類證明給定「解」和輸入是否匹配的問題。顯然p問題都是np問題,至於np是否等於p,目前沒有定論。
如果乙個np問題的解決難度不小於其他任何np問題,那麼我們認為此問題是npc問題(np完全問題)。可以發現,只要證明乙個npc問題是p問題,那麼等價於證明了np=p。
給定乙個問題b,如何證明其是npc問題呢?假設我們已知了乙個npc問題a,那麼我們只要找到乙個多項式演算法將a轉化為b即可,因為這樣保證了問題b和問題a在多項式時間因子內的難度是一樣的。我們稱這個方法為多項式時間歸約。
那麼剩下的問題就是找到第乙個npc問題。這個問題是「電路可滿足性問題」:給出乙個由與或非組成的布和組合電路,那麼這個電路是否是可滿足的?即是否存在乙個輸入使得電路輸出1。我們只需要證明每乙個np問題都可以多項式歸約到這個問題即可,如下所示:
由於電路可滿足性問題是乙個判斷性問題,即其解只有「是」或「否」,那麼我們也只能把判斷性問題歸約到它。我們將證明可以把任何可判斷性的np問題多項式歸約到電路可滿足性問題,這看似沒法證明後者是npc的,實則不然,因為可判斷性的問題的「表達容量」相當大,幾乎任何np問題都可以轉化為對應的判斷性問題。
對於任意乙個判斷性的np問題l,給定輸入x和「解」y(對於電路滿足問題,x是電路結構,y是使電路x輸出1的電路輸入),必然存在演算法a可以在多項式時間內判斷x和y是否「匹配」。由於a是多項式時間演算法,那麼其執行步數和所需的記憶體必然都是多項式複雜度的,我們可以把演算法a的執行過程展開,如下圖所示:
我們可以把上圖在多項式時間內轉化為乙個接受y作為輸入的電路,如果這個電路是可滿足的,即證明存在y使得原問題l的解為「是」。
綜上所述,電路可滿足問題是npc問題得證。
npc問題在很多領域都會遇到,下面將介紹幾種npc問題,其證明結構如下圖所示:
若輸入規模小,這採用超多項式複雜度演算法直接求解。
尋找可以在多項式時間內求解的特殊情況。
本文到這裡就結束了,主要圍繞時間複雜度理論和np完全性理論。
時間複雜度為O(n)的排序演算法
我們常用的幾種排序演算法,氣泡排序,選擇排序,它們已經是相對比較簡單,穩定的排序演算法了,但是它們時間複雜度為o n n 基本都要用到兩層迴圈,今天我就像大家介紹一種簡單,只用一層for迴圈,時間複雜度為o n 的排序演算法。樣例輸入 1 4 5 6 3 4 2 8 9 1 樣例輸出 1 1 2 3...
實現排序演算法,時間複雜度為O n
我們常用的排序氣泡排序 o n 2 快速排序o nlogn 堆排序o nlogn 選擇排序o n 2 我們常用的排序都不符合時間複雜度的要求 經常聽說乙個說法 用空間代替時間 現在要排序的陣列為陣列 a 例如a陣列裡面有 1,1,2,2,3,3,2,2,5,5.等等很多無序的數字 那麼我們申請乙個陣...
時間複雜度為on的排序演算法 理解演算法的時間複雜度
翻譯 瘋狂的技術宅 原文 https www.在電腦科學中,演算法分析是非常關鍵的部分。找到解決問題的最有效演算法非常重要。可能會有許多演算法能夠解決問題,但這裡的挑戰是選擇最有效的演算法。現在關鍵是假如我們有一套不同的演算法,應該如何識別最有效的演算法呢?在這裡演算法的空間和時間複雜度的概念出現了...