簡體   English   中英

如何求解:T(n) = T(n/2) + T(n/4) + T(n/8) + (n)

[英]How to solve: T(n) = T(n/2) + T(n/4) + T(n/8) + (n)

我知道如何為只調用自己一次的算法做遞歸關系,但我不確定如何做一次多次調用自己的事情。

例如:

T(n) = T(n/2) + T(n/4) + T(n/8) + (n)

使用遞歸樹。 請參閱 CLRS“算法簡介”中遞歸樹的最后一個示例。

T(n) = T(n/2) + T(n/4) + T(n/8) + n。 根將是 n(cost) & 分為 3 個遞歸。 所以遞歸樹如下所示:

T(n) = n = n T(n/2)T(n/4)T(n/8) (n/2) (n/4) (n/8) T(n/4)T(n /8)T(n/16) T(n/8)T(n/16)T(n/32) T(n/16)T(n/32)T(n/64)

                                             n---------------------------------> n      

                             (n/2)         (n/4)           (n/8)--------------> (7/8)n

                         n/4 n/8 n/16  n/8 n/16 n/32  n/16 n/32 n/64)--------> (49/64)n
                                            ...         

最長路徑:最左邊的左分支 = n -> n/2 -> n/4 -> ... -> 1

最短分支:最右邊的右分支 = n -> n/8 -> n->64 -> ... -> 1

葉子數(l):3^log_8(n) < l < 3^log_2(n) => n^0.5 < l < n^1.585

看看樹 - 到 log_8(n) 層,樹已經滿了,然后隨着我們往下走,越來越多的內部節點不存在。 根據這個理論,我們可以給出界限,

T(n) = Big-Oh(總和 j=0 到 log_2(n)-1 (7/8)^jn) = ... => T(n) = O(n)。 T(n) = Big-Omega(總和 j=0 到 log_8(n)-1 (7/8)^jn) = ... => T(n) = Big-Omega(n)。

因此,T(n) = Theta(n)。

這里的要點是:T(n/2) 路徑的長度最長......

這一定不是一個完整的三叉樹...高度 = n 的對數基數 2 & # 的葉子必須小於 n ...

希望,可能這樣你可以解決問題。

有兩種方法可以解決這個問題。 一種是展開遞歸並找到相似之處,這可能需要創造性並且非常困難。 另一種方法是使用Akra-Bazzi 方法

在這種情況下, g(x) = na1 = a2 = a3 = 1b1 = 1/2b2 = 1/4b3 = 1/8 求解方程

在此處輸入圖片說明

1/2^p + 1/4^p + 1/8^p = 1你得到p = 0.87915 解決積分你會得到在此處輸入圖片說明 ,這意味着復雜度為: O(n)

請參閱圖片以獲得更好的解釋-

在此處輸入圖片說明

樹的高度:我們采用 log(n)(base 2),因為與 n/4 和 n/8 相比,n/2 使樹更長。 我們的 GP 系列將一直持續到 k=logn(base)。

正如CLRS所說, T(n)可以通過數學歸納法替換為cn 這個歸納假設適用於n以下的數字。 如上所述,我們需要證明的是參數值為n。 因此,如下: 假設: T(n) <= cn對於小於n的數; 得出結論:

T(n) = T(n/2) + T(n/4) + T(n/8) + n
    <= c/2*n + c/4*n + c/8*n + n
     = (7/8*c + 1) * n
    <= cn (when c >= 8)

就這樣。

就像編寫斐波那契數列(困難的方式)作為示例一樣,您只需鍵入以下內容:

 long fib(long n){ if(n <= 1) return n; else return fib(n-1) + fib(n-2); }

或者,更好的是,使用全局變量記住它以使其更快。 再一次,使用斐波那契數列:

 static ArrayList<Long>fib_global = new ArrayList(1000); //delcare a global variable that can be appended to long fib(long n){ if(n >= fib_global.length)fib_global.add(fib(n-1) + fib(n-2)); return fib_global.get(n); }

代碼一次只會執行其中一個調用,並且很可能按照您輸入的從左到右的順序,這樣您就不必擔心需要執行的次數叫什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM