软考—从分治法中看时间复杂度计算
来源:互联网 发布:java invoke 返回空 编辑:程序博客网 时间:2024/04/29 09:33
1)分治策略的思想和理论
分治算法是按照下列方案来工作的:
1、将问题的实例划分为几个较小的实例,最好具有相等的规模(事实上,一般来说就是这样来分的,而且分为2个实例的居多,注意是递归的分!!!)
2、对这些较小的实例求解(一般使用递归的方法,但在问题规模足够小的时候也可以采用采用另一个算法(停止递归))
3、如果有必要的话,合并这些较小问题的解,以得到原始问题的解(事实上,一个分治算法的精华就在于合并解的过程)
不要忽视这三句话!!!它是许多分治算法经验的总结,有助于在分析问题中考虑如何去使用分治算法,提请注意括号里我的注释!!!
形象的表示一下,截张图:
大多数都是规模为n的问题,被划分为2个规模为n/2的问题,更一般的情况下,从理论上分析一下:
一个规模为n的实例可以划分为b个规模为n/b的实例,其中a个实例是需要求解的,为了简化分析,我们假设n是b的幂(每次都可以整的划分),对算法的运行时间,下面的递推关系式是显然的:
其中,a,b的含义已经说过了,f(n)表示将求解得到的a个子问题的解合并起来所需要的时间复杂度。
如何根据a,b以及f的阶来确定这个算法的时间复杂度呢?有下列主定理:(证明参见算法导论)
2)定理分析
1、b,a,f(n)的含义,这个要弄清楚,要不然恐怕你是无法记住这个结论的。
2、这个式子是一个通用的数学表达式,在计算机的常用算法策略中,它太概括了,我们往往用到的只是它范围很小的一部分。
分析1:a和b的关系,其实a绝大多数时候都是等于b的吧(因为规模n划分为了b个子规模,需要处理的是a个,参见a,b的含义),a,b的含义告诉我们a <= b(当这是最基本要满足的条件)。常常要么是 a==b(分成的子规模都要处理,然后去合并),要么是a==1(实际上这是减治的思想,分成了b个子规模,但最终却可以排除其他的,只在其中一个子规模中去处理)。一般来说就是这样,所以a,b并不是随意的。
分析2:其实b要么为2(几乎所有情况)要么为3(极少数情况)吧,这个分治思想里面就说啦,一般来说都是分为2个规模相等的子规模(当然谁都想分的越多越好,这样算法就更快,但是现实是问题往往没有那么高效的算法,找到一个3的分治就已经很不错了)
分析3:由上面2条可知,a,b的值几乎就那么几个(当然我说的是几乎所有书上可以看到的常见算法案例),所以不用那么担心。
分析4:f(n)是线性的的情况很多(即d=1的情况是最多的)。再来看看a和b^d比较大小的关系说明了什么:f(n)代表的是合并的复杂度,1<=a <= b,定性的分析,可以知道:
第一种情况:a < b^d
因为1<=a <= b,所以只要d>1,不管a,b是什么(不管怎么划分规模,也不关需要处理几个规模),总是第一种情况,时间复杂度是n^d。如果d=1呢,只要a < b(处理的比划分的少),那么还是第一种情况,时间复杂度也是n^d = n
第二种情况:a = b^d
因为1<=a <= b,所以如果a=b(划分多少处理多少),那么d只能为1才能是这种情况。-----常见的归并排序都是这样而如果a < b,那b就只能<1才能是这种情况,一般很少见。
第三种情况:a > b^d
非常少见,我还木有见过这样的算法,一开始我认为这种情况不可能,但在理论上它是存在的。因为1<=a <= b,所以要满足这个式子d必须<1 。
从这也可以看出这三个参数之间的关系,事实上是划分的复杂度和合并的复杂度在争抢复杂度的控制权。
说了这么多,感觉越分析越复杂了吗,其实不是,把这些分析想清楚,对递推式的理解就更进一步了,有了上述分析,其实下面几个常见的递推式就包含了大多数的算法:
T(n) = a * T(n/b) + f(n)的常见式子:
1、T(n) = 2 * T(n/2) + O(n) 时间复杂度n*log(n)
一般来说分治算法就是这样,分成2个子规模的问题,需要处理的也是2个,对这两个子规模合并又是线性的
a = b = 2, d = 1; a == b^d 由主定理得n*log(n)
只要a=b,d=1,就都是这个复杂度
2、T(n) = T(n/2) + O(n) 时间复杂度为n,线性的
a = 1,b = 2,d=1(分为2个子规模,但只对一个子规模处理,合并也是线性的)
a < b^d, 时间复杂度是n^d = n
其实质押a < b,d=1,都是这个。
感觉对一个定理解读了这么多,确实让它变得更加复杂了,但如果你做了上述思考,相信对这个式子认识也更加深刻了一点。
1 0
- 软考—从分治法中看时间复杂度计算
- 软考 递归式时间复杂度计算详解
- 软考 递归式时间复杂度计算详解
- 软考 递归式时间复杂度计算详解
- 分治策略时间复杂度计算--综述
- 关于分治法的时间复杂度
- 软考软件设计师中McCabe环路复杂度计算
- 分治法的递归算法时间复杂度分析
- 分治法和二分法的时间复杂度简明分析
- 分治法和二分法的时间复杂度简明分析
- 二分查找法时间复杂度计算
- 时间复杂度的计算
- 时间复杂度的计算
- 时间复杂度的计算
- 时间复杂度的计算
- 时间复杂度的计算
- 时间复杂度的计算
- 时间复杂度计算
- hdu 5961 传递 ccpc 2016 合肥站
- Java知识点整理
- Android下静态代理和动态代理解析
- Ardupilot任务调度的理解
- 把jar包放到本地maven仓库中
- 软考—从分治法中看时间复杂度计算
- ECMAScript 6 入门 个人笔记(一)
- 基础:高通bring up camera
- 【JDK源码阅读5-util】Collection-List---Vector
- 菜鸟之路——Spring MVC(四)handlerMapping和handlerAdapter
- EffectiveJava(Item: 1 to 12)
- [Arduino库]任务调度器,更好地处理多任务
- React生成有序列表
- 使用Itext 进行PDf导出功能