重談主定理(master定理)及其證明


參考文章:

【洛谷日報#33】時空復雜度分析及master定理

李卿. 遞歸算法分析中主定理的應用[J]. 黑龍江科技信息, 2011(29):97+207.

Thomas H.Cormen,Charles E.Leiserson,Ronald L.Rivest,Clifford Stein. 殷建平等譯. 算法導論第三版 [M]. 北京:機械工業出版社,2013,55-58.

前言:

本篇文章與我的 博客園 同步更新。

在此之前,請先閱讀 【洛谷日報#33】時空復雜度分析及master定理,其中關於時間復雜度表示的基礎知識不再闡述。

引出:

現在考慮一個問題:假設某算法的計算時間表示為遞歸式:

\[\begin{aligned}T(n)&=2T(\frac{n}{2})+n\log n\\T(1)&=1\end{aligned} \]

求該算法的時間復雜度。

當給你拋出這么一個題型時,你怎么辦?

憑經驗和感覺蒙

小幾率能蒙對,但你覺得這種題CCF會送你分嗎?

遞歸進去

像這樣遞歸進去:

\[\begin{aligned}T(n)&=2T(\frac{n}{2})+n\log n\\&=2\left(2T(\frac{n}{4})+\frac{n}{2}\log(\frac{n}{2})\right)+n\log n\\&=2\left(2\left(2T(\frac{n}{8})+\frac{n}{4}\log(\frac{n}{4})\right)+\frac{n}{2}\log(\frac{n}{2})\right)+n\log n\\&\cdots\end{aligned} \]

每項都 \(n\div 2\),總共遞歸 \(\log_2 n\) 層:

\[T(n)=\Theta\left(\log n\cdot(n\log n+n\log(\frac{n}{2})+n\log(\frac{n}{2^2})+\cdots+n\log(\frac{n}{2^{\log_2 n}}))\right) \]

\(T(n)=\Theta(n\log^2 n)\)

這么做不是沒有道理,但是如果 \(T(n)=3T(\frac{n}{4})+n\log n\),用這種方法根本算不出來(或許可以算出來,但是操作極其麻煩)。

主定理(master定理)求解

主定理:\(a,b\) 是常數,\(f(n)\) 為額外附加值函數\(T(n)\) 為遞歸式 \(T(n)=aT(\frac{n}{b})+f(n)\quad(a>0,b>1)\),就有:

  1. \(f(n)=\mathcal{O}(n^{(\log_ba)-\epsilon})\) 其中 \(\epsilon>0\) 是一個常數(相當於 \(\log_ba>f(n)\)),則有 \(T(n)=\Theta(n^{\log_ba})\)
  2. \(f(n)=\Theta(n^{\log_ba})\),則有 \(T(n)=\Theta(n^{\log_ba}\log n)\)
  3. \(f(n)=\Omega(n^{(\log_ba)+\epsilon})\) 其中 \(\epsilon>0\) 是一個常數(相當於 \(\log_ba<f(n)\)),且對於一個常數 \(c<1\) 和所有足夠大的 \(n\)\(af(\frac{n}{b})\leq cf(n)\)(這一條件在這里可以暫時忽略不看,但在證明時起到至關重要的作用),則有 \(T(n)=\Theta(f(n))\).
  4. \(f(n)=\Theta(n^{\log_ba}\log^kn)\) 其中 \(k\geq1\) 是一個常數,則有 \(T(n)=\Theta(n^{\log_ba}\log^{k+1}n)\)

這么看着有點枯燥乏味的樣子,不利於理解,但如果丟掉定理四的話(畢竟CSP/NOIp好像真的沒考過定理四,其實可以發現定理二和定理四其實是同一種,便於萌新理解就分開了),主定理的定義可以直接寫成:

圖一

(圖一)

也就是 \(n^{\log_ba}\)\(f(n)\) 進行比較!

圖一、算法導論和上面提過的論文沒有提到過定理四,但是原來那篇日報(#33)有,對此我想說,洛谷日報真是太好了!導論不行!日報行!(老伏拉夫了

舉例說明:

例一:\(T(n)=4T(\frac{n}{2})+n\),此時 \(a=4,b=2,\epsilon=1\),那么 \(\log_ba=\log_24=2,f(n)=\mathcal{O}(n^{\log_ba-\epsilon})=\mathcal{O}(n^{2-1})\)\(f(n)\) 成立,所以 \(T(n)=\Theta(n^{\log_ba})=\Theta(n^2)\)

例二:\(T(n)=2T(\frac{n}{2})+n\),此時 \(a=2,b=2\),那么 \(\log_ba=\log_22=1,f(n)=\Theta(n^{\log_ba})=\Theta(n)\)\(f(n)\) 成立,所以 \(T(n)=\Theta(n^{\log_ba}\log n)=\Theta(n\log n)\)

例三:\(T(n)=4T(\frac{n}{2})+n^3\),此時 \(a=4,b=2,\epsilon=1\),那么 \(\log_ba=\log_24=2,f(n)=\Omega(n^{\log_ba+\epsilon})=\Omega(n^{2+1})\),對於 \(c=\frac{2}{3}\) 和夠大的 \(n\)\(\left(af(\frac{n}{b})=4(\frac{n}{2})^3=4(\frac{n^3}{8})=\frac{n^3}{2}\right)\leq \left(cf(n)=\frac{2n^3}{3}\right)\)\(f(n)\) 成立,所以 \(T(n)=\Theta(f(n))=\Theta(n^3)\)

例四:\(T(n)=2T(\frac{n}{2})+n\log n\),此時 \(a=2,b=2,k=1\),那么 \(\log_ba=\log_22=1,f(n)=\Theta(n^{\log_ba}\log^kn)=\Theta(n\log n)\)\(f(n)\) 成立,所以 \(T(n)=\Theta(n^{\log_ba}\log^{k+1}n)=\Theta(n\log^2 n)\)

證明:

先聲明:證明又長又臭,有億點點難理解,學有余力的 dalao 可以來康康。

俗話說得好:“欲要證明master,就先畫棵遞歸樹”:

圖二

(圖二)

關於圖二的解釋及證明:

對於第 \(i\) 層(\(i\ne \log_bn\)),有 \(a^i\) 個節點,而每個節點的值是 \(f(\frac{n}{b^i})\),那么第 \(i\) 層總共的值是 \(a_if(\frac{n}{b^i})\)

對於第 \(\log_bn\) 層,有 \(a^{\log_bn}\) 個節點,而每個節點的時間復雜度是 \(\Theta(1)\),那么這一層總共的時間復雜度是 \(\Theta(a^{\log_bn})=\Theta(n^{\log_ba})\) 層。

對於 \(a^{\log_bn}=n^{\log_ba}\) 的證明:

\[\begin{aligned}a^{\log_bn}&=b^{{\log_ba}^{\log_bn}}\\&=b^{{\log_bn}^{\log_ba}}\\&=n^{\log_ba}\end{aligned} \]

\(a^{\log_bn}=n^{\log_ba}\) 得證。

這么看,圖二的遞歸樹的總時間復雜度為 \(T(n)=\Theta(n^{\log_ba})+\sum_{j=0}^{\log_bn-1}a^jf(\frac{n}{b^j})\),就是葉子節點層加上其它結點層的值。

證明*:

根據上文這個 \(T(n)\) 的時間復雜度,我們定義一個函數 \(g(n)\)

\[g(n)=\sum_{j=0}^{\log_bn-1}a^jf(\frac{n}{b^j}) \]

這個 \(g(n)\) 有一些性質:

  1. \(f(n)=\mathcal{O}(n^{(\log_ba)-\epsilon})\) 其中 \(\epsilon>0\) 是一個常數,則有 \(g(n)=\mathcal{O}(n^{\log_ba})\)
  2. \(f(n)=\Theta(n^{\log_ba})\) 時,則有 \(g(n)=\Theta(n^{\log_ba}\log n)\)
  3. \(f(n)=\Omega(n^{(\log_ba)+\epsilon})\) 其中 \(\epsilon>0\) 是一個常數,且對於一個常數 \(c<1\) 和所有足夠大的 \(n\)\(af(\frac{n}{b})\leq cf(n)\),則有 \(g(n)=\Theta(f(n))\).
  4. \(f(n)=\Theta(n^{\log_ba}\log^kn)\) 其中 \(k\geq1\) 是一個常數,則有 \(g(n)=\Theta(n^{\log_ba}\log^{k+1}n)\)

欸!有沒有發現好像在哪見過!那是因為這是我從上文復制下來的(

證明關於g函數性質*:

性質 1:

\(f(n)=\mathcal{O}(n^{(\log_ba)-\epsilon})\) 代入進 \(g(n)=\sum_{j=0}^{\log_bn-1}a^jf(\frac{n}{b^j})\)

\[\begin{aligned}g(n)&=\mathcal{O}\left(\sum_{j=0}^{\log_bn-1}a^j(\frac{n}{b^j})^{(\log_ba)-\epsilon}\right)\\&=\mathcal{O}\left(\sum_{j=0}^{\log_bn-1}a^j(\frac{n^{(\log_ba)-\epsilon}}{b^{j^{(\log_ba)-\epsilon}}})\right)\\&=\mathcal{O}\left(\sum_{j=0}^{\log_bn-1}n^{(\log_ba)-\epsilon}(\frac{a^j}{b^{j^{(\log_ba)-\epsilon}}})\right)\\&=\mathcal{O}\left(n^{(\log_ba)-\epsilon}\sum_{j=0}^{\log_bn-1}(\frac{a}{b^{(\log_ba)-\epsilon}})^j\right)\\&=\mathcal{O}\left(n^{(\log_ba)-\epsilon}\sum_{j=0}^{\log_bn-1}(\frac{ab^\epsilon}{a})^j\right)\\&=\mathcal{O}\left(n^{(\log_ba)-\epsilon}\sum_{j=0}^{\log_bn-1}(b^\epsilon)^j\right)\end{aligned} \]

然后根據等比數列求和公式化簡 \(\sum_{j=0}^{\log_bn-1}(b^\epsilon)^j\)

\[\begin{aligned}g(n)&=\mathcal{O}\left(n^{(\log_ba)-\epsilon}(\frac{b^{\epsilon\log_bn}-1}{b^{\epsilon}-1})\right)\\&=\mathcal{O}\left(n^{(\log_ba)-\epsilon}(\frac{n^{\epsilon}-1}{b^{\epsilon}-1})\right)\end{aligned} \]

這里回想一下 \(b,\epsilon\) 的定義,(做到不忘初心牢記使命),它們是常數,所以式子中 \(\frac{1}{b^{\epsilon}-1}\) 也是常數,應忽略:

\[\begin{aligned}g(n)&=\mathcal{O}\left(n^{(\log_ba)-\epsilon}\cdot n^{\epsilon}\right)\\&=\mathcal{O}(n^{\log_ba})\end{aligned} \]

性質 1 得證。

性質 2:

性質 1 和性質 2 操作一樣,就是一直代入再一直化簡,將 \(f(n)=\Theta(n^{\log_ba})\) 代入進 \(g(n)=\sum_{j=0}^{\log_bn-1}a^jf(\frac{n}{b^j})\)

\[\begin{aligned}g(n)&=\Theta\left(\sum_{j=0}^{\log_bn-1}a^j\left(\frac{n}{b^j}\right)^{\log_ba}\right)\\&=\Theta\left(\sum_{j=0}^{\log_bn-1}a^j\left(\frac{n^{\log_ba}}{b^{j^{\log_ba}}}\right)\right)\\&=\Theta\left(n^{\log_ba}\sum_{j=0}^{\log_bn-1}\left(\frac{a^j}{b^{j^{\log_ba}}}\right)\right)\\&=\Theta\left(n^{\log_ba}\sum_{j=0}^{\log_bn-1}\left(\frac{a}{b^{\log_ba}}\right)^j\right)\\&=\Theta\left(n^{\log_ba}\sum_{j=0}^{\log_bn-1}1\right)\\&=\Theta\left(n^{\log_ba}\log_bn\right)\end{aligned} \]

注意:這里重頭戲來了!式子中的 \(\log_bn\) 是可以直接改底數的,因為可以通過換底公式得到對數函數都是同級的。因此我們可以把 \(b\) 改成 \(2\)(即 \(\log_bn\) 化成 \(\log n\)):

\[g(n)=\Theta\left(n^{\log_ba}\log n\right) \]

性質 2 得證。

性質 3:

性質 3 是最特殊的,用 \(af(\frac{n}{b})\leq cf(n)\) 遞歸 \(j\) 次可以得到 \(a^j f(\frac{n}{b^j})\leq c^j f(n)\)。再用這個式子套 \(g(n)\) 定義:

\[\begin{aligned}g(n)\leq\sum_{j=0}^{\log_bn-1}c^jf(n)&\Rightarrow g(n)\leq f(n)\sum_{j=0}^{\log_bn-1}c^j\\&\Rightarrow g(n)\leq f(n)\sum_{j=0}^{\infty}c^j\end{aligned} \]

解釋一下上面的式子,因為 \(c\) 都是正數,所以如果 \(g(n)\leq f(n)\sum_{j=0}^{\log_bn-1}c^j\),顯然 \(g(n)\leq f(n)\sum_{j=0}^{\infty}c^j\)。而這么做是為了更好證明。

接下來還是用等比數列求和公式化簡:

\[\begin{aligned}g(n)\leq f(n)\sum_{j=0}^{\infty}c^j\Rightarrow g(n)\leq\left(\frac{1}{1-c}\right)f(n)\end{aligned} \]

你可能好奇這個等比數列求和是怎么化的,下面證明一下:

\(S=c^0+c^1+c^2+\cdots+c^{\infty}\) 表示 \(\sum_{j=0}^{\infty}c^j\),此時公比為 \(c\)

\(cS=c^1+c^2+c^3+\cdots+c^{\infty}\),這里 \(\infty+1=\infty\)

\((1-c)S=c^0=1\)

\(S=\frac{1}{1-c}\)

\(\sum_{j=0}^{\infty}c^j=\frac{1}{1-c}\)

回到題目,由 \(g(n)\leq\left(\frac{1}{1-c}\right)f(n)\) 得到 \(g(n)=\mathcal{O}(f(n))\)

而根據 \(g(n)\) 的定義 \(g(n)=f(n)+af(\frac{n}{b})+a^2f(\frac{n}{b^2})+\cdots+a^{\log_bn-1}f(\frac{n}{b^{\log_bn-1}})\geq f(n)\),得到 \(g(n)=\Omega(f(n))\)

所以 \(g(n)=\Theta(f(n))\)

性質 3 得證。

性質 4:

老套路,將 \(f(n)=\Theta(n^{\log_ba}\log^kn)\) 代入進 \(g(n)=\sum_{j=0}^{\log_bn-1}a^jf(\frac{n}{b^j})\)

\[\begin{aligned}g(n)&=\Theta\left(\sum_{j=0}^{\log_bn-1}a^j\left(\frac{n}{b^j}\right)^{\log_ba}\log^k\left(\frac{n}{b^j}\right)\right)\\&=\Theta\left(\sum_{j=0}^{\log_bn-1}a^j\left(\frac{n^{\log_ba}}{b^{j^{\log_ba}}}\right)\left(\log n-\log b^j\right)^k\right)\\&=\Theta\left(n^{\log_ba}\sum_{j=0}^{\log_bn-1}\left(\frac{a^j}{b^{j^{\log_ba}}}\right)\left(\log^k n-\log^k b^j\right)\right)\\&=\Theta\left(n^{\log_ba}\sum_{j=0}^{\log_bn-1}\left(\frac{a}{b^{\log_ba}}\right)^j\left(\log^k n-\log^k b^j\right)\right)\\&=\Theta\left(n^{\log_ba}\sum_{j=0}^{\log_bn-1}\log^k n-\log^k b^j\right)\\&=\Theta\left(n^{\log_ba}\left(\log_bn\cdot\log^k n-\sum_{j=0}^{\log_bn-1}\log^k b^j\right)\right)\\&=\Theta\left(\log_bn\cdot\log^k n\cdot n^{\log_ba}-n^{\log_ba}\sum_{j=0}^{\log_bn-1}\log^k b^j\right)\end{aligned} \]

和性質 2 一樣: \(\log_bn\) 可以直接化為 \(\log n\)。然后 \(-n^{\log_ba}\sum_{j=0}^{\log_bn-1}\log^k b^j\) 是一個負數,在時間復雜度的表示中可以忽略,所以得到:

\[\begin{aligned}g(n)&=\Theta\left(n^{\log_ba}\log^{k+1}n\right)\end{aligned} \]

性質 4 得證。

主定理總時間復雜度證明:

回到圖二的總時間復雜度 \(T(n)=\Theta(n^{\log_ba})+\sum_{j=0}^{\log_bn-1}a^jf(\frac{n}{b^j})\)

\(f(n)=\mathcal{O}(n^{(\log_ba)-\epsilon})\) 時:

\[\begin{aligned}T(n)&=\Theta(n^{\log_ba})+\sum_{j=0}^{\log_bn-1}a^jf(\frac{n}{b^j})\\&=\Theta(n^{\log_ba})+g(n)\\&=\Theta(n^{\log_ba})+\mathcal{O}(n^{\log_ba})\\&=\Theta(n^{\log_ba})\end{aligned} \]

\(f(n)=\Theta(n^{\log_ba})\) 時:

\[\begin{aligned}T(n)&=\Theta(n^{\log_ba})+\sum_{j=0}^{\log_bn-1}a^jf(\frac{n}{b^j})\\&=\Theta(n^{\log_ba})+g(n)\\&=\Theta(n^{\log_ba})+\Theta(n^{\log_ba}\log n)\\&=\Theta(n^{\log_ba}\log n)\end{aligned} \]

\(f(n)=\Omega(n^{(\log_ba)+\epsilon})\),且對於一個常數 \(c<1\) 和所有足夠大的 \(n\)\(af(\frac{n}{b})\leq cf(n)\)

\[\begin{aligned}T(n)&=\Theta(n^{\log_ba})+\sum_{j=0}^{\log_bn-1}a^jf(\frac{n}{b^j})\\&=\Theta(n^{\log_ba})+g(n)\\&=\Theta(n^{\log_ba})+\Theta(f(n))\\&=\Theta(f(n))\end{aligned} \]

\(f(n)=\Theta(n^{\log_ba}\log^kn)\) 時:

\[\begin{aligned}T(n)&=\Theta(n^{\log_ba})+\sum_{j=0}^{\log_bn-1}a^jf(\frac{n}{b^j})\\&=\Theta(n^{\log_ba})+g(n)\\&=\Theta(n^{\log_ba})+\Theta(n^{\log_ba}\log^{k+1}n)\\&=\Theta(n^{\log_ba}\log^{k+1} n)\end{aligned} \]

主定理證畢。

后記 & 感謝名單:

在這篇文章證明的主定理只是對於 \(b\) 的冪下的,就是說向上、向下取整的沒有證明,但要證明這些實在太難了,要花費更長的時間 (主要還是懶

我在查找資料的時候發現還有一種定理——Akra-Bazzi定理(打開要梯子)也是時間復雜度的。

感謝名單(排名不分先后):

@stoorz

@bruteforce_

@SSL_TJH_蒟蒻

@RABU


免責聲明!

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



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