递归、分治、动态规划、回溯

上传人:wt****50 文档编号:50693728 上传时间:2018-08-10 格式:PPT 页数:73 大小:571KB
返回 下载 相关 举报
递归、分治、动态规划、回溯_第1页
第1页 / 共73页
递归、分治、动态规划、回溯_第2页
第2页 / 共73页
递归、分治、动态规划、回溯_第3页
第3页 / 共73页
递归、分治、动态规划、回溯_第4页
第4页 / 共73页
递归、分治、动态规划、回溯_第5页
第5页 / 共73页
点击查看更多>>
资源描述

《递归、分治、动态规划、回溯》由会员分享,可在线阅读,更多相关《递归、分治、动态规划、回溯(73页珍藏版)》请在金锄头文库上搜索。

1、递归、分治、动态规划与回溯回溯递归递推一般实现方式正反方向 有时可相互转化较简洁,要求数学规 律性较强DFS 穷举的优化版启发式搜索 路径寻找图论/网 络流 数学问题:组合数学 树、图、排序等问题 分治、以大化小动态规划 的实现 DP=递归贪心回溯、递归、递推是计算机算法中基础 内容,范围极其广泛。递归与分治基本原理n对这k个子问题分别求解。如果子问题的规模仍然不够 小,则再划分为k个子问题,如此递归的进行下去,直 到问题规模足够小,很容易求出其解为止。T(n/2)nT(n/2)T(n/2)T(n/2)T(n)=T(n/2)nT(n/2)T(n/2)T(n/2)T(n)=n对这k个子问题分别求

2、解。如果子问题的规模仍然不够 小,则再划分为k个子问题,如此递归的进行下去,直 到问题规模足够小,很容易求出其解为止。nT(n)=n/2T(n/4)T(n/4)T(n/4)T(n/4)n/2T(n/4)T(n/4)T(n/4)T(n/4)n/2T(n/4)T(n/4)T(n/4)T(n/4)n将求出的小规模的问题的解合并为一个更大规模的问 题的解,自底向上逐步求出原来问题的解。递归与分治基本原理n/2T(n/4)T(n/4)T(n/4)T(n/4)n将求出的小规模的问题的解合并为一个更大规模的问 题的解,自底向上逐步求出原来问题的解。nT(n)=n/2T(n/4)T(n/4)T(n/4)T(n

3、/4)n/2T(n/4)T(n/4)T(n/4)T(n/4)n/2T(n/4)T(n/4)T(n/4)T(n/4)n/2T(n/4)T(n/4)T(n/4)T(n/4)递归与分治基本原理递归的概念递归的概念n直接或间接地调用自身的算法称为递归算法。 用函数自身给出定义的函数称为递归函数。n由分治法产生的子问题往往是原问题的较小模 式,这就为使用递归技术提供了方便。在这种 情况下,反复应用分治手段,可以使子问题与 原问题类型一致而其规模却不断缩小,最终使 子问题缩小到很容易直接求出其解。这自然导 致递归过程的产生。n分治与递归像一对孪生兄弟,经常同时应用在 算法设计之中,并由此产生许多高效算法。

4、递推与递归 n递归与递推表面看来是相逆的过程,其实也是相似的,最 终的计算都是从小算到大。n递推的使用环境要求高导致了递推的高效性,递推没有重 复计算什么数据,保持了高效。n递归大多数会重复计算子问题,导致时间浪费,所以一般 不要使用过深的递归,甚至会空间溢出。但是也不能说递推好,递归差,因为递归却能解决很多 递推做不到的事情,在某些特定的环境下也能实现高效 ,并且递归容易使用。我们要就事论事!斐波那契数列(Fibonacci),对于f(30),如果使用递 归则需要运行1664079次,而递推只需30次就可以了,速 度悬殊。递归: long f (long n) if i1时,perm(R)由

5、(r1)perm(R1),(r2)perm(R2), (rn)perm(Rn)构成。 例5 整数划分问题 将正整数n表示成一系列正整数之和:n=n1+n2+nk, 其中n1n2nk1,k1。 正整数n的这种表示称为正整数n的划分。求正整数n的不 同划分个数。 例如正整数6有如下11种不同的划分:6;5+1;4+2,4+1+1;3+3,3+2+1,3+1+1+1;2+2+2,2+2+1+1,2+1+1+1+1;1+1+1+1+1+1。递归举例递归举例(2) q(n,m)=q(n,n),mn; 最大加数n1实际上不能大于n。因此,q(1,m)=1。(1) q(n,1)=1,n1; 当最大加数n1不

6、大于1时,任何正整数n只有一种划分形式, 即(4) q(n,m)=q(n,m-1)+q(n-m,m),nm1; 正整数n的最大加数n1不大于m的划分由n1=m的划分和 n1n-1 的划分组成。(3) q(n,n)=1+q(n,n-1); 正整数n的划分由n1=n的划分和n1n-1的划分组成。例5 整数划分问题 前面的几个例子中,问题本身都具有比较明显的递归关系,因 而容易用递归函数直接求解。 在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关 系,因此考虑增加一个自变量:将最大加数n1不大于m的划分 个数记作q(n,m)。可以建立q(n,m)的如下递归关系。递归举例递归举例例5 整数

7、划分问题 前面的几个例子中,问题本身都具有比较明显的递归关系,因 而容易用递归函数直接求解。 在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关 系,因此考虑增加一个自变量:将最大加数n1不大于m的划分 个数记作q(n,m)。可以建立q(n,m)的如下递归关系。正整数n的划分数p(n)=q(n,n)。 递归举例递归举例例6 Hanoi塔问题 设a,b,c是3个塔座。开始时,在塔座a上有一叠共n个圆盘 ,这些圆盘自下而上,由大到小地叠在一起。各圆盘 从小到大编号为1,2,n,现要求将塔座a上的这一叠圆 盘移到塔座b上,并仍按同样顺序叠置。在移动圆盘时 应遵守以下移动规则: 规则1:每次

8、只能移动1个圆盘; 规则2:任何时刻都不允许将较大的圆盘压在较小的圆盘 之上; 规则3:在满足移动规则1和2的前提下,可将圆盘移至 a,b,c中任一塔座上。递归举例递归举例在问题规模较大时,较难找到一般的方法,因此我们尝试 用递归技术来解决这个问题。当n=1时,问题比较简单。此时,只要将编号为1的圆盘从塔座a 直接移至塔座b上即可。 当n1时,需要利用塔座c作为辅助塔座。此时若能设法将n-1个 较小的圆盘依照移动规则从塔座a移至塔座c,然后,将剩下的最 大圆盘从塔座a移至塔座b,最后,再设法将n-1个较小的圆盘依照 移动规则从塔座c移至塔座b。 由此可见,n个圆盘的移动问题可分为2次n-1个圆

9、盘的移动问题, 这又可以递归地用上述方法来做。由此可以设计出解Hanoi塔问 题的递归算法如下。例6 Hanoi塔问题public static void hanoi(int n, int a, int b, int c)if (n 0)hanoi(n-1, a, c, b);move(a,b);hanoi(n-1, c, b, a);思考题:如果塔的个数变为思考题:如果塔的个数变为a,b,c,da,b,c,d 四个,现要将四个,现要将n n个圆盘从个圆盘从a a全部移动全部移动 到到d d,移动规则不变,求移动步数最移动规则不变,求移动步数最 小的方案。小的方案。递归举例递归举例递归小结递归

10、小结优点:结构清晰,可读性强,而且容易用数学归纳 法来证明算法的正确性,因此它为设计算法、调 试程序带来很大方便。缺点:递归算法的运行效率较低,无论是耗费的计 算时间还是占用的存储空间都比非递归算法要多 。分治法的基本步骤分治法的基本步骤 divide-and-conquer(P)if ( | P | ai,同理我们只要在amid 的后面查找x即可。无论是在前面还是后面查找x,其方法都 和在a中查找x一样,只不过是查找的规模缩小了。这就说明 了此问题满足分治法的第二个和第三个适用条件。分析:很显然此问题分解出的子问题相互独立,即在ai的前 面或后面查找x是独立的子问题,因此满足分治法的第四个适

11、 用条件。给定已按升序排好序的n个元素a0:n-1,现要在这n个元素中找 出一特定元素x。 分析:该问题的规模缩小到一定的程度就可以容易地解决;该问题可以分解为若干个规模较小的相同问题;分解出的子问题的解可以合并为原问题的解;分解出的各个子问题是相互独立的。 二分搜索技术二分搜索技术 给定已按升序排好序的n个元素a0:n-1,现要在这n个元素中找 出一特定元素x。据此容易设计出二分搜索算法: public static int binarySearch(int a, int x, int n)/ 在 a0 amiddle) left = middle + 1;else right = midd

12、le - 1;return -1; / 未找到x算法复杂度分析: 每执行一次算法的 while循环, 待搜索数 组的大小减少一半。因 此,在最坏情况下, while循环被执行了 O(logn) 次。循环体内 运算需要O(1) 时间, 因此整个算法在最坏情 况下的计算时间复杂性 为O(logn) 。 思考题:思考题:给定给定a a,用二分法设计出求,用二分法设计出求a an n的算法。的算法。大整数的乘法大整数的乘法请设计一个有效的算法,可以进行两个n位大整数的乘法运算u小学的方法:O(n2) 效率太低 u分治法: ab cd复杂度分析T(n)=O(n2) 没有改进X = Y = X = a 2

13、n/2 + b Y = c 2n/2 + d XY = ac 2n + (ad+bc) 2n/2 + bd 大整数的乘法大整数的乘法请设计一个有效的算法,可以进行两个n位大整数的乘法运算u小学的方法:O(n2) 效率太低 u分治法: XY = ac 2n + (ad+bc) 2n/2 + bd 为了降低时间复杂度,必须减少乘法的次数。1.XY = ac 2n + (a-c)(b-d)+ac+bd) 2n/2 + bd2.XY = ac 2n + (a+c)(b+d)-ac-bd) 2n/2 + bd复杂度分析T(n)=O(nlog3) =O(n1.59)较大的改进细节问题:两个XY的复杂度都是

14、O(nlog3),但考虑到a+c,b+d可 能得到m+1位的结果,使问题的规模变大,故不选择第2种方 案。大整数的乘法大整数的乘法请设计一个有效的算法,可以进行两个n位大整数的乘法运算u小学的方法:O(n2) 效率太低u分治法: O(n1.59) 较大的改进 u更快的方法? 如果将大整数分成更多段,用更复杂的方式把它们组合起来 ,将有可能得到更优的算法。 最终的,这个思想导致了快速傅利叶变换(Fast Fourier Transform)的产生。该方法也可以看作是一个复杂的分治算 法,对于大整数乘法,它能在O(nlogn)时间内解决。 是否能找到线性时间的算法?目前为止还没有结果。Strass

15、enStrassen矩阵乘法矩阵乘法A和B的乘积矩阵C中的元素Ci,j定义为: 若依此定义来计算A和B的乘积矩阵C,则每计 算C的一个元素Cij,需要做n次乘法和n-1次 加法。因此,算出矩阵C的 个元素所需的计算 时间为O(n3)u传统方法:O(n3)StrassenStrassen矩阵乘法矩阵乘法使用与上例类似的技术,将矩阵A,B和C中每一矩阵都分块成4 个大小相等的子矩阵。由此可将方程C=AB重写为:u传统方法:O(n3) u分治法:由此可得:复杂度分析T(n)=O(n3) 没有改进StrassenStrassen矩阵乘法矩阵乘法u传统方法:O(n3) u分治法: 为了降低时间复杂度,必

16、须减少乘法的次数。复杂度分析T(n)=O(nlog7) =O(n2.81)较大的改进StrassenStrassen矩阵乘法矩阵乘法u传统方法:O(n3) u分治法: O(n2.81) u更快的方法? Hopcroft和Kerr已经证明(1971),计算2个矩阵的乘积 ,7次乘法是必要的。因此,要想进一步改进矩阵乘法的时间 复杂性,就不能再基于计算22矩阵的7次乘法这样的方法了 。或许应当研究或矩阵的更好算法。 在Strassen之后又有许多算法改进了矩阵乘法的计算时间复 杂性。目前最好的计算时间上界是 O(n2.376) 是否能找到O(n2)的算法?目前为止还没有结果。快速排序快速排序private static int partition (int p

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号