算法导论(二):渐进符号、递归及解法

news2024/10/7 4:29:59

渐近符号
基本的渐近符号:
O 表示上界,即小于等于 ≤
Ω 表示下界,即大于等于 ≥
Θ 表示渐近等于 =(上一集也有使用这个符号)

还有几个严格符号:
o 表示小于 <
ω 表示大于 >

渐近符号O
主要详细讲解了渐近符号O
对于f(n) = O(g(n)),表示存在适当的常数c>0,n0>0,使得f(n) ≤ c·g(n),对于所有的n≥n0

f(n)可以说是属于g(n)构成的函数集,可以定义O(g(n))为一个函数集
O(g(n)) = { f(n):存在c>0、n0>0,使得0≤f(n)≤cg(n),其中n≥n0 }

严格意义上来讲,f(n) = O(g(n))中的等号=是不对称的
即不能从右边推算到左边。这里表达的意思是属于某个集合
即相当于f(n)O(g(n))

有一些关于O符号的精妙用法,把它当作宏来用,
例子:f(n) = n3 + O(n2)
表示f(n)主要是n3,但是还有个低阶项O(n2)。即存在某函数h(n)=O(n2),使得f(n) = n3 + h(n)。O(n2)是一个误差项

例子:n2 + O(n) = O(n2)
表示对所有f(n)∈O(n),存在h(n)∈O(n2),使得n2+f(n)=h(n)

渐近符号Ω
f(n) = Ω(g(n)) 这里比较简单带过,Ω的集合版定义为:
Ω(g(n)) = { f(n):存在c>0、n0>0,使得0≤cg(n)≤f(n),其中n≥n0 }

渐近符号Θ
Θ(g(n)) = O(g(n)) ∩ Ω(g(n))

解递归式
解递归式没有通用的方法(没有万金油),但是有三种主要的方法:代换法、递归树法、主方法。

代换法
代换法和解积分类似,主要有三个步骤:

1.猜答案,不需要非常精确
2.验证
3.找出常数系数,使问题成立

注:代换法的验证是使用数学归纳法,在这一步不能使用O符号。

一个错误的证明:
要证明n=O(1)【显然是不成立的,不然所有算法都是常数复杂度了】
因为
1 = O(1)
…(逐步归纳)
n-1 = O(1)
所以n = (n-1)+1 = O(1) + O(1) = O(1)

上面的证明是错误的,不能在归纳中使用O,因为这里的常数是变化的。如果是有穷数量的常数加倍,没太大问题,这依然是一个常数。但如果是2k次的这种加倍就有问题了,常数是依赖于n变化的。在归纳过程中,要保证常数系数是不变的。


练习一
T(n) = 4T(n/2) + n
T(1) = Θ(1)

猜测①:T(n) = O(n3)
验证:T(k) ≤ c(k3),其中k<n
验证过程如下:
T(n) = 4T(n/2)+n
… ≤ 4c(n/2)3+n
… = (1/2)cn3+n
… = cn3-[(1/2)cn3-n]
其中,cn3为理想情况,余项=[(1/2)cn3-n]
T(n) ≤ cn3, if 余项=[(1/2)cn3-n]≥0
这里的c是一个常数系数,可以设定任何想要的值。比如设置c=2,猜测成立。


1.猜测②:T(n)=O(n2)
2.验证:T(k) ≤ c(k2),其中k<n
验证过程如下:
T(n) = 4T(n/2)+n
… ≤ 4c(n/2)2+n
… = cn2+n
… = cn2-(-n)
其中,cn2为理想情况,余项=-n
T(n) ≤ cn2, if 余项=-n ≥ 0
因为n≥1,所以显然不成立。


1.猜测③:T(n) = O(c1n2-c2n)
2.验证:T(k) ≤ c1k2-c2k,其中k<n
验证过程如下:
T(n) = 4T(n/2)+n
… ≤ 4[c1(n/2)2-c2(n/2)]+n
… = c1n2 - 2c2n + n
… = c1n2 - c2n - (c2n-n)

其中,c1n2为理想情况,余项=c2n-n
so,T(n) ≤ c1n2-c2n,if 余项=c2n-n ≥ 0,即c2≥1。
当n=1,T(1) ≤ c1 - c2,又因为T(1) = Θ(1),故c1>c2。


一般大家都比较关心上界,所以只求O,不过偶尔也会求一下下界Ω。

递归树法
在上一集讲归并排序的时候,讲了一点递归树法。这节课找了个稍微复杂点的例子。

练习二
T(n) = T(n/4) + T(n/2) + n2
… = n2 + T(n/4) +T(n/2)
… = n2 + (n/4)2 + T(n/16) + T(n/8) + (n/2)2 + T(n/8) + T(n/4)
… = n2 + (n/4)2 + (n/2)2 + [(n/16)2] + [(n/8)2] + [(n/8)2] + [(n/4)2]
… = …


注:为了简洁书写,表示[(n/8)2]表示T(n/8)的展开形式

用脑图来表示递归树
第一次展开:T(n) = T(n/4) + T(n/2) + n2,如下图:
在这里插入图片描述
第二次展开:T(n) = n2 + (n/4)2 + T(n/16) + T(n/8) + (n/2)2 + T(n/8) + T(n/4),如下图:

在这里插入图片描述
继续展开:在这里插入图片描述
观察得到,算法的初始规模为T(n),每次递归分解为一个T(n/4)和T(n/2),每次都会比上一级减少1/4的n,所以可推断最后的叶节点数量 < n

一直递归到T(1),即常数。观察可得,递归树每层n2的系数是一个等比级数,如第一层为1,第二层为5/16,第三层为25/256…
可得n2的系数总和=1 + 5/16 + 52/162 + … + 5k/16k ≤ 2

也就是T(n) ≤ 2n2 +n = O(n2)

主方法
主方法是递归树法的一个应用,但是比递归树法更精确。但只能应用到特定的递归式上。
特定的递归式:
T(n) = aT(n/b)+f(n),其中a≥1,b>1,f(n)渐近趋正。
对于规模为n的算法,每次递归可以转化为a个规模为n/b的算法,以及一个非递归的代价f(n)。

渐近趋正:对于足够大的n,f(n)是正的。即存在n0,当n≥n0,f(n)>0

主方法有个简单的思路:比较非递归函数f(n)和函数nlogba(表示递归树叶节点的数量)的大小,比较的结果有三种情况:小于,等于,大于。

情况一:小于
对于第一种情况,f(n) < nlogba。
即:f(n) = O(nlogba - ε),ε>0
==> T(n) = Θ(nlogba),即由nlogba作为主导,忽略f(n)。

情况二:等于
第二种情况,f(n) = nlogba
注意:这里的等于不是完全等于,而是基本等于。
即:f(n) = Θ(nlogba · lgkn),k≥0
==> T(n) = Θ(nlogba · lgk+1n),即f(n)·h,h=lgn。

情况三:大于
第三种情况,f(n) > nlogba
即:f(n) = Ω(nlogba + ε),ε>0
还需要考虑f(n)是如何增长的,需要确保在递归的过程中,f是不断减小的,否则可能得到无限大的值。。
即要求【下一层的总代价af(n/b)】 ≤ 【小于当前层的代价(1-ε’)f(n)】 ,ε’ > 0,(1-ε’)表示严格<1
==> T(n) = Θ(f(n)),即由f(n)作主导,忽略nlogba。

练习三
T(n) = 4T(n/2)+n
代入以上的公式【T(n)=aT(n/b)+f(n)】可得:a=4,b=2,f(n)=n
计算可得nlogba = n2
接下来比较 f(n)=n 和 nlogba=n2
因为n ≤ n2,所以符合第一种情况,故T(n) = Θ(n2)

练习四
T(n) = 4T(n/2)+n2
代入以上的公式【T(n)=aT(n/b)+f(n)】可得:a=4,b=2,f(n)=n2
计算可得nlogba = n2
接下来比较 f(n)=n2 和 nlogba=n2
因为n2 == n2,所以符合第二种情况,故T(n) = Θ(n2lgk+1n)
即T(n) = Θ(n2lgn),设定k=0

练习五
T(n) = 4T(n/2)+n3
省略一下推算,符合第三种情况
即T(n) = Θ(n3)

为了好复习好找到这个笔记,我就搬运过来了
作者:LuLuX
链接:https://www.jianshu.com/p/867fba3d0220
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/179476.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Latex中给图表添加中英文标题及生成相关目录

通常我们都是用\caption{这里是标题}的方式给图表添加对应的标题&#xff0c;如果我们需要同时给出两个标题呢&#xff1f;&#xff08;例如某些毕业论文中要求同时给出中英文标题&#xff09;如果我们还要生成对应的图表目录呢&#xff1f;这些问题都可以利用bicaption这个包来…

【论文翻译】A simple yet effective baseline for 3d human pose estimation

【论文】https://arxiv.org/abs/1705.03098v2 【pytorch】weigq/3d_pose_baseline_pytorch: A simple baseline for 3d human pose estimation in PyTorch. (github.com) 【tensorflow】https://github.com/una-dinosauria/3d-pose-baseline 摘要 随着深度卷积网络的成功&am…

手把手教你如何在项目中使用阿里字体图标IconFont

阿里图标官网地址&#xff1a;IconFont-阿里巴巴矢量图标库 一、注册账号 要使用阿里图标&#xff0c;首先你要在它的官网注册一个账号&#xff0c;注册的方式有多种&#xff08;手机号&#xff0c;Github&#xff0c;微博&#xff0c;阿里域账号&#xff09;&#xff0c;根据…

【CSDN的2022与2023】普普通通的三年,从懵懂、焦虑到坚定、奋进,破除焦虑努力成为更好的自己

大家好&#xff0c;我是黄小黄&#xff01;一名普通的软件工程在读学生。最近终于闲下来了一丢丢&#xff01;借着休息之余&#xff0c;来写一篇年度总结散散心~与其说是年度总结&#xff0c;不如说是给大学生活与莽莽撞撞的自己一个交代叭&#xff01; 这些都是小标题~碎碎念1…

行为型模式-观察者模式

1.概述 定义&#xff1a;又被称为发布-订阅&#xff08;Publish/Subscribe&#xff09;模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时&#xff0c;会通知所有的观察者对象&#xff0c;使他们能…

深度卷积对抗神经网络 基础 第四部分 可控制的GANs(Controllable GANs)

不同的生成模型定义 深度卷积对抗神经网络包含两种不同的生成模型&#xff0c; 条件生成模型 和非条件生成模型。非条件生成模型就像是一个彩票机或者赌博机&#xff0c;你输入一个任意数字的硬币数量&#xff0c;而输出则是随机的彩球。这样的系统&#xff0c;我们不能控制输…

第九层(3):STL之vector类

文章目录前情回顾vrctor类vrctor类的功能vector与普通数组的区别vector的迭代器vector类内的构造函数vector类内的赋值操作vector类内对容器和大小操作vector类内的插入操作vector类内的删除操作vector类内的单个访问vector类内的交换函数vector类内的预留空间下一座石碑&#…

goto语句——“C”

各位CSDN的uu你们好啊&#xff0c;好久不见&#xff0c;甚是想念。今天小雅兰要带大家学习的内容是一个小知识点——goto语句&#xff0c;好啦&#xff0c;就让我们进入goto语句的世界吧 C语言中提供了可以随意滥用的goto语句和标记跳转的标号。 从理论上 goto语句是没有必要…

Python爬虫教你爬取视频内容

前面介绍了基本的数据爬取&#xff0c;图片爬取的相关案例前面文章也有涉及&#xff0c;关于有些案例网站不能登录的问题&#xff0c;可以再找些别的网站&#xff0c;因为道理既然明白了&#xff0c;其实什么网站都一样&#xff0c;它有反爬机制&#xff0c;自然有应对它的办法…

安装mysql 5.7.24

官网 https://downloads.mysql.com/archives/community/ 安装 安装好后解压有如下内容 配置电脑环境变量 MYSQL_HOME mysql安装目录 PATH %MYSQL_HOME%\bin 配置mysql相关信息 &#xff08;1&#xff09;新建配置文件my.ini 配置的是字符集类信息与存储引擎相关信息 &…

(Java高级教程)第四章必备前端基础知识-第二节2:CSS属性

文章目录一&#xff1a;CSS属性一览表二&#xff1a;常用属性详解&#xff08;1&#xff09;字体属性&#xff08;2&#xff09;文本属性&#xff08;3&#xff09;背景属性一&#xff1a;CSS属性一览表 W3C&#xff1a;元素属性 A&#xff1a; align-content规定弹性容器内…

[Android开发练习1] 绘制国旗

前言 本题主要在于熟练使用线性布局&#xff0c;了解其布局特点学会横向与纵向排列控件&#xff0c;以及认识TextView控件&#xff0c;同时学会使用对控件赋予不同的权重值来布局&#xff0c;在布局中使用了权重的控件的宽度就要设置成0dp。另外&#xff0c;了解到如何应对xml代…

Linux常见命令 25 - RPM包安装、升级、卸载、查询、校验、提取

目录 1. 包名与包全名 2. RPM安装 3. RPM包升级 4. RPM包卸载 5. 查询是否安装RPM包 6. RPM包校验 7. RPM包中文件提取 1. 包名与包全名 包全名&#xff1a;操作的包是没有安装的软件包时&#xff0c;使用包全名&#xff0c;而且要注意路径包名&#xff1a;操作已经安…

【进击的算法】基础算法——怎么优雅地控制边界范围

学习范围 &#xff1a; ✔️数组 ✔️边界控制本文作者 &#xff1a; 蓝色学者i 边界控制的艺术前言一、为什么需要控制边界&#xff1f;二、怎么优雅地控制边界&#xff1f;三、令人抓狂的二分查找3.1 题目概述3.2解题思路3.3 解决方案方案一&#xff1a;边界都有效方案二&…

Python3 循环语句

本章节将为大家介绍 Python 循环语句的使用。 Python 中的循环语句有 for 和 while。 Python 循环语句的控制结构图如下所示&#xff1a; while 循环 Python 中 while 语句的一般形式&#xff1a; while 判断条件(condition)&#xff1a;执行语句(statements)…… 执行流程…

【数据结构之二叉树系列】万字深剖普通二叉树的遍历+分治算法思想

目录前言一、背景知识二、前序遍历三、中序遍历四、后序遍历五、求二叉树中结点的个数1. 遍历计数&#xff08;1&#xff09;前序遍历计数&#xff08;2&#xff09;中序遍历计数&#xff08;3&#xff09;后序遍历计数2.分治算法思想&#xff08;推荐&#xff09;敬请期待前言…

Java基础 IO

IO流 IO流 什么是IO流&#xff1f; 存储和读取数据的解决方案 I&#xff1a;input O&#xff1a;output 流&#xff1a;像水流一样传输数据 IO流的作用&#xff1f; 用于读写数据&#xff08;本地文件&#xff0c;网络&#xff09; IO流按照流向可以分类哪两种流&#xff1f…

数据库02_函数依赖,数据库范式,SQL语句关键字,数据库新技术---软考高级系统架构师009

1.首先我们来看这个,给定一个X,能确定一个Y那么就说,X确定Y,或者Y依赖x,那么 比如y = x * x 就是x确定y,或者y依赖于x 2.然后再来看图,那么左边的部分函数依赖,就是,通过A和B能决定C,那么如果A只用给就能决定C,那么就是部分函数依赖. 3.然后再来看,可以看到,A可以决定B,那么…

servlet过滤器Filter简要回顾-过滤请求字符编码,/和/*和/**的区别

servlet过滤器Filter简要回顾-过滤请求字符编码,/和/*和/**的区别servlet过滤器1.filter过滤器的含义2.filter过滤器的使用3.测试-过滤字符编码正确响应中文编码3.1 创建servlet用于显示中文字符3.2 自定义过滤器3.3 配置web.xml中的servlet映射以及过滤器请求拦截3.4 运行输出…

【编程入门】开源记事本(安卓版)

背景 前面已输出多个系列&#xff1a; 《十余种编程语言做个计算器》 《十余种编程语言写2048小游戏》 《17种编程语言10种排序算法》 《十余种编程语言写博客系统》 《十余种编程语言写云笔记》 本系列对比云笔记&#xff0c;将更为简化&#xff0c;去掉了网络调用&#xff0…