前言

虽说在学OI的时候学到了非常多的有递归结构的算法或方法,也很清楚他们的复杂度,但更多时候只是能够大概脑补这些方法为什么是这个复杂度,而从未从定理的角度去严格证明他们。因此借着这个机会把主定理整个梳理一遍。

介绍

主定理(Master Theorem)提供了用于分析一类有递归结构算法时间复杂度的方法。这种递归算法通常有这样的结构:

def solve(problem):
solve_without_recursion()
for subProblem in problem:
solve(subProblem)

我们可以用一种表示方式来概括这些结构的算法:对于一个规模为\(n\)的问题,我们把它分为\(a\)个子问题,每个子问题规模为\(\frac nb\)。那么这种方法的复杂度\(T(n)\)可以表示为:

\[T(n)=a\,T\Big(\frac nb\Big)+f(n)
\]

其中\(a\ge 1,b>1\)为常数,\(\frac{n}{b}\)指\(\lfloor \frac{n}{b}\rfloor\)或\(\lceil \frac{n}{b}\rceil\),\(f(n)\)为创造这些递归或者将这些子问题结果整合的函数。对这个方法我们可以建一个递归树:

其中树高为\(\log_bn\),树的第\(i\)层有\(a^i\)个节点,每个节点的问题规模为\(\frac{n}{b^i}\)。则这棵树有\(a^{\log_bn}=n^{\log_ba}\)个叶子节点。因此这种方法的复杂度也可以表示为:

\[T(n)=\Theta(n^{\log_ba})+\sum_{i=0}^{\log_bn-1}a^if\Big(\frac{n}{b^i}\Big)
\]

从中我们可以看出,整个方法的复杂度取决于\(f(n)\)的复杂度。主定理对\(f(n)\)分了三种情况:

  1. \(\exist \varepsilon>0\ s.t.\ f(n)=O(n^{\log_ba-\varepsilon})\)。此时\(T(n)=\Theta(n^{\log_ba})\)。
  2. \(f(n)=\Theta(n^{\log_ba})\)。此时\(T(n)=\Theta(n^{\log_ba}\lg n)\)。
  3. \(\exist \varepsilon>0\ s.t.\ f(n)=\Omega(n^{\log_ba+\varepsilon})\),且\(\exist c<1\),当\(n\)足够大时,有\(a\, f(\frac{n}{b})\le c\, f(n)\)。此时\(T(n)=\Theta(f(n))\)。

\(f(n)\)含\(\log\)的情况类似,待补充。

证明

Case 1

令\(g(n)=\sum_{i=0}^{\log_bn-1}a^if(\frac{n}{b^i})\),由\(f(n)=O(n^{\log_ba-\varepsilon})\),得:

\[g(n)=O\Big(\sum_{i=0}^{\log_bn-1}a^i\Big(\frac{n}{b^i}\Big)^{\log_ba-\varepsilon}\Big)
\]

之后就是对后面式子的化简:

\[\begin{aligned}
\sum_{i=0}^{\log_bn-1}a^i\Big(\frac{n}{b^i}\Big)^{\log_ba-\varepsilon} &= n^{\log_ba-\varepsilon}\sum_{i=0}^{\log_bn-1}\Big(\frac{ab^\varepsilon}{b^{\log_ba}}\Big)^i\\
&= n^{\log_ba-\varepsilon}\sum_{i=0}^{\log_bn-1}(b^\varepsilon)^i\\
&= n^{\log_ba-\varepsilon}\Big(\frac{(b^\varepsilon)^{\log_bn}-1}{b^\varepsilon-1}\Big)^i\\
&= n^{\log_ba-\varepsilon}\Big(\frac{n^\varepsilon-1}{b^\varepsilon-1}\Big)^i
\end{aligned}
\]

因此\(g(n)=O(\sum_{i=0}^{\log_bn-1}a^i(\frac{n}{b^i})^{\log_ba-\varepsilon})=O(n^{\log_ba})\)。所以有:

\[T(n)=\Theta(n^{\log_ba})+O(n^{\log_ba})=\Theta(n^{\log_ba})
\]

Case 2

同Case 1。令\(g(n)=\sum_{i=0}^{\log_bn-1}a^if(\frac{n}{b^i})\)得:

\[g(n)=\Theta\Big(\sum_{i=0}^{\log_bn-1}a^i\Big(\frac{n}{b^i}\Big)^{\log_ba}\Big)
\]

继续化简:

\[\begin{aligned}
\sum_{i=0}^{\log_bn-1}a^i\Big(\frac{n}{b^i}\Big)^{\log_ba} &= n^{\log_ba}\sum_{i=0}^{\log_bn-1}\Big(\frac{a}{b^{\log_ba}}\Big)^i\\
&= n^{\log_ba}\log_bn
\end{aligned}
\]

因此可得\(g(n)=n^{\log_ba}\log_bn=n^{\log_ba}\lg n\)。所以有:

\[T(n)= \Theta(n^{\log_ba})+\Theta(n^{\log_ba}\lg n)=\Theta(n^{\log_ba}\lg n)
\]

Case 3

还是令\(g(n)=\sum_{i=0}^{\log_bn-1}a^if(\frac{n}{b^i})\)。但Case 3这里有一个条件:\(a\, f(\frac{n}{b})\le c\, f(n)\)。我们对这个条件做一下处理:

\[\begin{aligned}
a\, f\Big(\frac{n}{b}\Big) &\le c\, f(n)\\
\Rightarrow f\Big(\frac{n}{b}\Big) &\le \frac{c}{a}f(n)\\
\Rightarrow f\Big(\frac{n}{b^2}\Big) &\le \frac{c}{a}f\Big(\frac nb\Big)\le\Big(\frac{c}{a}\Big)^2f(n)\\
&\vdots\\
f\Big(\frac{n}{b^i}\Big) &\le\Big(\frac{c}{a}\Big)^if(n)\\
\Rightarrow a^i\, f\Big(\frac{n}{b^i}\Big) &\le c^i\, f(n)\\
\end{aligned}
\]

由此我们可以很轻易的向下化简:

\[\begin{aligned}
\sum_{i=0}^{\log_bn-1}a^i\Big(\frac{n}{b^i}\Big)^{\log_ba} &\le \sum_{i=0}^{\log_bn-1}c^i\,f(n)+O(1)\\
&\le f(n)\sum_{i=0}c^i+O(1)\\
&=f(n)\Big(\frac{1}{1-c}\Big)+O(1)\\
&=f(n)
\end{aligned}
\]

得\(g(n)=O(f(n))\)。又因为\(g(n)=\sum_{i=0}^{\log_bn-1}a^if(\frac{n}{b^i})\ge f(n)\),得\(g(n)=\Omega(f(n))\)。因此\(g(n)=\Theta(f(n))\)。

所以有:

\[T(n)=\Theta(n^{\log_ba})+\Theta(f(n))=\Theta(f(n))
\]

证毕。

应用

二叉树建树

\[T(n)=2T\Big(\frac{n}{2}\Big)+O(1),\ T(n)=O(n)
\]

此时\(\log_ba<1\),满足Case 1。

BFPRT(Median of Medians)

\[T(n)\le T\Big(\frac{n}{5}\Big)+\Big(\frac{7n}{10}\Big)+O(n),\ T(n)=O(n)
\]

此时\(\log_ba>1\),即划分之后总规模减小(\(1/5+7/10<1\)),满足Case 2。

归并排序

\[T(n)=2T\Big(\frac{n}{2}\Big)+O(n),\ T(n)=O(\lg n)
\]

此时\(\log_ba=1\),满足Case 3。

对主定理(Master Theorem)的理解的更多相关文章

  1. 算法设计与分析 - 主定理Master theorem (分治法递推时间复杂度)

    英文原版不上了 直接中文 定义 假设有递推关系式T(n)=aT(n/b)+f(n) 其中n为问题规模 a为递推的子问题数量 n/b为每个子问题的规模(假设每个子问题的规模基本一样) f(n)为递推以外 ...

  2. 主定理(Master Theorem)与时间复杂度

    1. 问题 Karatsuba 大整数的快速乘积算法的运行时间(时间复杂度的递推关系式)为 T(n)=O(n)+4⋅T(n/2),求其最终的时间复杂度. 2. 主定理的内容 3. 分析 所以根据主定理 ...

  3. 重新粗推了一下Master Theorem

    主定理一般形式是T(n) = a T(n / b) + f(n), a >= 1, b > 1.递归项可以理解为一个高度为 logbn 的 a 叉树, 这样 total operation ...

  4. 答:SQLServer DBA 三十问之二:系统DB有哪些,都有什么作用,需不需要做备份,为什么;损坏了如何做还原(主要是master库)

    2. 系统DB有哪些,都有什么作用,需不需要做备份,为什么:损坏了如何做还原(主要是master库): master:它包含一个系统表集合,是整个实例的中央存储库,维护登录账户,其他数据库,文件分布, ...

  5. Master Theorem

    Master theorem provides a solution in asymptotic terms to solve time complexity problem of most divi ...

  6. 确界原理 supremum and infimum principle 戴德金定理 Dedekind theorem

    确界原理  supremum and infimum principle  戴德金定理  Dedekind theorem http://www.math.ubc.ca/~cass/courses/m ...

  7. [BZOJ4007][JLOI2015]战争调度(DP+主定理)

    第一眼DP,发现不可做,第二眼就只能$O(2^{1024})$暴搜了. 重新审视一下这个DP,f[x][i]表示在x的祖先已经全部染色之后,x的子树中共有i个参战平民的最大贡献. 设k为总结点数,对于 ...

  8. 旋度定理(Curl Theorem)和散度定理(Divergence theorem)

    原文链接 首先说说格林公式(Green's theorem).对于一段封闭曲线,若其围城的区域D为单连通区域(内部任意曲线围城的区域都属于院区域),则有如下公式: 其中其中L为D的边界,取正方向.如果 ...

  9. O、Θ、Ω&主定理

    1.这些是时间复杂度的.(e.g. O(n).Θ(n).Ω(n)) 主要为主定理(坏东西) 2.本质 O <= Θ = Ω >= 3.(你可以把他们都试一遍)主要用处(目前,2020-09 ...

随机推荐

  1. sublime text3 安装详解+前端插件

    1,下载sublime 3,地址:http://www.sublimetext.com/ 2,注册码:(在网上找的,感谢前辈)打开sublime3, help----add license---复制下 ...

  2. Flume 自定义拦截器 多行读取日志+截断

    前言: Flume百度定义如下: Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据:同时,F ...

  3. .NET CORE应用程序启动

    ASP.NET Core 应用是在其 Main 方法中创建 Web 服务器的控制台应用: Main 方法调用 WebHost.CreateDefaultBuilder,通过生成器模式来创建web主机. ...

  4. element-ui 组件 el-calendar 农历显示问题

    一.官方文档:https://element.eleme.cn/#/zh-CN/component/calendar 发现官方并无农历显示的介绍 二.1. 自己写阳历转阴历的方法或引入别人写好的 JS ...

  5. Android埋点方案的简单实现-AOP之AspectJ

    个人博客 http://www.milovetingting.cn Android埋点方案的简单实现-AOP之AspectJ AOP的定义 AOP为Aspect Oriented Programmin ...

  6. opencv —— equalizeHist 直方图均衡化实现对比度增强

    直方图均匀化简介 从这张未经处理的灰度图可以看出,其灰度集中在非常小的一个范围内.这就导致了图片的强弱对比不强烈. 直方图均衡化的目的,就是把原始的直方图变换为在整个灰度范围(0~255)内均匀分布的 ...

  7. Django单元测试中Fixtures用法

    在使用单元测试时,有时候需要测试数据库中有数据,这时我们可以使用Django的Fixtures来生成测试数据. 基础配置 在settings.py 中配置如下内容: FIXTURE_DIRS = (' ...

  8. 避免js重复加载的问题

    避免js重复加载的问题 在日常开发中,一个页面加载另一个页面的时候,就会把另一个页面的js也会加载进来,那么如何才能避免被加载页面不再重复加载已经加载过的js呢? 先上代码 动态加载js // 加载j ...

  9. nodejs爬虫--抓取CSDN某用户全部文章

    最近正在学习node.js,就像搞一些东西来玩玩,于是这个简单的爬虫就诞生了. 准备工作 node.js爬虫肯定要先安装node.js环境 创建一个文件夹 在该文件夹打开命令行,执行npm init初 ...

  10. Java Web笔记(2)

    学习笔记,狂神说java,链接:https://www.bilibili.com/video/av68833391 5.Maven 我为什么要学习这个技术? 在Javaweb开发中,需要使用大量的ja ...