[英]Solving a Recurrence Relation: T(n)=T(n-1)+T(n/2)+n
求解: T(n)=T(n-1)+T(n/2)+n 。
我嘗試使用遞歸樹解決這個問題。分別有兩個分支T(n-1)
和T(n/2)
。 T(n-1)
將進入更高的深度。 所以我們得到O(2^n)
。 這個想法正確嗎?
對於CS類來說,這是一個非常奇怪的重復。 這是因為從一個角度來看: T(n) = T(n-1) + T(n/2) + n
大於T(n) = T(n-1) + n
,即 O(n ^2)。
但從另一個角度來看,函數方程有一個精確解: T(n) = -2(n + 2)
。 通過將其代入方程,您可以輕松看出這是精確解: -2(n + 2) = -2(n + 1) + -(n + 2) + n
。 我不確定這是否是唯一的解決方案。
我是這樣得到的: T(n) = T(n-1) + T(n/2) + n
。 因為您為非常大的n
計算事物,所以n-1
幾乎與n
相同。 所以你可以把它改寫為T(n) = T(n) + T(n/2) + n
即T(n/2) + n = 0
,它等於T(n) = - 2n
,所以它是線性的。 這對我來說是違反直覺的(這里是減號),但是有了這個解決方案,我嘗試了T(n) = -2n + a
並找到了 a 的值。
我相信你是對的。 遞推關系總是分成兩部分,即 T(n-1) 和 T(n/2)。 看看這兩個,很明顯 n-1 的值下降比 n/2 慢,或者換句話說,你將從樹的 n-1 部分有更多的分支。 盡管如此,在考慮 big-o 時,只考慮“最壞情況”是有用的,在這種情況下,樹的兩邊都減少了 n-1(因為這減少得更慢,您需要有更多的分支)。 總之,您需要將關系一分為二,總共 n 次,因此您說 O(2^n) 是正確的。
你的推理是正確的,但你放棄的太多了。 (例如,說2x^3+4=O(2^n)
也是正確的,但這不像2x^3+4=O(x^3)
。)
我們要做的第一件事是去掉非齊次項n
。 這表明我們可以尋找形式為T(n)=an+b
。 將其代入,我們發現:
an+b = a(n-1)+b + an/2+b + n
這減少到
0 = (a/2+1)n + (b-a)
暗示a=-2
和b=a=-2
。 因此, T(n)=-2n-2
是方程的解。
我們現在想通過減去我們已經找到的解決方案來找到其他解決方案。 讓我們定義U(n)=T(n)+2n+2
。 那么方程變為
U(n)-2n-2 = U(n-1)-2(n-1)-2 + U(n/2)-2(n/2)-2 + n
這減少到
U(n) = U(n-1) + U(n/2).
U(n)=0
是這個方程的一個明顯解,但是這個方程的非平凡解是如何表現的呢?
讓我們假設U(n)∈Θ(n^k)
對於某些k>0
,因此U(n)=cn^k+o(n^k)
。 這使得方程
cn^k+o(n^k) = c(n-1)^k+o((n-1)^k) + c(n/2)^k+o((n/2)^k)
現在, (n-1)^k=n^k+Θ(n^{k-1})
,所以上面變成
cn^k+o(n^k) = cn^k+Θ(cn^{k-1})+o(n^k+Θ(n^{k-1})) + cn^k/2^k+o((n/2)^k)
吸收低階項並減去公共cn^k
,我們得到
o(n^k) = cn^k/2^k
但這是錯誤的,因為右側比左側增長得更快。 因此, U(n-1)+U(n/2)
比U(n)
U(n-1)+U(n/2)
增長得更快,這意味着U(n)
必須比我們假設的Θ(n^k)
增長得更快。 因為這對於任何k
都是正確的,所以U(n)
必須比任何多項式增長得更快。
指數函數是一個比任何多項式增長都快的例子。 因此,讓我們假設U(n)∈Θ(c^n)
對於某些c>1
,因此U(n)=ac^n+o(c^n)
。 這使得方程 ac^n+o(c^n) = ac^{n-1}+o(c^{n-1}) + ac^{n/2}+o(c^{n/2 }) 重新排列並使用一些增長數學的順序,這變成
c^n = o(c^n)
這是錯誤的(再次),因為左側比右側增長得更快。 因此, U(n)
增長速度比U(n-1)+U(n/2)
快,這意味着U(n)
增長速度必須比我們假設的Θ(c^n)
慢。 由於這對於任何c>1
都是正確的,因此U(n)
必須比任何指數增長得更慢。
這使我們進入了擬多項式領域,其中ln U(n)∈O(log^cn)
和子指數,其中ln U(n)∈O(n^ε)
。 其中任何一個都意味着我們要查看L(n):=ln U(n)
,其中前面的段落暗示L(n)∈ω(ln n)∩o(n)
。 取方程的自然對數,我們有
ln U(n) = ln( U(n-1) + U(n/2) ) = ln U(n-1) + ln(1+ U(n/2)/U(n-1))
或者
L(n) = L(n-1) + ln( 1 + e^{-L(n-1)+L(n/2)} ) = L(n-1) + e^{-(L(n-1)-L(n/2))} + Θ(e^{-2(L(n-1)-L(n/2))})
所以一切都歸結為: L(n-1)-L(n/2)
增長的速度有多快? 我們知道L(n-1)-L(n/2)→∞
,否則L(n)∈Ω(n)
。 並且L(n)-L(n/2)
可能同樣有用,因為L(n)-L(n-1)∈o(1)
遠小於L(n-1)-L(n/2)
。
不幸的是,這是我能夠解決的問題。 我沒有看到一個很好的方法來控制L(n)-L(n/2)
增長的速度(而且我幾個月來一直盯着這個)。 我唯一能結束的就是引用另一個答案:“CS 類的一個非常奇怪的遞歸”。
我覺得我們可以這樣看:
T(n)=2T(n/2)+n < T(n)=T(n−1)+T(n/2)+n < T(n)=2T(n−1)+n
如果我們應用大師定理,那么:
Θ(n∗logn) < Θ(T(n)) < Θ(2n)
請記住, T(n) = T(n-1) + T(n/2) + n
(漸近)大於T(n) = T(n-1) + n
僅適用於漸近正函數。 在這種情況下,我們有T = Ω(n^2)
。
請注意, T(n) = -2(n + 2)
是函數方程的解,但我們不感興趣,因為它不是漸近正解,因此 O 的符號沒有有意義的應用.
您還可以輕松檢查T(n) = O(2^n)
。 (如果需要,請參閱 yyFred 解決方案)
如果您嘗試對n^a(lgn)^b
類型的函數使用 O 的定義,其中a(>=2)
和b
正常數,您會發現這不是替代方法的可能解決方案。
事實上,唯一允許用替換方法證明的函數是指數函數,但我們知道這種遞歸的增長速度不如T(n) = 2T(n-1) + n
,所以如果T(n) = O(a^n)
,我們可以有a < 2
。
假設T(m) <= c(a^m)
,對於一些常數 c,實數和正數。 我們的假設是這種關系對所有 m < n 都有效。 試圖為 n 證明這一點,我們得到:
T(n) <= (1/a+1/a^(n/2))c(a^n) + n
我們可以通過將假設更改為低階項來輕松擺脫 n。 這里重要的是:
1/a+1/a^(n/2) <= 1
a^(n/2+1)-a^(n/2)-a >= 0
改變變量:
a^(N+1)-a^N-a >= 0
我們希望找到盡可能緊密的結合,因此我們正在尋找盡可能低的a
。 我們上面找到的不平等接受的解決方案, a
它是相當接近1,但a
允許獲得任意接近1? 答案是否定的,讓a
的形式為a = (1+1/N)
。 將a
代入不等式並應用極限N -> INF
:
e-e-1 >= 0
這是荒謬的。 因此,上面的不等式有一些固定數N*
作為最大解,可以通過計算找到。 一個快速的 Python 程序讓我發現a < 1+1e-45
(有一點外推),所以我們至少可以確定:
T(n) = ο((1+1e-45)^n)
T(n)=T(n-1)+T(n/2)+n
與T(n)=T(n)+T(n/2)+n
因為我們正在求解非常大的值的 T(n)=T(n)+T(n/2)+n
只有在T(n/2) + n = 0
才能為真。 這意味着T(n) = T(n) + 0 ~= O(n)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.