算法导论中文版
中科大算法导论第2次课
Cn
lg n
n n T 2 T 2 2 2
Cn
………………
n T i 2
n T i 2
………………
n C i 2
n C i 2
Cn
令n=2i,则i=lgn T(n)=递归树一层的时间×总的层数 =cn ×(i+1) =cn ×(lgn+1) =cnlgn+cn 数学归纳法证明该结果如下: proof:归纳基础:当n=1时 ∵ T(n)=cnlgn+cn=c ∴ 命题成立 归纳假设:假设n=2i时命题成立
logb a log b a log b a ε
, 则T(n ) θn l gn 2) i f f(n ) θn , 常数ε 0且常数c 1, n足够够大时 3) i f f(n ) Ωn
n 有af cf(n ) , 则T(n ) θf(n ) b
对于Merge-sort算法: ∵ a=2, b=2, D(n)=θ(1), C(n)=θ(n)
(1) T(n) n 2T 2 (n ) n1 n1
上式可改为等价的形式:
C T(n ) n 2T 2 C n n1 n1
直观上看, m aste r 定 理 就 是 比 较 二 个 函f 数 (n )和n logb a 的渐进大小 ,即 : if n logb a f (n ) th e n T(n )适 用 条 件 1 ) if n logb a f (n ) th e n T(n )适 用 条 件 2 ) if n logb a f (n ) th e n T(n )适 用 条 件 3 ) n 例5: T(n ) 9T n 3 2n 例6 : T(n ) T 1 3 n 例7 : T(n ) 3T n lgn 4 n 例8 : T(n ) 2T n lgn 2
算法导论02
Algorithm : Design & Analysis [2]
In the last class…
Goal of the Course Algorithm: the Concept Algorithm Analysis: the Contents Average and Worst-Case Analysis Lower Bounds and the Complexity of Problems
Searching a Sequence
For a given K, there are two possibilities
K in E (say, with probability q), then K may be any one of E[i] (say, with equal probability, that is 1/n) K not in E (with probability 1-q), then K may be located in any one of gap(i) (say, with equal probability, that is 1/(n+1))
Input:
an array E containing n entries of numeric type sorted in non-decreasing order a value K
Output:
index for which K=E[index], if K is in E, or, -1, if K is not in E
Asymptotic Behavior
Asymptotic growth rate The Sets Ο, Ω and Θ Complexity Class An Example: Maximum Subsequence Sum
算法导论第1次课
n
Βιβλιοθήκη n最好情况:输入数据状态为升序,此时A[i]≤key,所以tj=1 T(n) = C1n+C2(n-1)+C3(n-1)+C4(n-1)+C7(n-1) = (C1+C2+C3+C4+C7)n-(C2+C3+C4+C7) = An+B 最坏情况:输入数据状态为倒序,此时A[i]>key,所以tj=j T(n) = C1n+C2(n-1)+C3(n-1)+C4 = ½(C4+C5+C6)n2+(C1+C2+C3+½C4-½C5 -½C6+C7)n-(C2+C3+C4+C7) = An2+Bn+C
特别提示,大O既可表示紧上界也可表示松上界。
2.3 Ω符号(渐进下界) def: Ω(g(n)={f(n):存在正常数C和n0,使得对于所有 的n≥n0,都有0≤Cg(n)≤f(n)} 记为:f(n) = Ω(g(n))
例5:证明f(n)=3n2 = Ω(n) proof: 即要证 Cn≤3n2 Θ,O,Ω符号之间存在关系如下: 定理3.1(P29) 对于任意的函数f(n)和g(n),当且仅当f(n)=O(g(n))且 f(n)=Ω(g(n))时,f(n)=Θ(g(n))。
1 例6:f (n ) n(n 1), g(n ) n 2 2 例7:f (n ) l g n, g(n ) n
第二章 渐进符号(Asympototic notation)
2.1 Θ符号(渐近符号)
def: Θ(g(n)) = { f(n):存在大于0的常数C1、C2和n0,使得
《算法导论(第二版)》(中文版)课后答案
5
《算法导论(第二版) 》参考答案 do z←y 调用之前保存结果 y←INTERVAL-SEARCH-SUBTREE(y, i) 如果循环是由于y没有左子树,那我们返回y 否则我们返回z,这时意味着没有在z的左子树找到重叠区间 7 if y≠ nil[T] and i overlap int[y] 8 then return y 9 else return z 5 6 15.1-5 由 FASTEST-WAY 算法知:
15
lg n
2 lg n1 1 2cn 2 cn (n 2 ) 2 1
4.3-1 a) n2 b) n2lgn c) n3 4.3-4
2
《算法导论(第二版) 》参考答案 n2lg2n 7.1-2 (1)使用 P146 的 PARTION 函数可以得到 q=r 注意每循环一次 i 加 1,i 的初始值为 p 1 ,循环总共运行 (r 1) p 1次,最 终返回的 i 1 p 1 (r 1) p 1 1 r (2)由题目要求 q=(p+r)/2 可知,PARTITION 函数中的 i,j 变量应该在循环中同 时变化。 Partition(A, p, r) x = A[p]; i = p - 1; j = r + 1; while (TRUE) repeat j--; until A[j] <= x; repeat i++; until A[i] >= x; if (i < j) Swap(A, i, j); else return j; 7.3-2 (1)由 QuickSort 算法最坏情况分析得知:n 个元素每次都划 n-1 和 1 个,因 为是 p<r 的时候才调用,所以为Θ (n) (2)最好情况是每次都在最中间的位置分,所以递推式是: N(n)= 1+ 2*N(n/2) 不难得到:N(n) =Θ (n) 7.4-2 T(n)=2*T(n/2)+ Θ (n) 可以得到 T(n) =Θ (n lgn) 由 P46 Theorem3.1 可得:Ω (n lgn)
算法导论 第四章 递归
Idea of master theorem
• Recursion tree
#leaves = ah = alogbn = nlogba
a
Three common cases
• Compare f(n) with nlogba : -- 1. f(n) = O(nlogba-ε) for some constantε> 0 >> f(n) grows polynomially slower than nlogba (by an nε factor)多项式小于 -- Solution: T(n) = Θ(nlogba)
Idea of master theorem
• Recursion tree
CASE 1: The weight increases geometrically from the root to the leaves. The leaves hold a constant fraction of the total weight.
-- Consider T(n) = 2T(
n
) + lgn,
-- Rename m = lgn and we have T(2m) = 2T(2m/2) + m.
-- Set S(m) = T(2m) and we have S(m) = 2S(m/2) + m S(m) = O(mlgm) -- Changing back from S(m) to T(n), we have T(n) = T(2m) = S(m) = O(mlgm) = O(lgnlglgn)
Substitution method替换法
• The most general method: -- Guess the form of the solution猜测解的形式 -- Verify by induction数学归纳法证明 -- Solve for constants解出常数c,n0
算法导论-贪心算法
贪心算法可以看作是动态规划的一种特例,其中只保 留了与当前状态和当前选择相关的子问题的解,而不
是保留所有子问题的解。
贪心算法通常在每一步选择中只考虑当前状态下的局 部最优解,而不是考虑所有可能的选择和未来的状态。
贪心算法的经述 • 贪心算法的基本思想 • 贪心算法的经典问题 • 贪心算法的实现与优化 • 贪心算法的性能分析 • 总结与展望
贪心算法概述
01
定义与特点
定义
贪心算法是一种在每一步选择中都采取当前情况下最好或最优(即最有利)的 选择,从而希望导致结果是最好或最优的算法。
无法保证全局最优解
贪心算法可能只得到局部最优解,而非全局最 优解。
缺乏理论支持
贪心算法的理论基础尚不完备,难以对所有情况做出准确预测。
贪心算法与其他算法的比较
与动态规划算法比较
动态规划算法通过将问题分解为子问题来求解,适合处理具有重叠子问题和最优子结构的问题;而贪 心算法则是每一步都选择当前最优的选择,希望这样的局部最优选择能够导致全局最优解。
法的时间复杂度。
需要注意的是,贪心算法并不总是能够提供最优解,因此在实际应用中, 需要权衡时间复杂度和解的质量。
空间复杂度分析
贪心算法的空间复杂度主要取决于算法 的存储需求。在某些情况下,贪心算法 可能需要大量的存储空间来存储中间结
果或数据结构。
在分析贪心算法的空间复杂度时,需要 考虑算法所需的存储空间和存储结构的 复杂性。通过将每个存储需求的空间复 杂度相加,可以得出整个算法的空间复
与分治算法比较
分治算法是将问题分解为若干个子问题,然后递归地求解这些子问题,再将子问题的解合并起来得到 原问题的解;而贪心算法是在每一步都做出在当前状态下最好或最优(即最有利)的选择,希望这样 的局部最优选择能够导致全局最优解。
《算法导论(原书第3版)》读后感
《算法导论(原书第3版)》读后感在去年初夏的某个夜晚,当我看完“蒲慕明所长在中科院神经所2010 年会上的讲话”后,不禁又想起了这本令我印象深刻的书籍。
去年五月,我大致通读了《算法导论》,但不敢说自己完全理解了其中的内容。
虽然我按照提示完成了部分习题,但后来由于搬家等事务繁忙,未能深入研读。
在我看来,这本书更像是一本编写得像教材的文献综述。
此外,我还意识到,这本书至少有40%的精华都蕴含在课后习题中。
关于这本书的评价和总结已经数不胜数,我只想谈一谈自己的一些个人感悟。
尽管算法的理论常常涉及计算复杂性理论,但算法归根结底是一门实验科学。
一个精妙设计的算法在很大程度上依赖于问题本身的固有性质。
总体而言,提出一个有效的算法需要深入研究以下三个方面(它们是相互关联、循序渐进的): 1. 问题本身的性质和特点:例如,分治算法基于问题的子问题之间存在较弱的约束,而贪心求解算法则基于局部最优就是全局最优的特点。
2. 算法的性能受到哪些因素的影响,以及这些因素如何影响算法,其机制是什么:例如,动态规划的效率与初始随机点的选择方式有关,可满足性问题的解搜索耗时与节点的策略设定有关。
3. 在前面两个部分的基础上提出框架或进行改进,构建一个高效的算法:例如,快速排序是在归并排序的基础上进行改进的,计算代数中的 F5 算法是在 Buchberger 算法的基础上进行改进的,它们都是基于对前两个部分更深入的研究。
我要指出的是,以上三个部分需要大量的实验(验证/试错)来贯彻执行,这就是那“天才的百分之九十九的汗水”。
然而,“秘诀在于使用简单、步骤少、并行且可反复修改的科研方案”。
我们可以看到,神经科学未来的发展趋势所关注的是,最大的问题不是观察什么现象,而是探索这些现象在不同层面上的联系。
例如,我们研究神经系统,从基因到分子细胞,到环路,再到系统,最后到行为,每个层面都有其自身的问题。
现在,最大的问题是,往往一个层面的问题与另一个层面的问题存在相关性,但我们不清楚这种相关性是如何产生的。
算法导论中文版
补充递归和分治策略•通过例子理解递归的概念;•掌握设计有效算法的分治策略;•通过下面的范例学习分治策略设计技巧:过的范例学分策略技¾Merge sort¾Multiplication of two numbers¾Multiplication of two matrices¾Finding Minimum and Maximumj y p¾Majority problem (多数问题)算法总体思想对这k个子问题分别求解。
如果子问题的规模仍然不够z 将要求解的较大规模的问题分割成k个更小规模的子问小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。
题。
nT(n)=T(n/2)T(n/2)T(n/2)T(n/2)算法总体思想将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。
nT(n)=n/2n/2n/2n/2T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4) T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)算法总体思想将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。
分治法的设计思想是将个难以直接解决的大问题n T(n)=分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之分而治之。
n/2n/2n/2n/2T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4递归的概念直接或间接地调用自身的算法称为z递归算法。
算法导论课件5
6
Exam2 Multiplication of two numbers (整数相乘) two n-digit numbers X and Y, Complexity(X × Y) = ? � Divide and Conquer algorithm Let X=ab Y=cd where a, b, c and d are n/2 digit numbers, e.g. 1364=13×102+64. Let m= n/2. Then XY = (10ma+b)(10mc+d) =102mac+10m(bc+ad)+bd
11
Exam3 Multiplication of two matrices (矩阵相乘) two n×n matrices A and B, Complexity(C=A×B) = ?
�
Divide and conquer (Strassen Algorithm) An n×n matrix can be divided into four n/2×n/2 matrices, ⎡ A11 A12 ⎤ ⎡ B11 B12 ⎤ ⎡ C11 C12 ⎤ A= ⎢ ,B= ⎢ ,C= ⎢ ⎥ ⎥ ⎥ ⎣A 21 A 22 ⎦ ⎣B21 B22 ⎦ ⎣C21 C 22 ⎦
12
Complexity analysis: Totally, 7 multiplications, and 18 additions. T(1)=1, T(n) = 7T( ⎡n/2⎤ )+ cn2. Applying Master Theorem,
算法导论第三版新增27章中文版
多线程算法(完整版)——算法导论第3版新增第27章Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein邓辉译原文:/sites/products/documentation/cilk/book_chapter.pdf本书中的主要算法都是顺序算法,适合于运行在每次只能执行一条指令的单处理器计算机上。
在本章中,我们要把算法模型转向并行算法,它们可以运行在能够同时执行多条指令的多处理器计算机中。
我们将着重探索优雅的动态多线程算法模型,该模型既有助于算法的设计和分析,同时也易于进行高效的实现。
并行计算机(就是具有多个处理单元的计算机)已经变得越来越常见,其在价格和性能方面差距甚大。
相对比较便宜的有片上多处理器桌面电脑和笔记本电脑,其中包含着一个多核集成芯片,容纳着多个处理“核”,每个核都是功能齐全的处理器,可以访问一个公共内存。
价格和性能都处于中间的是由多个独立计算机(通常都只是些 PC 级的电脑)组成的集群,通过专用的网络连接在一起。
价格最高的是超级计算机,它们常常采用定制的架构和网络以提供最高的性能(每秒执行的指令数)。
多处理器计算机已经以各种形态存在数十年了。
计算社团早在计算机科学形成的初期就选定采用随机存取的机器模型来进行串行计算,但是对于并行计算来说,却没有一个公认的模型。
这主要是因为供应商无法在并行计算机的架构模型上达成一致。
比如,有些并行计算机采用共享内存,其中每个处理器都可以直接访问内存的任何位置。
而有些并行计算机则使用分布式内存,每个处理器的内存都是私有的,要想去访问其他处理器的内存,必须得向其他处理器发送显式的消息。
不过,随着多核技术的出现,新的笔记本和桌面电脑目前都成为共享内存的并行计算机,趋势似乎倒向了共享内存多处理这边。
虽然一切还是得由时间来证明,不过我们在章中仍将采用共享内存的方法。
对于片上多处理器和其他共享内存并行计算机来说,使用静态线程是一种常见的编程方法,该方法是一种共享内存“虚拟处理器”或者线程的软件抽象。
第1讲算法导论讲述
广州大学华软软件学院
第3页
算法分析与设计 3
算法(Algorithm)
• 算法是指解决问题的一种方法或一个过程。 • 算法是若干指令的有穷序列,满足性质: • (1)输入:有外部提供的量作为算法的输入。 • (2)输出:算法产生至少一个量作为输出。
lim
n
• 若λ=非零常数,则称Ỹ(n)是T(n)的渐近表达式, 或称T(n)渐近等于Ỹ(n),记为 T(n)=Θ(Ỹ(n)),这个记号称为算法运 行时间的渐近Θ-记号,简称为Θ-记号。
T ( n)
广州大学华软软件学院
第11页
算法分析与设计 11
5.有效算法
• 如果两个算法运行时间的渐近表达式相同,则将 它们视为具有相同时间复杂度的算法。显然,渐 近时间为对数幂的算法优于渐近时间为幂函数的 算法,而渐近时间为幂函数的算法则优于渐近时 间为指数函数的算法。我们把渐近时间为幂函数 的算法称为是具有多项式时间的算法,渐近时间 不超过多项式的算法则称其为有效的算法。
广州大学华软软件学院
第9页
算法分析与设计 9
3.实例
• 在线性表A中查找。 • (a)查找值为x=1的元素, 从A[1]起依次要进行5次检测, 第一次找到值为1的元素。 • (b)查找值为x=11的元素, 从A[1]起依次检测完所有元素 (进行10次检测),没有找到 值为11的元素——最坏情形。 • (c)查找值为x=3的元素, 从A[1]起仅进行一次检测就找 到值为3的元素——最好情形。
算法导论
几种重要的算法一高级技术和分析技术1.动态规划------------------------------------------------------√1.1动态规划的本质动态规划是在20世纪50年代初,为了解决一类多阶段决策问题而诞生的。
那么,什么样的问题被称作多阶段决策问题呢?多阶段决策问题通过下面这个例子来说明。
[例一]多段图中的最短路径问题:在图1.1中找出从Al到D1的最短路径(图中的边上的数字表示该边上的权)。
图1多阶段决策问题这个图有一个特点,就是可以将图中的点分为四类(图1.1中的A、B、C、D),那么图中所有的边都处于相邻的两类点之间,并且都从前一类点指向后一类点。
这样,图中的边就被分成了三类(A→B、B→C、C→D)。
这时需要从每一类中选出一条边来,组成从Al到Dl的一条路径,并且这条路径是所有这样的路径中的最短者。
这是多阶段决策问题。
更精确的定义如下:多阶段决策过程,是指这样的一类特殊的活动过程,问题可以按时间顺序分解成若干相互联系的阶段,在每一个阶段都要做出决策,全部过程的决策是一个决策序列。
要使整个活动的总体效果达到最优的问题,称为多阶段决策问题。
多阶段决策问题有两个要素:一个是阶段,一个是决策。
1.1.2阶段与状态阶段:将所给问题的过程,按时间或空间特征分解成若干相互联系的阶段,以便按次序去求每阶段的解。
常用字母k表示阶段变量。
阶段是问题的属性。
多阶段决策问题中通常存在着若干个阶段,如上图中就有A、B、C、D这四个阶段。
在一般情况下,阶段是和时间有关的;但是在很多问题中,阶段和时间是无关的。
从阶段的定义中,可以看出阶段的两个特点:一是“相互联系”,二是“次序”。
阶段之间是怎样相互联系的?就是通过状态和状态转移。
状态:各阶段开始时的客观条件叫做状态。
描述各阶段状态的变量称为状态变量,常用Sk表示第k阶段的状态变量,状态变量Sk的取值集合称为状态集合,用Sk表示。
状态是阶段的属性。
算法导论
算法的乐趣说到算法,大部分同学的第一反应是关于计算机的高端算法,联想到本科学过的C语言、程序设计等问题,感觉特别复杂,然而并不是这样,恰恰这门关于生物信息学的算法却充满着无限的乐趣。
首先,我要感谢马磊老师在这门课程中严格要求我们,认真讲述了有关算法的诸多问题,让我们学到了很多东西,让我明白“授人以鱼不如授人以渔”,传授思路而不是算法本身,算法是为了解决实际问题而设计的,让大家认识到算法奥妙的自然顺序,展示优雅的算法,归纳设计思路,算法是解法,设计算法是寻求解法。
虽然算法作为一门科学是归纳寻求解法的思路,但学习这种归纳法的前提是能体会各种具体算法的用处和效果,这一点吸引了我们大家。
1.法设计的基础现实问题复杂多样,对应的算法也是复杂多样,形态各异,但是这些算法都遵循一些特定的的方法和模式。
就算法模式而言,处理各种求最优解问题时,人们常用贪婪法、动态规划法等算法模式;处理迷宫类问题时,穷尽式枚举和回溯是常用的模式,如果算法需要查表,那么数据结构的设计通常会选择有序表来实现;当算法用到树和图这样的数据结构时,就会用到递归结构的方法。
2.程序的基本结构顺序执行、循环和分支跳转是程序设计的三大基本结构。
1)、假如算法中某个操作需要几个步骤完成,每个步骤都依赖于前一个步骤,将前一个步骤的输出作为下一个步骤的输入,中间不能打断和顺序这样的结构就是算法的顺序执行结构。
2)、循环被定义为在算法中只出现一次但是却有可能被执行多次的一段逻辑体,循环结构一般有三部分组成:循环初始体、循环体和循环条件。
而递归结构通常都可以用复杂一点的循环形式代替。
递归方法符合人类思考问题的方式,它可以使算法结构简单,过程简洁。
对于树和图这样的数据结构,递归方法更是具有循环形式无法比拟的优势。
3)、分支和跳转结构在程序中扮演着重要的角色,正是由于有了分支和跳转,程序才能够产生多种多样的结果,算法在执行的过程中,根据构造的分支条件进行判断,根据判断的结果转入相应的处理流程继续执行。
算法导论中文版答案
} cout<<len<<endl; } return 0; } 15.5-1
15.5-2 15.5-3
15.5-4
16.1-1
第 16 章
16.1-2 16.1-3
16.1-4 16.2-1 16.2-2
16.2-3
16.2-4
16.2-5 16.2-6
16.2-7
25.3-6
5.3-6
6.1-1 6.1-2 6.1-3 6.1-4 6.1-5 6.1-6
第6章
6.1-7
6.2-1 见图 6-2 6.2-2
6.2-3
6.2-4
6.2-5 对以 i 为根结点的子树上每个点用循环语句实现 6.2-6
6.3-1
见图 6-3 6.3-2
6.3-3
6.4-1 见图 6-4 6.4-2 HEAPSORT 仍然正确,因为每次循环的过程中还是会运行 MAX-HEAP 的过程。 6.4-3
6.4-4
6.4-5
6.5-1 据图 6-5 6.5-2
6.5-3 6.5-4 6.5-5
6.5-6 6.5-7
6.5-8
7.1-1 见图 7-1 7.1-2
7.1-3 7.1-4 7.2-1 7.2-2
7.2-3 7.2-4 7.2-5
第七章
7.2-6 7.3-1
7.3-2
7.4-1 7.4-2
16.3-1 16.3-2
16.3-3 16.3-4
16.3-5
16.3-6 那就推广到树的结点有三个孩子结点,证明过程同引理 16.3 的证明。 16.3-7 16.3-8
第 24 章
24.1-1 同源顶点 s 的运行过程,见图 24-4 24.1-2
算法导论第十五章
算法导论第⼗五章15.115.1-1证明:T(n) = 1+\(\sum_0^{n-1}T(j)\)令S(n) = \(\sum_0^nT(j)\)则S(n) - S(n-1) = 1 + S(n-1)S(n) = \(2^{n+1}\)-1T(n) = \(2^n\)15.1-2长度i1234价格pi146.54价格密度126.5/31按照贪⼼策略分割为3、1,总价格为7.5然⽽最优解为2、2,总价格为815.1-3#include <limits.h>int *solution(int *p, int n, int c){int r[n+1];r[0] = 0;for (int i = 1; i <=n; i++){int q = INT_MIN;for (int j = 1; j <= i; j++){q = max(q, p[j]+r[i-j]-c);}r[i] = q;}return r;}15.1-4#include <limits.h>void MEMORIZED_CUT_ROD_AUX(int *p, int n, int *r, int *s){if (r[n] >= 0){return r[n];}if (n == 0) q = 0;else{q = INT_MIN;for (int i = 1; i <= n; i++){int rest = MEMORIZED(p, n-i, r, s);if (q < p[i] + rest){q = p[i] + rest;s[n] = i;}}r[i] = q;}return q;}void MEMOIZED_CUT_ROD(int *p, int n){int r[n+1];for (int i = 0; i <= n; i++){r[i] = INT_MIN;}int s[n+1];return MEMORIZED_CUT_ROD_AUX(p, n, r, s);}15.1-5int solution(int n){int res[MAX_SIZE];res[0] = 0;res[1] = 1;for (int i = 2; i <= n; i++){res[i] = res[i-1]+res[i-2];}return res[n];}15.215.2-1123456 6204019501770186015000 5193024309303000044053301800333036002150010最优化括号⽅案:(\(A_1\)\(A_2\))((\(A_3A_4\))(\(A_5A_6\)))15.2-2typedef struct{int matrix[MAX_SIZE][MAX_SIZE];int n;int m;}Matrix;Matrix MATRIX_CHAIN_MUTIPLY(Matrix *a, int **s, int front, int rear) {if (front == rear){return a[front];}else{int p = s[front][rear];Matrix t = MATRIX_CHAIN_MUTIPLY(a, s, front, p);Matrix y = MATRIX_CHAIN_MUTIPLY(a, s, p+1, rear);Matrix u;u.n = t.n;u.m = y.m;for (int i = 0; i < t.n; i++){for (int j = 0; j < t.m; j++){for (int k = 0; k < t.m; k++){u.matrix[i][k] += t.matrix[i][j]*y.matrix[j][k];}}}return u;}}15.2-3证明:设P(k) >= \(c2^k\)P(n) = \(\sum_1^{n-1}\)P(k)P(n-k)\(\geq\)\(\sum_1^{n-1}c2^k*c2^{n-k}\)\(\geq\)\(\sum_1^{n-1}c^22^n\)\(\geq\)\(c2^n\)15.2-4\(\frac{n^2-n}{2}\)个顶点,2(n-2)条边,分别连接顶点(1, i)、(i+1, n)(i = 2,3,4,...,n-1)15.2-5由条件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
补充递归和分治策略•通过例子理解递归的概念;•掌握设计有效算法的分治策略;•通过下面的范例学习分治策略设计技巧:过的范例学分策略技¾Merge sort¾Multiplication of two numbers¾Multiplication of two matrices¾Finding Minimum and Maximumj y p¾Majority problem (多数问题)算法总体思想对这k个子问题分别求解。
如果子问题的规模仍然不够z 将要求解的较大规模的问题分割成k个更小规模的子问小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。
题。
nT(n)=T(n/2)T(n/2)T(n/2)T(n/2)算法总体思想将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。
nT(n)=n/2n/2n/2n/2T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4) T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)T(/4)算法总体思想将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。
分治法的设计思想是将个难以直接解决的大问题n T(n)=分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之分而治之。
n/2n/2n/2n/2T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4)T(n/4递归的概念直接或间接地调用自身的算法称为z递归算法。
用函数自身给出定义的函数称为递归函数。
z由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。
在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。
这自然导致递归过程的产生。
z分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。
下面来看几个实例。
递归的例子例1 阶乘函数阶乘函数可递归地定义为:边界条件01!=⎧=n n 0)!1(>⎩⎨−n n n 递归方程边界条件与递归方程是递归函数的二个要素,递归函数只有具备了这两个要素,才能在有限次计算后得出结果。
递归的例子例2 排列问题设计一个递归算法生成n个元素{r 1,r 2,…,r n }的全排列。
设R={r …1,r 2,,r n }是要进行排列的n个元素,R i =R-{r i }。
集合X中元素的全排列记为perm(X)。
(r i )perm(X)表示在全排列perm(X)的每一个排列前加上前缀得到的排列。
R的全排列可归纳定义如下:当n=1时,perm(R)=(r),其中r是集合R中唯一的元素;当n>1时,perm(R)由(r 1)perm(R 1),(r 2)perm(R 2),…,(r )perm(R )构成。
n n 7递归的例子例3 整数划分问题将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。
正整数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。
递归的例子例3 整数划分问题前面的几个例子中,问题本身都具有比较明显的递归关系,因而容易用递归函数直接求解。
在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数n 1不大于m的划分个数记作q(n,m)。
可以建立q(n,m)的如下递归关系。
(1) q(n,1)=1,n ≥1;(3) q(n,n)=1+q(n,n-1);(2)q(n,m)=q(n,n),m 当最大加数n 1不大于1时,任何正整数n只有一种划分形式,即48476Λn n 111+++=(4)q(n,m)=q(n,m-1)+q(n-m,m),n>m>1;正整数n的划分由n 1=n的划分和n 1≤n-1的划分组成。
(2) q(n,m)=q(n,n),m ≥n;最大加数n 1实际上不能大于n。
因此,q(1,m)=1。
(4) q(n,m)=q(n,m-1)+q(n-m,m),n>m>1;正整数n的最大加数n 1不大于m的划分由n 1=m的划分和≤n-1的划分组成。
9n 1≤n-1 的划分组成。
递归的例子例3 整数划分问题前面的几个例子中,问题本身都具有比较明显的递归关系,因而容易用递归函数直接求解。
在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数n 1不大于m的划分个数记作q(n,m)。
可以建立q(n,m)的如下递归关系。
⎪⎧==1,11n m n ⎪⎪⎨=<−+=)1,(1),(),(m n m n n q n n q m n q ⎪⎩>>−+−1),()1,(m n m m n q m n q 正整数n的划分数p(n)=q(n,n)。
递归小结优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。
缺点:递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。
递归小结解决方法:在递归算法中消除递归调用,使其转化为非递归算法。
1、采用一个用户定义的栈来模拟系统的递归调用工作栈。
该方法通用性强,但本质上还是递归,只不过人工做了本来由编译器做的事情,优化效果不明显。
2、用递推来实现递归函数。
3、通过变换能将一些递归转化为尾递归,从而迭代求出结果。
后两种方法在时空复杂度上均有较大改善,但其适用范围有限。
分治法的适用条件分治法所能解决的问题一般具有以下几个特征:分治法所能解决的问题般具有以下几个特征:z 该问题的规模缩小到一定的程度就可以容易地解决;z 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质z 利用该问题分解出的子问题的解可以合并为该问题的解;z 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
因为问题的计算复杂性一般是随着问题规模的增加这条特征涉及到分治法的效率,如果各子问题是不而增加,因此大部分问题满足这个特征。
这条特征是应用分治法的前提,它也是大多数问题可以满足的,此特征反映了递归思想的应用能否利用分治法完全取决于问题是否具有这条特征,如果具备了前两条特征,而不具备第三条特征,则可以考虑贪心算法或动态规划。
独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然也可用分治法,但一般用动态规划较好。
分治法的基本步骤:分治法的基本步骤divide-and-conquer(P){if( | P | <= n0) adhoc(P); //解决小规模的问题divide P into smaller subinstances P1,P2,...,Pk;//分解问题P into smaller subinstances P1P2Pkfor(i=1,i<=k,i++)y d v de d co que();//递归的解各子问题yi=divide-and-conquer(Pi); //return merge(y1,...,yk); //将各子问题的解合并为原问题的解}人们从大量实践中发现,在用分治法设计算法时,最好使子问题的规模大致相同。
即将一个问题分成大小相等的k个子问题的处理方法是行之有效的。
这种使子问题规模大致相等的做法是出自一种平衡(balancing)子问题的思想,它几乎总是比子问题规模不等的做法要好。
分治法的复杂性分析一个分治法将规模为n的问题分成k个规模为n/m的子问题去解。
设分解阀值n0=1,且adhoc解规模为1的问题耗费1个单位时间。
再设将原问题分解为k个子问题以及用merge将k个子问题的解合并为原问题的解需用f(n)个单位时间。
用T(n)表示该分治法解规模为|P|=n的问题所需的计算时间,则有:=⎧11)()/()1()(>⎩⎨+=n n n f m n kT O n T −1logn 通过迭代法求得方程的解:∑=+=g 0log )/()(mj jjkm m n f knn T 注意:递归方程及其解只给出n 等于m 的方幂时T(n)的值,但是如果认为T(n)足够平滑,那么由n 等于m 的方幂时T(n)的值可以估计T(n)的增长速度。
通常假定T(n)是单调上升的,从而当m i ≤n<m i+1时,T(m i )≤T(n)<T(m i+1)。
Examples:分治法例子pz Merge sortMultiplication of two numbers z Multiplication of two numbers z Multiplication of two matrices z Finding Minimum and Maximum z Majority problem (多数问题j y p ()z 循环赛日程表1. 整数相乘问题。
分治法的例子X 和Y 是两个n 位的十进制整数,分别表示为X=x n-1x n-2...x 0, Y=y n-1y n-2...y 0,其中0 ≤ x i , y ≤ 9 (i,j j=0,1,…n-1) ,设计一个算法求X ×Y ,并分析其计算复杂度。
说明:算法中“基本操作”约定为两个个位整数以及两个整数相加相乘x i ×y j ,以及两个整数相加。
2. 矩阵相乘问题。
阶实方阵表示为111...n a a ⎛⎞⎜⎟111...n b b ⎛⎞⎜⎟A 和B 是两个n 阶实方阵,表示为,设计个算法求并分析计算复杂度1...........n nn a a =⎜⎟⎜⎟⎝⎠A 1...........n nn b b =⎜⎟⎜⎟⎝⎠B 设计一个算法求A ×B ,并分析计算复杂度。
说明:算法中“基本操作”约定为两个实数相乘,或两个实数相加个实数相加。
Exam1M lti li ti f t b two n -digit numbers X and Y, Complexity(X ×Y) = ?Exam1 Multiplication of two numbers (大整数的乘法)zNaive (原始的) pencil-and-paper algorithm31415962×271828182513276963141596212×2325132769662831924251327696634314159622199117342276Complexity analysis: n 2multiplications and at most 62831924853974377340916p y y pn 2-1additions (加法). So, T (n )=O (n 2).Exam1M lti li ti f t bExam1 Multiplication of two numbers(大整数的乘法)two n-digit numbers X and Y, Complexity(X ×Y) = ?z Divide and Conquer algorithmLet X = a bY = c dwhere a, b, c and d are n/2 digit numbers, e.g.1364=13×102+64.Let m= n/2. ThenXY = (10m a+b)(10m c+d)=102m ac+10m(bc+ad)+bdExam1M lti li ti f t btwo n-digit numbers X and Y, Complexity(X ×Y) = ? Exam1 Multiplication of two numbers(大整数的乘法)z Divide and Conquer algorithmLet X = a b,Y = c dthen XY = (10m a+b)(10m c+d) = 102m ac+10m(bc+ad)+bd Multiply(X; Y; n):if1if n= 1 return X×Y else Complexity analysis: T(1)=1,m= ⎡n/2⎤a= ⎣X/10m⎦; b=X mod 10m c= ⎣Y/10m⎦; d=Y mod 10m =Multiply(;;T(n)=4T(⎡n/2⎤)+O(n). Applying Master Theorem, he= Multiply(a; c; m) f= Multiply(b; d; m) g= Multiply(b; c; m) =Multiply(;;we have T(n)=O(n2).h Multiply(a; d; m) return 102m e+ 10m(g+ h) + fExam1M lti li ti f t b two n -digit numbers X and Y, Complexity(X ×Y) = ?Exam1 Multiplication of two numbers (大整数的乘法)z Divide and Conquer (Karatsuba’s algorithm )Let X = a b ,Y = c d XY =(10)=10then XY = (10m a +b )(10m c +d ) = 102m ac +10m (bc +ad )+bd Note that bc + ad = ac + bd −(a −b )(c −d ). So, we haveF tM lti l (X Y )FastMultiply(X; Y; n ):if n = 1return X ×Y Complexity analysis:(1)1elsem = ⎡n /2⎤a = ⎣X/10m ⎦;b =X mod 10m =m ;=Y mod 10m T (1)=1, T (n )=3T (⎡n /2⎤)+O (n ).Applying Master Theorem,c ⎣Y/10⎦; d Y mod 10e = FastMultiply(a; c; m )f = FastMultiply(b; d; m )g =−b;c −d;m Applying Master Theorem, we havelog 31.59g FastMultiply(a b; c d; m )return 102m e + 10m (e + f −g )+ f2g ()()()T n O nO n==Exam1M lti li ti f t bExam1 Multiplication of two numbers(大整数的乘法)请设计一个有效的算法,可以进行两个n位大整数的乘法运算 小学的方法:O(n2) 8效率太低分治法: O(n1.59) 9较大的改进:O(n)更快的方法??¾如果将大整数分成更多段,用更复杂的方式把它们组合起来,将有可能得到更优的算法。