求解遞歸式,計算時間復雜度


方法一:代換法

代換法主要需要以下兩個步驟

1、  猜答案,不需要完全猜出來,不需要知道常熟系數的准確值,而只需要猜出它的形式,比如猜一個遞歸式的時間復雜度大概是O(n2),即它的運行時間應該是一個常熟乘以n2,可能還會有一些低階項。

2、  用數學歸納法證明之,設法求出常數系數可以使問題成立

例如 T(n)= 4T(n/2) +n , [T(1) = O(1)]

通過觀察該遞歸式,注意到當n加倍時,輸出增加4倍,於是猜測該遞歸式時間復雜度為O(n2),即T(n) = O(n2) 。不過直接證明時間復雜度是n2有點困難,可以先從一個更簡單的開始,比如猜測它的時間復雜度是n3,下面用歸納法證明它。

很顯然在n=1的時候是成立的,只需要一個比較大的常數就夠了。

在用歸納法證明過程中是不能使用O符號的,所以需要用常熟系數展開它,

假設T(k) ≤ ck3 (k<n) ,帶入上面遞歸式,得到

T(n) ≤ 4c(n/2)3 + n = 1/2cn3+n = cn3-(1/2cn3-n)≤cn3 如果cn3-n≥0

可以看到當c≥1,n≥1的時候,該不等式是成立的,即T(n)小於等於一個常數乘以n3,只需要該常數大於等於1,這樣就得到了一個上界,但不是嚴格意義上的上界,因為我們覺得對於n2它也應該是成立的,下面開始證明n2的情況,於是抄襲上面的步驟再來一次,得到

T(k) ≤ ck2(k<n)

T(n) ≤ 4c(n/2)2 + n =cn2+n= cn2-(-n) 這兒無法得到T(n) ≤cn2 ,假設是錯的?囧,看樣子假設里需要一個低階項,於是繼續假設

T(k) ≤ c1k2-c2k(k<n)

T(n) ≤4[c1(n/2)2-c2(n/2)]+n=c1n2+(1-2c2)n = c1n2-c2n-(c2-1)n≤c1n2-c2n 如果c2≥1

這樣就證明了,對於任意的c1,只要c2大於等於1,那么不等式就成立。但事實上,當n=1的時候,要求c1>c2,不等式才能成立,因此c1要盡可能的大,至少要比c2大。


 

方法二:遞歸樹法

遞歸樹法主要是通過遞歸樹將遞歸式展開來找到答案,然后再用代換法證明它,因為遞歸樹法是不嚴謹的。

例如,用遞歸樹法求T(n) = T(n/2) + n2 , 用遞歸樹法將該遞歸式展開

像這樣將遞歸樹展開並延伸下去,最終到葉子節點就只剩下T(1),那么該遞歸樹的高度就是logn,因為從頂點n出發,到n/2,到n/4,……最后到1,那么從n到1的折半次數是logn,即高度是logn(應該是一個常數乘以logn,不過沒多大關系)。而最下面葉子節點的數目是n,因為從第一層往下,節點數變化為1,2,4,8……,如果樹的高度是h,那么就會有2h個葉節點,而高度是logn,那么2logn=n。那么,整體所做的工作加起來就是T(n)了

T(n) = [1+1/2+1/4+……]n2 = 2n2,於是可知時間復雜度為T(n) = O(n2)。

再例如,用遞歸樹法求T(n) = T(n/4)+T(n/2)+n2 ,下面用遞歸樹的方法將該遞歸式展開

最后,求葉子節點的數目有點麻煩,因為分支的遞歸速度是不一樣的,左邊降低到n/16的時候,右邊才降低到n/4,左邊子樹的高度將會比右邊子樹的高度要小。可以看到葉子節點的數目必然小於n,因為最開始的問題大小是n,然后遞歸成一個n/4和n/2的兩個子問題,直到最后遞歸到1停止,而n/4+n/2 < n , 所以最后葉子節點的數目不會超過n,將每層求和就得到T(n),經過觀察發現一個等比數列,於是數學歸納法開始派上用場

T(n) = (1+5/16+25/256+……)n2≤2n2 = O(n2)   於是得到該遞歸式時間復雜度為O(n2),因為是猜出來的等比數列,於是需要用數學歸納法證明之,就又變成方法一中代換法求證了。


方法三:主方法 (master method)

該方法僅適用於特定格式的遞歸式

同時要求f(n)漸進趨正,即當n->無窮時,f(n)>0。(我覺得上圖中第2,3中少了個logn,具體請參考算法導論一書中對時間復雜度的討論)

例如:

T(n)=4T(n/2)+n , 則a=4,b=2,f(n)=n,計算nlog(b,a)=n2>f(n) , 滿足模式一,因此T(n) = nlog(b,a)=O(n2)

T(n)=4T(n/2)+n2,則根據上面計算,滿足模式二,因此T(n)=O(n2logn)

T(n)=4T(n/2)+n3,滿足模式三,T(n)=O(n3)

對於該方法的正確性,可以通過遞歸樹的方法證明,懶的畫了,可以在大腦里構思出這樣一個草圖:

在第一層,f(n)分解為a個子問題,每個子問題都是f(n/b),第二層每個子問題又分解為a個子問題,每個問題都是f(n/b2)……這樣遞歸分解下去,最后的葉子還是O(1),整個樹的高度就是log以b為底n的對數,整個的葉子節點數目為a的log以b為底n的對數次方(alog(b,n)),即nlog(b,a)個葉子節點。每個分支的遞減速度是一樣的,將每層都加在一起便得到T(n) ,此時就需要對f(n)的情況進行討論(於是就是上面的1,2,3)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM