据此容易设计出二分搜索算法:templateint BinarySearch(Type a[], const Type& x, int l, int r){while (l<=r ){int m = ((l+r)/2);if (x 二二 a[m]) return m;if (x < a[m]) r = m-1; else l = m+1;}return -1;}6、 合并排序描述如下:templatevoid Mergesort(Type a[ ], int left, int right){if (left0)y=y*x;(return y) ;}四、问答题1. 用计算机求解问题的步骤:1、 问题分析2、数学模型建立3、算法设计与选择4、算法指标5、算法分析6、算法实现7、程序调试8、结果整理文档编制2. 算法定义:算法是指在解决问题时,按照某种机械步骤一定可以得到问题结果的处理过 程3. 算法的三要素1、操作2、控制结构3、数据结构4. 算法具有以下5个属性:有穷性:一个算法必须总是在执行有穷步之后结束,且每一步都在有穷时间 内完成。
确定性:算法中每一条指令必须有确切的含义不存在二义性只有一个入 口和一个出口可行性:一个算法是可行的就是算法描述的操作是可以通过已经实现的基本 运算执行有限次来实现的输入:一个算法有零个或多个输入,这些输入取自于某个特定对象的集合输出:一个算法有一个或多个输出,这些输出同输入有着某些特定关系的量5. 算法设计的质量指标:正确性:算法应满足具体问题的需求;可读性:算法应该好读,以有利于读者对程序的理解;健壮性:算法应具有容错处理,当输入为非法数据时,算法应对其作出反应, 而不是产生莫名其妙的输出结果效率与存储量需求:效率指的是算法执行的时间;存储量需求指算法执行过 程中所需要的最大存储空间一般这两者与问题的规模有关经常采用的算法主要有迭代法、分治法、贪婪法、动态规划法、回溯法、分支 限界法6. 迭代法:也称“辗转法”,是一种不断用变量的旧值递推出新值的解决问题的方法7. 利用迭代算法解决问题,需要做好以下三个方面的工作:1)、确定迭代模型在可以用迭代算法解决的问题中,至少存在一个直接或 间接地不断由旧值递推出新值的变量,这个变量就是迭代变量2) 、建立迭代关系式所谓迭代关系式,指如何从变量的前一个值推出其下 一个值的公式(或关系)。
迭代关系式的建立是解决迭代问题的关键,通常可以 使用递推或倒推的方法来完成3) 、对迭代过程进行控制在什么时候结束迭代过程?这是编写迭代程序必 须考虑的问题不能让迭代过程无休止地重复执行下去迭代过程的控制通常可 分为两种情况:一种是所需的迭代次数是个确定的值,可以计算出来;另一种是 所需的迭代次数无法确定对于前一种情况,可以构建一个固定次数的循环来实 现对迭代过程的控制;对于后一种情况,需要进一步分析出用来结束迭代过程的 条件8. 分治法的基本思想是:将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立 且与原问题相同递归地解这些子问题,然后将各个子问题的解合并得到原问题 的解9. 分治法所能解决的问题一般具有以下几个特征:(1) 该问题的规模缩小到一定的程度就可以容易地解决;(2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有 最优子结构性质;(3) 利用该问题分解出的子问题的解可以合并为该问题的解;(4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不 包含公共的子子问题10、分治法的基本步骤分治法在每一层递归上都有三个步骤:(1) 分解:将原问题分解为若干个规模较小,相互独立,与原问题 形式相同的子问题;(2) 解决:若子问题规模较小而容易被解决则直接解,否则递归地 解各个子问题;(3) 合并:将各个子问题的解合并为原问题的解。
11. 动态规划的基本思想前文主要介绍了动态规划的一些理论依据,我们将前文所说的具有明显的阶 段划分和状态转移方程的动态规划称为标准动态规划,这种标准动态规划是在研 究多阶段决策问题时推导出来的,具有严格的数学形式,适合用于理论上的分析 在实际应用中,许多问题的阶段划分并不明显,这时如果刻意地划分阶段法反而 麻烦一般来说,只要该问题可以划分成规模更小的子问题,并且原问题的最优 解中包含了子问题的最优解(即满足最优子化原理),则可以考虑用动态规划解 决动态规划的实质是分治思想和解决冗余,因此,动态规划是一种将问题实例 分解为更小的、相似的子问题,并存储子问题的解而避免计算重复的子问题,以 解决最优化问题的算法策略由此可知,动态规划法与分治法和贪心法类似,它们都是将问题实例归纳为 更小的、相似的子问题,并通过求解子问题产生一个全局最优解贪心法的当前选择可能要依赖已经作出的所有选择,但不依赖于有待于做出 的选择和子问题因此贪心法自顶向下,一步一步地作出贪心选择; 而分治法中的各个子问题是独立的(即不包含公共的子问题),因此一旦递归地 求出各子问题的解后,便可自下而上地将子问题的解合并成问题的解。
不足之处:如果当前选择可能要依赖子问题的解时,则难以通过局部的贪心 策略达到全局最优解;如果各子问题是不独立的,则分治法要做许多不必要的工 作,重复地解公共的子问题解决上述问题的办法是利用动态规划该方法主要应用于最优化问题,这类 问题会有多种可能的解,每个解都有一个值,而动态规划找出其中最优(最大或 最小)值的解若存在若干个取最优值的解的话,它只取其中的一个在求解过 程中,该方法也是通过求解局部子问题的解达到全局最优解,但与分治法和贪心 法不同的是,动态规划允许这些子问题不独立,(亦即各子问题可包含公共的子 问题)也允许其通过自身子问题的解作出选择,该方法对每一个子问题只解一次, 并将结果保存起来,避免每次碰到时都要重复计算因此,动态规划法所针对的问题有一个显著的特征,即它所对应的子问题树 中的子问题呈现大量的重复动态规划法的关键就在于,对于重复出现的子问题,只在第一次遇到时加以求解,并把答案保存起来,让以后再遇到时直接引用,不 必重新求解12、动态规划算法的基本步骤设计一个标准的动态规划算法,通常可按以下几个步骤进行:(1) 划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段注意这 若干个阶段一定要是有序的或者是可排序的(即无后向性),否则问题就无法用 动态规划求解。
2) 选择状态:将问题发展到各个阶段时所处于的各种客观情况用不同的状态 表示出来当然,状态的选择要满足无后效性3) 确定决策并写出状态转移方程:之所以把这两步放在一起,是因为决策和 状态转移有着天然的联系,状态转移就是根据上一阶段的状态和决策来导出本阶 段的状态所以,如果我们确定了决策,状态转移方程也就写出来了但事实上, 我们常常是反过来做,根据相邻两段的各状态之间的关系来确定决策4) 写出规划方程(包括边界条件):动态规划的基本方程是规划方程的通用形 式化表达式一般说来,只要阶段、状态、决策和状态转移确定了,这一步还是比较简单的 动态规划的主要难点在于理论上的设计,一旦设计完成,实现部分就会非常简单 根据动态规划的基本方程可以直接递归计算最优值,但是一般将其改为递推计 算实际应用当中经常不显式地按照上面步骤设计动态规划,而是按以下几个步 骤进行:(1) 分析最优解的性质,并刻划其结构特征2) 递归地定义最优值3) 以自底向上的方式或自顶向下的记忆化方法(备忘录法)计算出最优值4) 根据计算最优值时得到的信息,构造一个最优解步骤(1)〜(3)是动态规划算法的基本步骤在只需要求出最优值的情形,步 骤(4)可以省略,若需要求出问题的一个最优解,则必须执行步骤0)。
此时, 在步骤(3)中计算最优值时,通常需记录更多的信息,以便在步骤0)中,根 据所记录的信息,快速地构造出一个最优解总结:动态规划实际上就是最优化的问题,是指将原问题的大实例等价于同 一最优化问题的较小实例,自底向上的求解最小实例,并将所求解存放起来,存 放的结果就是为了准备数据与递归相比,递归是不断的调用子程序求解,是自 顶向下的调用和求解13. 分治法与动态规划法的相同点是:将待求解的问题分解成若干个子问题,先求解子问题,然后从这些子问题的 解得到原问题的解两者的不同点是:适合于用动态规划法求解的问题,经分解得到的子问题往 往不是互相独立的而用分治法求解的问题,经分解得到的子问题往往是互相独 立的14. 回溯法回溯法也称为试探法,该方法首先暂时放弃关于问题规模大小的限 制,并将问题的候选解按某种顺序逐一枚举和检验当发现当前候选解不可能是 解时,就选择下一个候选解;倘若当前候选解除了还不满足问题规模要求外,满 足所有其他要求时,继续扩大当前候选解的规模,并继续试探如果当前候选解 满足包括问题规模在内的所有要求时,该候选解就是问题的一个解在回溯法中, 放弃当前候选解,寻找下一个候选解的过程称为回溯。
扩大当前候选解的规模, 以继续试探的过程称为向前试探15. 分支限界法:这是一种用于求解组合优化问题的排除非解的搜索算法类似于回溯法,分 枝定界法在搜索解空间时,也经常使用树形结构来组织解空间然而与回溯法不 同的是,回溯算法使用深度优先方法搜索树结构,而分枝定界一般用宽度优先或 最小耗费方法来搜索这些树因此,可以很容易比较回溯法与分枝定界法的异同 相对而言,分枝定界算法的解空间比回溯法大得多,因此当内存容量有限时,回 溯法成功的可能性更大算法思想:分枝限界(branch and bound)是另一种系统地搜索解空间的方 法,它与回溯法的主要区别在于对E-节点的扩充方式每个活节点有且仅有一 次机会变成E-节点当一个节点变为E-节点时,则生成从该节点移动一步即可 到达的所有新节点在生成的节点中,抛弃那些不可能导出(最优)可行解的节 点,其余节点加入活节点表,然后从表中选择一个节点作为下一个E-节点从 活节点表中取出所选择的节点并进行扩充,直到找到解或活动表为空,扩充过程 才结束有两种常用的方法可用来选择下一个E-节点(虽然也可能存在其他的方法):1) 先进先出(F I F 0)即从活节点表中取出节点的顺序与加入节点的顺序相 同,因此活节点表的性质与队列相同。
2) (优先队列)最小耗费或最大收益法在这种模式中,每个节点都有一个对应 的耗费或收益如果查找一个具有最小耗费的解,则活节点表可用最小堆来建 立,下一个E-节点就是具有最小耗费的活节点;如果希望搜索一个具有最大收 益的解,则可用最大堆来构造活节点表,下一个E-节点是具有最大收益的活节 点16. 分支限界法与回溯法的相同点是:都是一种在问题的解空间树T中搜索 问题解的算法不同点:(1)求解目标不同;(2) 搜索方式不同;(3) 对扩展结点的扩展方式不同;(4) 存储空间的要求不同17. 分治法所能解决的问题一般具有的几个特征是:(1) 该问题的规模缩小到一定的程度就可以容易地解决;(2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子 结构性质;(3) 利用该问题分解出的子问题的解可以合并为该问题的解;(4) 原问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共 的子问题18. 用分支限界法设计算法的步骤是:(1)针对所给问题,定义问题的解空间(对解进行编码);(2) 确定易于搜索的解空间结构(按树或图组织解);(3) 以广度优先或以最小耗费(最大收益)优先的方式搜索解空间,并在搜索 过程中用剪枝函数避免无效搜索。
19. 常见的两种分支限界法的算法框架:(1) 队列式(FIFO)分支限界法:按照队列先进先出(FIFO)原则选取下一个 节点为扩展节点2) 优先队列式分支限界法:按照优先队列中规定的优先级选取优先级最高 的节点成为当前扩展节点20. 回溯法中常见的两类典型的解空间树是子集树和排列树当所给的问题是从n个元素的集合S中找出满足某种性质的子集时,相应 的解空间树称为子集树这类子集树通常有2n个叶结点,遍历子集树需O(2n) 计算时间当所给的问题是确定n个元素满足某种性质的排列时,相应的解空间树称 为排列树这类排列树通常有n!个叶结点遍历排列树需要O(n!)计算时间21. 分支限界法的搜索策略是:在扩展结点处,先生成其所有的儿子结点(分支),然后再从当前的活结点 表中选择下一个扩展结点为了有效地选择下一扩展结点,加速搜索的进程,在 每一个活结点处,计算一个函数值(限界),并根据函数值,从当前活结点表中 选择一个最有利的结点作为扩展结点,使搜索朝着解空间上有最优解的分支推 进,以便尽快地找出一个最优解22. 请叙述动态规划算法与贪心算法的异同共同点:都需要最优子结构性质,都用来求有优化问题不同点:动态规划:每一步作一个选择一依赖于子问题的解。
贪心方法:每一步作一个选择一不依赖于子问题的解动态规划方法的条件:子问题的重叠性质可用贪心方法的条件:最优子结构性质;贪心选择性质动态规划:自底向上求解;贪心方法:自顶向下求解可用贪心法时,动态规划方法可能不适用;可用动态规划方法时,贪心法可能不适用23. 请说明动态规划方法为什么需要最优子结构性质答:最优子结构性质是指大问题的最优解包含子问题的最优解动态规划方法是自底向上计算各个子问题的最优解,即先计算子问题的最优 解,然后再利用子问题的最优解构造大问题的最优解,因此需要最优子结构.24. 请说明:(1) 优先队列可用什么数据结构实现?(2) 优先队列插入算法基本思想?(3) 优先队列插入算法时间复杂度?答:(1)堆2)在小根堆中,将元素x插入到堆的末尾,然后将元素x的关键字与其双亲的关键字比较,若元素x的关键字小于其双亲的关键字,则将元素x与其双亲交换,然后再将元素x与其新双亲的关键字相比, 直到元素x的关键字大于双亲的关键字,或元素x到根为止3) 0( log n)25. 衡量算法时间效率的方法有哪两种?请叙述答:有事前分析法和事后分析法两种事后分析法:先将算法用程序设计语言实现,然后度量程序的运行时间。
事前分析法:算法的时间效率是问题规模的函数,假如,随着问题规模n的增长, 算法执行时间的增长率和函数f(n)的增长率相同,则可记作:T(n)=O(f(n))称T(n)为算法的渐进时间复杂度简称时间复杂度26. 在算法复杂性分析中,O、Q、®这三个记号的意义是什么?在忽略常数 因子的情况下,O、Q、®分别提供了算法运行时间的什么界?答:如果存在两个正常数c和N0,对于所有的NNN0,有|f(N)| WC|g(N)|,则记作: f(N)=O(g(N))这时我们说f(N)的阶不高于g(N)的阶若存在两个正常数C和自然数N0,使得当N N N0时有|f(N)|NC|g(N)|,记为 f(N)= (g(N))这时我们说f(N)的阶不低于g(N)的阶如果存在正常数cl, c2和n0,对于所有的nNn0,有cl|g(N)| W|f(N)| W c2|g(N)|则记作 f(N)= (g,(N))O、Q、Q分别提供了算法运行时间的上界、下界、平均27. 概率算法§ § § 很多算法的每一个计算步骤都是固定的,而概率算法允许算法在执行的过程中随机选择下一个计算步骤许多情况下,当算法在执行过 程中面临一个选择时,随机性选择常比最优选择省时。
因此概率算法可在 很大程度上降低算法的复杂度28. 概率算法的一个基本特征是对所求解问题的同一实例用同一概率算法求解两次可能得到完全不 同的效果这两次求解问题所需的时间甚至所得到的结果可能会有相当大 的差别29. 概率算法大致分为四类:数值概率算法,蒙特卡罗(Monte Carlo )算法,拉斯维加斯(Las Vegas ) 算法和舍伍德(Sherwood )算法30. 数值概率算法常用于数值问题的求解这类算法所得到的往往是近似解而且近似 解的精度随计算时间的增加不断提高在许多情况下,要计算出问题的精 确解是不可能或没有必要的,因此用数值概率算法可得到相当满意的解31. 蒙特卡罗算法用于求问题的准确解对于许多问题来说,近似解毫无意义例如,一 个判定问题其解为“是”或“否”,二者必居其一,不存在任何近似解答 又如,我们要求一个整数的因子时所给出的解答必须是准确的,一个整数 的近似因子没有任何意义用蒙特卡罗算法能求得问题的一个解,但这个 解未必是正确的求得正确解的概率依赖于算法所用的时间算法所用的 时间越多,得到正确解的概率就越高蒙特卡罗算法的主要缺点就在于此 一般情况下,无法有效判断得到的解是否肯定正确。
32. 拉斯维加斯算法不会得到不正确的解,一旦用拉斯维加斯算法找到一个解,那么这个解 肯定是正确的但是有时候用拉斯维加斯算法可能找不到解与蒙特卡罗 算法类似拉斯维加斯算法得到正确解的概率随着它用的计算时间的增加 而提高对于所求解问题的任一实例,用同一拉斯维加斯算法反复对该实 例求解足够多次,可使求解失效的概率任意小33. 舍伍德算法总能求得问题的一个解,且所求得的解总是正确的当一个确定性算法 在最坏情况下的计算复杂性与其在平均情况下的计算复杂性有较大差别 时,可以在这个确定算法中引入随机性将它改造成一个舍伍德算法,消除 或减少问题的好坏实例间的这种差别舍伍德算法精髓不是避免算法的最 坏情况行为,而是设法消除这种最坏行为与特定实例之间的关联性舍伍德算法 sherwood algorithm舍伍德算法一类概率算法的代称此类算法总能给出所求问题的正确的解 当解决某一问题的确定性算法的平均情形复杂性比最坏情形复杂性低得多时,通 过引入随机性来试图减少甚至消除“好”、“坏”实体之间这种时间上的差别, 以期望较小的运行时间例...五、算法设计与分析题1. 用动态规划策略求解最长公共子序列问题:(1) 给出计算最优值的递归方程。
2) 给定两个序列X={B,C,D,A}, Y={A,B,C,B},请采用动态规划策略求出 其最长公共子序列,要求给出过程答:(1)'0 当i=0或j=0时c[i, j] = < c[i -1, j -1] +1 当 i,j〉0且 Xj = Yj时、max(c[i, j- 1],c[i - 1,j])当 i,j〉0且 Xi 丰 Yj时(2)YABCBX0.000B00\*11C001' 2r2D0012j2A01122 最长公共子序列:{BC2. 对下列各组函数 f (n)和 g (n),确定 f (n)=O(g(n))或 f (n)=Q (g (n))或 f(n) = Q (g(n)),并简要说明理由1) f(n)=2n ;g(n)=n!(2) f(n)=$;g (n) = log n2(3) f(n)=100;g(n) = log100(4) f(n)=n3;g(n)= 3n⑸ f(n)=3 n ;g(n)=2n答:(1)f(n)= O(g(n))因为g(n)的阶比f(n)的阶高2)f(n)= Q (g(n))因为g(n)的阶比f(n)的阶低3)f(n) = q (g(n))因为g(n)与f(n)同阶。
4)f(n)= O(g(n))因为g(n)的阶比f(n)的阶高5)f(n)= Q (g(n))因为g(n)的阶比f(n)的阶低3.对下图所示的连通网络G,用克鲁斯卡尔(Kruskal)算法求G的最小生成树T, 请写出在算法执行过程中,依次加入T的边集TE中的边说明该算法的贪心策 略和算法的基本思想,并简要分析算法的时间复杂度答:TE={(3,4), (2,3),(1,5), (4,6) (4,5) }贪心策略是每次都在连接两个不同连通分量的边中选权值最小的边基本思想:首先将图中所有顶点都放到生成树中,然后每次都在连接两个不 同连通分量的边中选权值最小的边,将其放入生成树中,直到生成树中有n-1 条边时间复杂度为:O(eloge)4.请用分治策略设计递归的归并排序算法,并分析其时间复杂性(要求:分别 给出divide、conquer> combine这三个阶段所花的时间,并在此基础上列出递 归方程,最后用套用公式法求出其解的渐进阶)答 : Template void MergeSort (Type a[ ], int left, int right){ if (left 1用套用公式法:a=2, b=2, niogba 二 n , f(n)=n, 因为 f(n)与 niogba 同阶,T(n)=® (nlogn)5、设有n=2k个运动员要进行循环赛,现设计一个满足以下要求的比赛日程表: 每个选手必须与其他n-1名选手比赛各一次;每个选手一天至多只能赛一次;循环赛要在最短时间内完成.(1) (4分)循环赛最少需要进行(n-1 )天.(2) (6分)当n=23=8时,请画出循环赛日程表:1 2 3 4 5 6 712345678214365873412785643218765567812346587214378563412876543216、考虑用哈夫曼算法来找字符a,b,c,d,e,f的最优编码。
这些字符出现在文件 中的频数之比为20:10:6:4:44:16要求:(1) (4分)简述使用哈夫曼算法构造最优编码的基本步骤;(2) (5分)构造对应的哈夫曼树,并据此给出a,b,c,d,e,f的一种最优编码解:1)、哈夫曼算法是构造最优编码树的贪心算法其基本思想是,首先所 有字符对应n棵树构成的森林,每棵树只有一个结点,根权为对应字符的频率然后,重复下列过程n-1次:将森林中的根权最小的两棵树进行合并产生一个新树,该新树 根的两个子树分别是参与合并的两棵子树,根权为两个子树根权之和2)、根据题中数据构造哈夫曼树如下图所示d由此可以得出a,b,c,d,e,f的一组最优的编码:01,0000,00010,00011, 1,0017. 考虑在序列A[1..n]中找最大最小元素的问题一个分治算法描述如下:如果n W2就直接求解否则,将序列等分成两个子序列A[1..n/2]和A[n/2+1..n],分 别找出这两子序列的最大最小元素x1,y1和x2,y2;然后据此求出A[1..n]的最大 元素x=max{x1,x2}及最小元素y=min{y1,y2}请给出该算法计算时间T(n)满足的 递归方程,并解方程来确定算法的时间复杂度。
假定n=2k(k为正整数)答:算法时间复杂度满足如下递归方程:T(n)=2T(n/2)+2(n>2); T(2)二1因为n=2 k(k为正整数),所以,T(n)= T(2 k)= 2T(2 k-1)+2= 2?T(2 k-2)+ 22+2= 2k-1T(2)+ 2k-2+••• +23+22+2=2k-1+- +23+22+2因此,T(n)= (n)8. 考虑使用动态规划方法求解下列问题:01背包数据如下表,求:能够放入背包的最有价值的物品集合物品i重量wi价值vi承重量W1w1=2v1=12W=52w2=1v2=103w3=3v3=204w4=2v4=15如设:V(i, j) —— 前i个物品中能够装入承重量j的背包中的最大总 价值请将如下递推式填写完整:V(0, j)= 0(0个物品),V(i, 0)= 0 (承重量0)V(i, j)=V(i-1, j) 第i个物品不能装入,j < wi (超重)V(i, j) = max {, } j > wi (不超重) i在最优子集中 i不在最优子集中自底向上:按行或列填写下表Vj=012345i=000000010203040答:V(0, j)= 0 (0个物品),V(i, 0)= 0 (承重量0)V(i, j)=V(i-1, j) 第i个物品不能装入,j < wi (超重)V(i, j) = max { v + V(i-1,j-w), V(i-1, j)} j > wi(不超重)i在最优子集中 i不在最优子集中Vj=012345i=0000000100121212122010122222223010122230324010152530379. 请画出用回溯法解4皇后问题的解空间树和搜索空间树:解空间树:用回溯法的搜索空间树:10. 考虑用分支限界解0-1背包问题给定n种物品和一背包。
物品i的重量是wi,其价值为vi,背包的容量为C问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?示例:n=3, C=30, w={16, 15, 15}, v={45, 25, 25}求:1、问题的解空间树2、约束条件2、如何剪枝?解:问题的解空间树:约束条件:Z wx < ci=1如何剪枝?:设r是当前尚未考虑的剩余物品价值总和;Cv是当前价值;bestv是当前最 优价值当r + CvWbestv时,可剪去右子树11 ,请画出用回溯法解n=3的0-1背包问题的解空间树和当三个物品的重量为{20, 15,10}, 价值为{20, 30, 25},背包容量为25时搜索空间树答:解空间树:搜索空间树:不可行解 价值=20价值=55价值=30价值=25价值=0。