0403用代入法求解递归式-分治策略-算法导论第三版

文章目录

      • 1.代入法求解递归式步骤
        • 1.1 求解步骤
        • 1.2 边界条件
      • 2.做出好的猜测
      • 3.微妙的细节
      • 4.避免陷阱
      • 5.改变变量
    • 结语

1.代入法求解递归式步骤

1.1 求解步骤

代入法求解递归式分两步:

  1. 猜测解的形式。
  2. 用数学归纳法求出解中的常数,并证明解是正确的。

当讲归纳假设应用与较小的值时,我们将猜测的解带入函数,因此得名“导入法”。

我们可以用代入法为递归式建立上界或下界。例如,我们确定下面递归式的上界;

T ( n ) = 2 T ( ⌊ n 2 ⌋ ) + n T(n)=2T(\lfloor \frac{n}{2}\rfloor)+n T(n)=2T(⌊2n⌋)+n (4.19)

该递归式与递归式4.3和4.4相似,我们猜测其解为 T ( n ) = O ( n lg ⁡ n ) T(n)=\Omicron(n\lg n) T(n)=O(nlgn)。代入法要求证明,恰当选择常数 c > 0 c\gt 0 c>0,可有 T ( n ) ≤ c n lg ⁡ n T(n)\le cn\lg n T(n)cnlgn
证明: 假设次上界对所有正数 m < n 成立,特别是对 m = ⌊ n 2 ⌋ 有 T ( ⌊ n 2 ⌋ ) ≤ c ⌊ n 2 ⌋ lg ⁡ ⌊ n 2 ⌋ , 带入递归式 T ( n ) ≤ 2 c ⌊ n 2 ⌋ lg ⁡ ⌊ n 2 ⌋ + n ≤ c n lg ⁡ n 2 + n ≤ c n lg ⁡ n − c n + n 证明:\\ 假设次上界对所有正数m\lt n成立, 特别是对m=\lfloor \frac{n}{2}\rfloor\\ 有T(\lfloor\frac{n}{2}\rfloor)\le c \lfloor \frac{n}{2}\rfloor\lg\lfloor\frac{n}{2}\rfloor,带入递归式\\ T(n)\le 2c \lfloor \frac{n}{2}\rfloor\lg\lfloor\frac{n}{2}\rfloor+n\\ \le cn\lg\frac{n}{2}+n \le cn\lg n-cn+n 证明:假设次上界对所有正数m<n成立,特别是对m=2nT(⌊2n⌋)c2nlg2n,带入递归式T(n)2c2nlg2n+ncnlg2n+ncnlgncn+n
其中,只要 c ≥ 1 c\ge 1 c1,最后一步都会成立。

1.2 边界条件

数学归纳法要求我们证明解在边界条件下也成立。对于递归式4.19,我们必须证明,通过选择足够大的常数c,可以使得上界 T ( n ) ≤ c n lg ⁡ n T(n)\le cn\lg n T(n)cnlgn对边界条件也成立。这一要求有时可能引起问题。例如为了方便讨论,假设 T ( 1 ) = 1 T(1)=1 T(1)=1是递归式唯一的边界条件。
对于 n = 1 ,边界条件 T ( n ) ≤ c n lg ⁡ n 推到出 T ( 1 ) ≤ 0 与 T ( 1 ) = 1 相矛盾 对于n=1,边界条件T(n)\le cn\lg n推到出\\ T(1)\le 0\\ 与T(1)=1相矛盾 对于n=1,边界条件T(n)cnlgn推到出T(1)0T(1)=1相矛盾
对特定的边界条件证明归纳假设成立,可以适当修改。比如,在递归式4.19中,渐进符号仅要求我们对 n ≥ n 0 ,时证明 T ( n ) ≤ c n lg ⁡ n n\ge n_0,时证明T(n)\le cn\lg n nn0,时证明T(n)cnlgn,其中 n 0 n_0 n0是我们可以自己选择的常数。我们保留麻烦的边界条件 T ( 1 ) = 1 T(1)=1 T(1)=1,当将其从归纳证明中移除。首先观察到对于 n > 3 n\gt 3 n>3,递归式并不直接依赖T(1),因此将证明中的基本情况T(1)替换为T(2)和T(3)。
证明: 令 n 0 = 2 , 则 T ( 2 ) = 4 , T ( 3 ) = 5 对于某个常数 c ≥ 1 , T ( n ) ≤ c n lg ⁡ n 选择足够大的 c 满足 T ( 2 ) ≤ c 2 lg ⁡ 2 , T ( 3 ) ≤ c 3 lg ⁡ 3 当 c ≤ 2 时保证不等式成立 证明:\\ 令n_0=2,则T(2)=4,T(3)=5\\ 对于某个常数c\ge 1,T(n)\le cn\lg n\\ 选择足够大的c满足T(2)\le c2\lg2,T(3)\le c3\lg3\\ 当c\le 2时保证不等式成立 证明:n0=2,T(2)=4,T(3)=5对于某个常数c1,T(n)cnlgn选择足够大的c满足T(2)c2lg2,T(3)c3lg3c2时保证不等式成立
对于我们所要讨论的大多数递归式来说,扩展边界条件使归纳假设对较小的n成立,是一种简单直接的方法。

2.做出好的猜测

不存在通用的方法来猜解递归式的正确解。猜测解需要经验和创造力。可以使用一些启发式的方法来帮助完成猜解。

如果要求解的递归式与你曾见过的递归式相似,那么猜测一个类似的解是合理的。例如,考虑如下递归式:

T ( n ) = 2 T ( ⌊ n 2 ⌋ + 17 ) + n T(n)=2T(\lfloor \frac{n}{2}\rfloor+17)+n T(n)=2T(⌊2n+17)+n

增加的17不会显著的影响递归式的解。当n较大时, ⌊ n 2 ⌋ 和 ⌊ n 2 ⌋ + 17 \lfloor\frac{n}{2}\rfloor和\lfloor\frac{n}{2}\rfloor+17 2n2n+17差距不大,都是接近n的一半。因此猜测 T ( n ) = O ( n lg ⁡ n ) T(n)=\Omicron(n\lg n) T(n)=O(nlgn).

另一种做出好的猜测的方法是先证明递归式较松的上界和下界,然后缩小不确定的范围。例如,对递归式4.19,我们可以从下界 T ( n ) = Ω ( n ) T(n)=\Omega(n) T(n)=Ω(n)开始,因为递归式中包含n这一项,还可以证明一个初始上界 T ( n ) = O ( n 2 ) T(n)=\Omicron(n^2) T(n)=O(n2)。然后我们可以逐渐降低上界,提升下界,直至收敛到渐进紧确界 T ( n ) = Θ ( n lg ⁡ n ) T(n)=\Theta(n\lg n) T(n)=Θ(nlgn)

3.微妙的细节

有时你可能正确的猜测出了递归式的渐进界,但莫名其妙地在归纳证明时失败了。问题常常出在归纳假设不够强,无法证出准确的界。当遇到这种障碍时,如果修改猜测,将它减去一个低阶项,数学证明常常能顺利进行。

考虑如下递归式

T ( n ) = T ( ⌊ n 2 ⌋ ) + T ( ⌈ n 2 ⌉ ) + 1 T(n)=T(\lfloor\frac{n}{2}\rfloor)+T(\lceil\frac{n}{2}\rceil)+1 T(n)=T(⌊2n⌋)+T(⌈2n⌉)+1

我们猜测 T ( n ) = O ( n ) T(n)=\Omicron(n) T(n)=O(n),并尝试证明对某个恰当选出的常数c, T ( n ) ≤ c n T(n)\le cn T(n)cn成立。猜测带入递归式,得到

T ( n ) ≤ c ⌊ n 2 ⌋ + c ⌈ n 2 ⌉ + 1 ≤ c n + 1 T(n)\le c\lfloor\frac{n}{2}\rfloor+c\lceil\frac{n}{2}\rceil+1\le cn+1 T(n)c2n+c2n+1cn+1

这并不意味着对任意c都有 T ( n ) ≤ c n T(n)\le cn T(n)cn。我们可能忍不住尝试猜测一个更大的界,比如 T ( n ) = O ( n 2 ) T(n)=\Omicron(n^2) T(n)=O(n2)。虽然从这个猜测也能推出结果,但原来的猜测 T ( n ) = O ( n ) T(n)=\Omicron(n) T(n)=O(n)是正确的。然而为了证明它是正确是,我们必须做出更强的归纳假设。

直觉上,我们的猜测是接近正确的:只差一个常数1,一个低阶项。但是,除非我们证明与归纳假设严格一致的形式,否则数学归纳法还是会失败。克服这个困难的方法是从先前的猜测中减去一个低阶项。新的猜测为 T ( n ) ≤ c n + d T(n)\le cn+d T(n)cn+d,d是大于等于0的一个常数,带入递归式有:


T ( n ) ≤ ( c ⌊ n 2 ⌋ − d ) + c ( ⌈ n 2 ⌉ − d ) + 1 ≤ c n − 2 d + 1 ≤ c n − d T(n)\le (c\lfloor\frac{n}{2}\rfloor-d)+c(\lceil\frac{n}{2}\rceil-d)+1\\ \le cn-2d+1\le cn-d T(n)(c2nd)+c(⌈2nd)+1cn2d+1cnd
只要 d ≤ 1 d\le 1 d1,此式成立。与以前一样,我们必须选择走够大的c来处理边界条件。

你可能发现减去一个低阶项的想法与直觉是相悖的。比较,如果证明上界失败了,就应该将猜测增加而不是减少,更松的界难道不是更容易证明吗?不一定!当利用归纳法证明一个上界时,实际上一个更弱的上界可能会更困难一些,因为为了证明一个更弱的上界,我们在归纳证明中也必须使用同样更弱的界。在当前例子中,当递归式中包含超过一个递归项时,将猜测的界减去衣蛾低阶项意味着每次对每个递归项都减去一个低阶项。在上例中,我们将去常数d两次。我们以不等式 T ( n ) ≤ c n − 2 d + 1 T(n)\le cn-2d+1 T(n)cn2d+1结束,可以很容易找到一个d值,使得 c n − 2 d + 1 ≤ c n − d cn-2d+1\le cn-d cn2d+1cnd

4.避免陷阱

使用渐进符号很容易出错。例如,在递归式4.19中,我们可能错误地证明 T ( n ) = O ( n ) T(n)=\Omicron(n) T(n)=O(n),猜测 T ( n ) ≤ c n T(n)\le cn T(n)cn
证明: T ( n ) ≤ 2 ( c ⌊ n 2 ⌋ ) + n ≤ c n + n = O ( n ) 证明:\\ T(n)\le 2(c\lfloor\frac{n}{2}\rfloor)+n\le cn+n=\Omicron(n) 证明:T(n)2(c2n⌋)+ncn+n=O(n)

因为c是常数。错误在于我们并未证出与归纳假设 严格一致的形式,即 T ( n ) ≤ c n T(n)\le cn T(n)cn。因此,当要证明 T ( n ) = O ( n ) T(n)=\Omicron(n) T(n)=O(n)时,需要显示的证出 T ( n ) ≤ c n T(n)\le cn T(n)cn

5.改变变量

有时,一个小的代数运算可以将一个未知的递归式变成你熟悉的形式。例如,考虑如下递归式:

T ( n ) = 2 T ( ⌊ n ⌋ ) + lg ⁡ n T(n)=2T(\lfloor\sqrt{n}\rfloor)+\lg n T(n)=2T(⌊n ⌋)+lgn

我们可以通过改变变量来简化它。为避免舍入误差问题,只考虑 n \sqrt{n} n 是整数的情况。
令 m = lg ⁡ n , 得 T ( 2 m ) = 2 T ( 2 m / 2 ) + m 令m=\lg n,得\\ T(2^m)=2T(2^{m/2})+m m=lgn,T(2m)=2T(2m/2)+m
重新命名 S ( m ) = T ( 2 m ) S(m)=T(2^m) S(m)=T(2m)得到新的递归式

S ( m ) = 2 S ( m / 2 ) + m S(m)=2S(m/2)+m S(m)=2S(m/2)+m

这个递归式与4.19非常像,具有相同的解: S ( m ) = O ( m lg ⁡ m ) S(m)=\Omicron(m\lg m) S(m)=O(mlgm).在从 S ( m ) 转换会 T ( n ) S(m)转换会T(n) S(m)转换会T(n)

T ( n ) = T ( 2 m ) = S ( m ) = O ( m lg ⁡ m ) = O ( lg ⁡ n lg ⁡ lg ⁡ n ) T(n)=T(2^m)=S(m)=\Omicron(m\lg m)=\Omicron(\lg n\lg\lg n) T(n)=T(2m)=S(m)=O(mlgm)=O(lgnlglgn)

结语

欢迎小伙伴一起学习交流,需要啥工具或者有啥问题随时联系我。

❓QQ:806797785

⭐️源代码地址:https://gitee.com/gaogzhen/algorithm

[1]算法导论(原书第三版)/(美)科尔曼(Cormen, T.H.)等著;殷建平等译 [M].北京:机械工业出版社,2013.1(2021.1重印).p47-50

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

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

相关文章

C++ 47 之 函数调用运算符重载

#include <iostream> #include <string> using namespace std;class MyPrint{ public:// 重载小括号() 重载谁operator后就紧跟谁的符号void operator()(string txt){cout << txt << endl;} };class MyAdd{ public:int operator()(int a, int b){retur…

【Pandas驯化-04】Pandas中drop_duplicates、describe、翻转操作

【Pandas驯化-04】Pandas中drop_duplicates、describe、翻转操作 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 相关内容文档获取 微信公…

基于深度学习的光流预测

基于深度学习的光流预测 光流&#xff08;Optical Flow&#xff09;是指图像序列中像素的运动&#xff0c;即在连续的帧之间每个像素的移动向量。光流预测是计算机视觉中的一个重要任务&#xff0c;广泛应用于运动检测、视频分析、机器人导航等领域。基于深度学习的方法近年来…

redis大key优化

1.什么是大key以及可能造成的异常 1.1 什么大key redis是key,val型存储结构&#xff0c;key允许的最大大小为512MB&#xff0c;空字符串也是有效的键。大key是指value很大(占用大内存)。 常见的大key&#xff0c;大致可以这么分(根据具体redis规格以及实际压测而定): (1)单个…

搭建Python虚拟环境(五):Pyenv

使用Pyenv搭建虚拟环境的详细指南 Pyenv 是一个Python版本管理工具&#xff0c;可以让你在同一台机器上安装和管理多个Python版本。对于Windows用户&#xff0c;可以使用pyenv-win&#xff0c;这是一个专为Windows平台设计的Pyenv版本。本文将详细介绍如何使用Pyenv&#xff0…

判断子字符串是否存在

java判断字符串是否包含特定内容&#xff0c;用到contains语句 语法格式是 str.contains(string) 其中 str是字符串 string是查询字符串 示例代码如下 public class Stringcontains {public static void main(String[] args) {String str"今天的菜谱有:蒸羊羔&…

CleanMyMac X软件下载附加详细安装教程

​首先要介绍的是CleanMyMac X&#xff0c;这是一款极受欢迎的苹果电脑清理软件&#xff0c;它能够全面扫描你的电脑系统&#xff0c;清理无用的文件和垃圾&#xff0c;以释放硬盘空间&#xff0c;除了清理功能之外&#xff0c;CleanMyMac X 还可协助管理应用程序、优化性能、修…

[2024-06]-[大模型]-[Ollama]- WebUI

主要涉及要部署的前端webui是来源于:https://github.com/open-webui/open-webui 正常就使用: docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-web…

建造者模式(大话设计模式)C/C++版本

建造者模式 C 参考&#xff1a;https://www.cnblogs.com/Galesaur-wcy/p/15907863.html #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std;// Product Class&#xff0c;产品类&#xff0c;由多个…

小白跟做江科大32单片机之定时器输出比较

原理部分 背景 GPIO口是数字输出端口&#xff0c;只能输出1和0。但是通过PWM&#xff0c;可以使其控制LED呼吸灯亮灭的程度 1.通过CNT和CCR进行比较&#xff0c;可以输出一定频率和占空比的PWM波形 2.通用定时器有4个CCR&#xff0c;可同时输出4路PWM波形&#xff0c;但只有…

智慧消防新篇章:可视化数据分析平台引领未来

一、什么是智慧消防可视化数据分析平台&#xff1f; 智慧消防可视化数据分析平台&#xff0c;运用大数据、云计算、物联网等先进技术&#xff0c;将消防信息以直观、易懂的图形化方式展示出来。它不仅能够实时监控消防设备的运行状态&#xff0c;还能对火灾风险进行预测和评估…

Unity | Tilemap系统

目录 一、准备工作 1.插件导入 2.资源导入 二、相关组件介绍 1.Grid组件 2.Tilemap组件 3.Tile 4.Tile Palette 5.Brushes 三、动态创建地图 四、其他功能 1.移动网格上物体 2.拖拽缩放地图 Unity Tilemap系统为2D游戏开发提供了一个直观且功能强大的平台&#xff…

【知识点】std::thread::detach std::lock_guard std::unique_lock

在 C11 中&#xff0c;std::thread 提供了并发编程的基础设施&#xff0c;使得我们可以创建和管理线程。std::thread 的 detach 方法是一种常用的线程管理方式&#xff0c;允许线程在后台独立运行&#xff0c;而不必与主线程同步或等待其完成。 std::thread::detach 方法 当你…

【LeetCode最详尽解答】125-验证回文串 Valid-Palindrome

欢迎收藏Star我的Machine Learning Blog:https://github.com/purepisces/Wenqing-Machine_Learning_Blog。如果收藏star, 有问题可以随时与我交流, 谢谢大家&#xff01; 链接: 125-验证回文串 直觉 这个问题需要使用一些内置函数&#xff0c;比如 s[l].isalnum() 和 s[l].…

springboot整合security

整合Spring Security到Spring Boot项目中可以帮助你实现认证&#xff08;Authentication&#xff09;和授权&#xff08;Authorization&#xff09;&#xff0c;从而保护你的应用程序资源和数据。下面是一个基本的步骤指南&#xff0c;帮助你在Spring Boot项目中整合和配置Spri…

Docker运行 Redis、Mysql、Nginx、MongoDB、Minio等

Redis 挂载文件&#xff0c;自行选择 wget http://download.redis.io/redis-stable/redis.conf 创建对应的文件 mkdir -p /docker/redis/data mkdir -p /docker/redis/conf touch /docker/redis/conf/redis.conf # redis.conf什么的都不能是空docker pull redis:6.0.8dock…

Web前端真实简历:深入解析关键要点与技巧

Web前端真实简历&#xff1a;深入解析关键要点与技巧 在数字化快速发展的今天&#xff0c;Web前端技术已成为互联网行业的核心领域之一。一份真实而引人注目的Web前端简历&#xff0c;对于求职者来说至关重要。本文将从四个方面、五个方面、六个方面和七个方面&#xff0c;深入…

C++ 55 之 多继承

#include <iostream> #include <string> using namespace std;class Base08_1{ public:int m_a;Base08_1(){this->m_a 10;} };class Base08_2{ public:// int m_b;int m_a;Base08_2(){// this->m_b 20;this->m_a 30;} };// 多继承 继承的类型都要…

GenICam标准(一)

系列文章目录 GenICam标准&#xff08;一&#xff09; GenICam标准&#xff08;二&#xff09; GenICam标准&#xff08;三&#xff09; GenICam标准&#xff08;四&#xff09; GenICam标准&#xff08;五&#xff09; GenICam标准&#xff08;六&#xff09; 文章目录 系列文…

非对称加密系统解析

目录 1. 概述 2. 非对称加密标准 2.1 RSA 2.2 SM2 2.2.1 SM2私钥 2.2.2 SM2公钥 2.2.3 加密数据格式 2.2.4 签名数据格式 1. 概述 非对称加密中&#xff0c;密钥分为加密密钥和解密密钥两种。发送者用加密密钥对消息进行加密&#xff0c;接收者用解密密钥对密文进行解密…