算法设计与分析.docx
《算法设计与分析.docx》由会员分享,可在线阅读,更多相关《算法设计与分析.docx(13页珍藏版)》请在冰点文库上搜索。
算法设计与分析
一填空题
1.一个计算机算法的指令序列需要满足性质的是输入、输出、确定性、有限性。
输入、输出、确定性、有限性
2.
的渐近表达式是O(n2)
3.下面程序段的时间复杂度是O(n2)
for(i=0;ifor(j=0;j4.求两个n阶矩形的乘法C=A*B,其算法如下:#defineMAX100voidmaxtrixmult(intn,floata[MAX][MAX],floatc[MAX][MAX]){inti,j,k;floatx;for(i=1;i<=n;i++)8{for(j=1;j<=n;j++){x=0;for(k=1;k<=n;k++)x+=a[i][k]*b[k][j];c[i][j]=x;}}}该算法的时间复杂度为O(n3)5.通常用来表示时间算法的有以下六种多项式:按从小到大的顺序排列6.快速排序算法是基于分治策略的一个算法。其基本思想是,对于输入的子数组a[p:r],按以下3个步骤进行排序:分解、递归求解、合并。7.合并排序算法的基本思想是将待排序的元素分成大小大致相等的2个子集合,分别对两个子集合排序,最终将排好序的子集合合并成为所要求的集合。7.最优装载问题可用贪心算法求解。采用重量最轻者先装的贪心选择策略,可产生最优装载问题的最优解。8.贪心算法和动态规划算法都要求问题具有最优子结构性质。这是两类算法的一个共同点。9.动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式做出相继的贪心选择,每做出一次贪心选择就将所求问题简化为规模更小的子问题。计算机的资源,最重要的是时间和空间资源。因而,算法的复杂性有时间、空间之分。10.算法的时间复杂性函数用T(n)表示,它是的函数。11.f(n)=O(g(n))表示当且仅当存在正的常数C和N0,使得对于所有的n>=No,有f(n)12.写出下列f(n)的渐进性态:f(n)=C0,为常数:f(n)=O(1)f(n)=3n+2:f(n)=O(n)f(n)=6*2n+n:f(n)=O(2n)13.贪心方法是一种求最优解方法。它首先根据题意,选取一种度量标准。然后按这种度量标准对这N个输入排序,并按序一次选入一个量。如果这个输入量的加入,不满足约束条件,则不把此输入加到这部分解中。选择能产生问题最优解的度量标准是使用贪心法设计求解的核心问题。14.最优子结构性质:。15.子问题重叠性质:。16.背包问题可以获得最优解的输入排序是按价值密度排序。二选择题1.直接或间接的调用自身的算法称为A。A递归算法B贪心算法C迭代算法D动态规划算法2.阶乘函数用递归定义Publicstaticintfactorial(intn){if(n==0)return1;returnB;}An*factorial(n)Bn*factorial(n-1)Cn*factorial(n-2)Dn*factorial(n+1)3.与分治法不同的是,适合于用动态规划求解的问题,DA经分解得到子问题往往是任意的B经分解得到子问题往往是互相独立的C经分解得到子问题往往是互相交叉的D经分解得到子问题往往不是互相独立的4.合并排序法的基本思想是:将待排序元素分成大小大致相同的C个子集合,分别对每个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合。A4B3C2D55.二分搜索算法的基本思想是将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较:如果(C),则只要在数组a的右半部继续搜索x。Ax<a[n/2]Bx=a[n/2]Cx>a[n/2]Dx>=a[n/2]6.当问题的规模n趋向无穷大时,B的数量级(阶)称为算法的渐进时间复杂度。A空间复杂度B时间复杂度C冗余度D迭代次数7.实现快速排序算法如下:privatestaticvoidquickSort(intp,intr){ if(p { intq=partition(p,r);//以确定的基准元素a[p]对//子数组a[p;r]进行划分 A//对左半段排序 quickSort(q+1,r);//对右半段排序 }}AquickSort(p,q-1)BquickSort(p+1,q-1)CquickSort(p,q+1)DquickSort(p,q-2)8.计算机算法指的是CA.计算方法B.排序方法C.解决问题的方法和过程D.调度方法9.在动态规划算法中,问题的最优子结构性质使我们能够以D的方式递归地从子问题的最优解逐步构造出整个问题的最优解。A自左向右B自右向左C自上向下D自底向上10.用贪心法解最优装载问题的时候,我们采用的贪心选择的策略是CA重量大者先装B总价值大的先装C重量轻者先装D单位价值大的先装三、判断题1.从分治法的一般设计模式可以看出,用它设计出的程序一般是一个递归过程。因此,分治法的计算效率通常可以用递归方程来进行分析。(对)2.对同一个问题,动态规划算法和分治算法的计算复杂性是一样的。(错)3.0-1背包问题与背包问题这两类问题都可以用贪心算法求解。(错)4.分治法的基本思想是将一个规模较大的问题分解成若干个规模较小的子问题,这些子问题之间并不一定相互独立。(错)5.通常用T(n)来表示某一算法的“时间复杂性”,当输入量n逐渐增大时,时间复杂性的极限称为算法的“渐近时间复杂性”。(对)6.证明贪心选择后的问题简化为规模更小的类似子问题的关键在于利用该问题的最优子结构性质。(对)7.,其中P是一个正的常数。(对)8.贪心算法能对所有问题都得到整体最优解。(错)四、简述题1、请简述动态规划算法解题通常包含的四个步骤:答:1、找出最优解的性质,并刻画其结构特征;2、递归地定义最优值(写出动态规划方程);3、以自底向上的方式计算出最优值;4、根据计算最优值时得到的信息,构造一个最优解。2、试简述二分搜索算法的基本思想答:二分搜索算法的基本思想是将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较:如果x>a[n/2],则只要在数组a的右半部继续搜索x。3、用PRIM算法求下列带权图的最小生成树,要求画出选边的具体过程。答:最终结果为(g)或(h)都是正确的。4、用Kruskal算法求所给的下列图像的最小生成树,并画出选边的过程。答:五、问答题1、有n种不同的货物,规定每种最多只能拿一件,车容量为c,第i件货物占空间为wi(0<=i<=n),价值为pi(0<=i<=n),目标为装载的物品价值最大。请用下述不同的贪婪装载策略求解。1.有n种不同的货物,规定每种最多只能拿一件,车容量为c,第i件货物占空间为wi(0<=i<=n),价值为pi(0<=i<=n),目标为装载的物品价值最大。请用下述不同的贪婪装载策略求解。1)贪婪策略1:从剩余的物品中选择价值最大的物品。设n=3,w=[55,30,40],p=[30,20,15],c=80;2)贪婪策略2:从剩余的物品中选择占空间最小的物品。设n=3,w=[10,20,15],p=[5,25,10],c=25;3)贪婪策略3:从剩余的物品中选择价值密度最大(pi/wi)的物品。设n=3,w=[25,15,15],p=[40,25,25],c=35;4)分析不同策略的解,它们是最优解吗?如果不是,请直接写出最优解。5)用C语言或伪代码分别描述上述三个算法。答:首先确定问题的实质,是0-1背包问题而不是最优装载问题。最优装载问题的前提是重量受限制,而体积不受限制。伪代码:voidGreedyMethod{将问题的输入按贪心规则排序;For每个输入R[i]IfR[i]满足约束条件then加入解;Else抛弃;Endfor}上述三种策略,分别给出了三种对输入的排序规则:按价值最大、按占用空间最小、按价值密度最大。对于利用贪心策略解决0-1被包问题,很显然,只能得到局部最优解,而不能得到全局最优解。如果将问题进行以下变通,即从0-1背包问题变为背包问题,这样,就可以在装包的过程中,将物品i的一部分装入包中。书中第P90页给出了证明,即选择价值密度最大的贪心策略产生的解是全局最优解。因此,按此种方法产生的最优解也是0-1背包问题解的上界。2.有n=32个硬币,其中1个是假币,且假币较重。用分而治之方法设计一个找出假币的算法。1)请写出求解的步骤;2)用C程序或伪代码描述算法。答:将硬币递归的分成两份,比较这两份的重量,重量重者含有假币,因此,该问题可以转化为二分搜索问题。利用分治法解决该问题的伪代码如下://------------------------------------------------------------------divide-and-conquer(P){if(|P|<=n0)adhoc(P);//解决小规模的问题dividePintosmallersubinstancesP1,P2,...,Pk;//分解问题for(i=1,i<=k,i++)yi=divide-and-conquer(Pi);//递归的解各子问题returnmerge(y1,...,yk);//将各子问题的解合并为原问题的解}//------------------------------------------------------------------1、划分(Divide):将原问题分解为若干个规模较小,相互独立,与原问题性质相同的子问题。2、解决(Conquer):若子问题规模较小,则直接求解;否则递归求解子问题。3、合并(merge):将各个子问题的解合并为原问题的解。该问题的递归表达式为:T(N)=当n=2时,即每一份只有一枚硬币,比较一次,重者为假币。3.定义0/1背包问题为:。限制条件为:,且。设f(i,y)表示剩余容量为y,剩余物品为:i,i+1,…,n时的最优解的值。1)给出f(i,y)的递推表达式;2)设W=[10,20,30],P=[6,10,18],c=38,请用该递推表达式求解,要求写出计算过程。答:问题同第9题。4.子集和问题:对于集合S={3,4,2,5},求子集,要求该子集的元素之和d=9。1)画出子集和问题的解空间树;2)对该树用回溯算法求解,并写出依回溯算法遍历节点的序列;3)对该树用FIFO分枝定界法求解,并写出依该算法遍历节点的序列;4)用C语言或伪代码描述求解子集和问题的回溯算法;5)用C语言或伪代码描述求解子集和问题的FIFO分枝定界算法。答:利用回溯法解问题,首先要画出解空间树。集合S的子集合为:{3},{3,4}{3,4,2}{3,4,2,5}等。S的子集树如下图所示:1)回溯法的伪代码:voidbacktrack(intt){if(t>n)output(x);elsefor(inti=f(n,t);i<=g(n,t);i++){x[t]=h(i);if(d=9or遇到叶子节点)backtrack(t+1);}}按照深度优先的策略对子集树进行遍历,在遍历过程中,如果d已经等于9,则马上回溯,返回到父节点,继续按照深度优先的策略进行遍历。(图中节点没有用字母标识,故没有写出遍历节点路径。)通过遍历得到在子集树中,有两个分枝满足条件d=9,分别是{3,4,2}和{-,4,-,5}。从子集树可以看出,它和0-1背包问题的解集树相同,是一棵完全二叉树,左子树为1,右子树为0。该问题可以转化为类0-1背包问题,即{3,4,2,5}四个数中选出几个数,使得和为9。2)分枝限界解法由于该问题不是求取最优解,而是搜索满足约束条件的解,因此,利用分枝限界和利用回溯法只在搜索的策略上有所区别,并没有提高搜索效率。利用分枝限界法,需要额外提供活节点表来保存待扩展的节点。该题S中的元素太多,假如S={1,2,3}要求满足d=3,问题性质没变,子集树简单了一些,但同样能说明问题。伪代码://---------------------------------------------------------------------procedureDDif根节点T是答案节点then输出T;returnendifelse初始化活节点表L,置为空loopforE的每个子节点XDOifX是答案节点then输出从X到T的路径rethrnendifcallADD(X)//新的活节点X加入Lparent(X)=E//指示到根的路径repeatif不再有活节点thenprint('noanswernode');breakendifrepeatendLC//---------------------------------------------------------------------利用分枝限界解策略,剪枝条件d=3对活节点表起作用,在对活节点进行扩展之前,先检验其是否满足约束条件,如果满足,则对其扩展,否则杀死该节点。活节点表L按照FIFO原则进行扩展。上图被矩形框覆盖的区域是被剪枝的分枝。如L={D,E,F,G},对D进行扩展,检验d,发现其已经等于3,故杀死D,L变为{E,F,G}。5.旅行商问题:给出一个n个顶点网络(有向或无向),要求找出一个包含所有n个顶点的具有最小耗费的环路。任何一个包含所有n个顶点的环路被称作一个旅行。在旅行商问题中,要设法找到一条最小耗费的旅行。1)对图示的例,画出旅行商问题的解空间树;2)对该树运用回溯算法,写出依回溯算法遍历节点的顺序表及节点。确定回溯算法未遍历的节点。对应的解集树如下图所示:6.子集和问题:对于集合S={1,2,5,6,8},求子集,要求该子集的元素之和d=9。a)画出子集和问题的解空间树;b)对该树运用回溯算法,写出依回溯算法遍历节点的顺序表及节点。确定回溯算法未遍历的节点;c)如果S中有n个元素,指定d,用伪代码写出求解子集和问题的回溯算法。见第4题。7.旅行商问题:给出一个n个顶点的网络,要求找出一个包含所有n个顶点的具有最小耗费的环路。1)对图示的例,画出旅行商问题的解空间树;2)对该树用FIFO分枝定界法求解,并写出依该算法遍历节点的顺序表;3)用C语言或伪代码描述旅行商问题的FIFO分枝定界算法。8.设要计算矩阵连乘积,其中各矩阵的维数分别为:30X3535X1515X55X1010X2020X25利用动态规划算法计算矩阵连乘过程中,得出的计算次序如下图所示:试根据递归式:见教材p44。9.用动态规划解下列0-1背包问题例题:n=3,w=[100,14,10],p=[20,18,15],c=116。假设表示的是背包容量为,可选择物品为时0-1背包问题的最优值。由0-1背包问题的最优子结构性质,可以建立计算的递归式如下:答:1.由题意:2.利用递归式,可得:因此最优解m(1,116)=max{m(2,116),m(2,116-w1)+p1}=max{m(2,116),m(2,16)+20}=max{33,38}=38现在计算x1值,步骤如下:若m(1,c)=m(2,c),则x1=0;否则x1=1。接下来计算x2:m(2,c-w1)=m(3,c-w1)?依次类推得到x3,┅,xn该例中,m(2,116)=33≠m(1,116),所以x1=1。因剩余容量=116-100=16,又因m(2,16)=18,而m(3,16)=14≠m(2,16),因此x2=1;此时r=16-14=2,不足以放物品3,所以x3=0。
for(j=0;j4.求两个n阶矩形的乘法C=A*B,其算法如下:#defineMAX100voidmaxtrixmult(intn,floata[MAX][MAX],floatc[MAX][MAX]){inti,j,k;floatx;for(i=1;i<=n;i++)8{for(j=1;j<=n;j++){x=0;for(k=1;k<=n;k++)x+=a[i][k]*b[k][j];c[i][j]=x;}}}该算法的时间复杂度为O(n3)5.通常用来表示时间算法的有以下六种多项式:按从小到大的顺序排列6.快速排序算法是基于分治策略的一个算法。其基本思想是,对于输入的子数组a[p:r],按以下3个步骤进行排序:分解、递归求解、合并。7.合并排序算法的基本思想是将待排序的元素分成大小大致相等的2个子集合,分别对两个子集合排序,最终将排好序的子集合合并成为所要求的集合。7.最优装载问题可用贪心算法求解。采用重量最轻者先装的贪心选择策略,可产生最优装载问题的最优解。8.贪心算法和动态规划算法都要求问题具有最优子结构性质。这是两类算法的一个共同点。9.动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式做出相继的贪心选择,每做出一次贪心选择就将所求问题简化为规模更小的子问题。计算机的资源,最重要的是时间和空间资源。因而,算法的复杂性有时间、空间之分。10.算法的时间复杂性函数用T(n)表示,它是的函数。11.f(n)=O(g(n))表示当且仅当存在正的常数C和N0,使得对于所有的n>=No,有f(n)12.写出下列f(n)的渐进性态:f(n)=C0,为常数:f(n)=O(1)f(n)=3n+2:f(n)=O(n)f(n)=6*2n+n:f(n)=O(2n)13.贪心方法是一种求最优解方法。它首先根据题意,选取一种度量标准。然后按这种度量标准对这N个输入排序,并按序一次选入一个量。如果这个输入量的加入,不满足约束条件,则不把此输入加到这部分解中。选择能产生问题最优解的度量标准是使用贪心法设计求解的核心问题。14.最优子结构性质:。15.子问题重叠性质:。16.背包问题可以获得最优解的输入排序是按价值密度排序。二选择题1.直接或间接的调用自身的算法称为A。A递归算法B贪心算法C迭代算法D动态规划算法2.阶乘函数用递归定义Publicstaticintfactorial(intn){if(n==0)return1;returnB;}An*factorial(n)Bn*factorial(n-1)Cn*factorial(n-2)Dn*factorial(n+1)3.与分治法不同的是,适合于用动态规划求解的问题,DA经分解得到子问题往往是任意的B经分解得到子问题往往是互相独立的C经分解得到子问题往往是互相交叉的D经分解得到子问题往往不是互相独立的4.合并排序法的基本思想是:将待排序元素分成大小大致相同的C个子集合,分别对每个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合。A4B3C2D55.二分搜索算法的基本思想是将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较:如果(C),则只要在数组a的右半部继续搜索x。Ax<a[n/2]Bx=a[n/2]Cx>a[n/2]Dx>=a[n/2]6.当问题的规模n趋向无穷大时,B的数量级(阶)称为算法的渐进时间复杂度。A空间复杂度B时间复杂度C冗余度D迭代次数7.实现快速排序算法如下:privatestaticvoidquickSort(intp,intr){ if(p { intq=partition(p,r);//以确定的基准元素a[p]对//子数组a[p;r]进行划分 A//对左半段排序 quickSort(q+1,r);//对右半段排序 }}AquickSort(p,q-1)BquickSort(p+1,q-1)CquickSort(p,q+1)DquickSort(p,q-2)8.计算机算法指的是CA.计算方法B.排序方法C.解决问题的方法和过程D.调度方法9.在动态规划算法中,问题的最优子结构性质使我们能够以D的方式递归地从子问题的最优解逐步构造出整个问题的最优解。A自左向右B自右向左C自上向下D自底向上10.用贪心法解最优装载问题的时候,我们采用的贪心选择的策略是CA重量大者先装B总价值大的先装C重量轻者先装D单位价值大的先装三、判断题1.从分治法的一般设计模式可以看出,用它设计出的程序一般是一个递归过程。因此,分治法的计算效率通常可以用递归方程来进行分析。(对)2.对同一个问题,动态规划算法和分治算法的计算复杂性是一样的。(错)3.0-1背包问题与背包问题这两类问题都可以用贪心算法求解。(错)4.分治法的基本思想是将一个规模较大的问题分解成若干个规模较小的子问题,这些子问题之间并不一定相互独立。(错)5.通常用T(n)来表示某一算法的“时间复杂性”,当输入量n逐渐增大时,时间复杂性的极限称为算法的“渐近时间复杂性”。(对)6.证明贪心选择后的问题简化为规模更小的类似子问题的关键在于利用该问题的最优子结构性质。(对)7.,其中P是一个正的常数。(对)8.贪心算法能对所有问题都得到整体最优解。(错)四、简述题1、请简述动态规划算法解题通常包含的四个步骤:答:1、找出最优解的性质,并刻画其结构特征;2、递归地定义最优值(写出动态规划方程);3、以自底向上的方式计算出最优值;4、根据计算最优值时得到的信息,构造一个最优解。2、试简述二分搜索算法的基本思想答:二分搜索算法的基本思想是将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较:如果x>a[n/2],则只要在数组a的右半部继续搜索x。3、用PRIM算法求下列带权图的最小生成树,要求画出选边的具体过程。答:最终结果为(g)或(h)都是正确的。4、用Kruskal算法求所给的下列图像的最小生成树,并画出选边的过程。答:五、问答题1、有n种不同的货物,规定每种最多只能拿一件,车容量为c,第i件货物占空间为wi(0<=i<=n),价值为pi(0<=i<=n),目标为装载的物品价值最大。请用下述不同的贪婪装载策略求解。1.有n种不同的货物,规定每种最多只能拿一件,车容量为c,第i件货物占空间为wi(0<=i<=n),价值为pi(0<=i<=n),目标为装载的物品价值最大。请用下述不同的贪婪装载策略求解。1)贪婪策略1:从剩余的物品中选择价值最大的物品。设n=3,w=[55,30,40],p=[30,20,15],c=80;2)贪婪策略2:从剩余的物品中选择占空间最小的物品。设n=3,w=[10,20,15],p=[5,25,10],c=25;3)贪婪策略3:从剩余的物品中选择价值密度最大(pi/wi)的物品。设n=3,w=[25,15,15],p=[40,25,25],c=35;4)分析不同策略的解,它们是最优解吗?如果不是,请直接写出最优解。5)用C语言或伪代码分别描述上述三个算法。答:首先确定问题的实质,是0-1背包问题而不是最优装载问题。最优装载问题的前提是重量受限制,而体积不受限制。伪代码:voidGreedyMethod{将问题的输入按贪心规则排序;For每个输入R[i]IfR[i]满足约束条件then加入解;Else抛弃;Endfor}上述三种策略,分别给出了三种对输入的排序规则:按价值最大、按占用空间最小、按价值密度最大。对于利用贪心策略解决0-1被包问题,很显然,只能得到局部最优解,而不能得到全局最优解。如果将问题进行以下变通,即从0-1背包问题变为背包问题,这样,就可以在装包的过程中,将物品i的一部分装入包中。书中第P90页给出了证明,即选择价值密度最大的贪心策略产生的解是全局最优解。因此,按此种方法产生的最优解也是0-1背包问题解的上界。2.有n=32个硬币,其中1个是假币,且假币较重。用分而治之方法设计一个找出假币的算法。1)请写出求解的步骤;2)用C程序或伪代码描述算法。答:将硬币递归的分成两份,比较这两份的重量,重量重者含有假币,因此,该问题可以转化为二分搜索问题。利用分治法解决该问题的伪代码如下://------------------------------------------------------------------divide-and-conquer(P){if(|P|<=n0)adhoc(P);//解决小规模的问题dividePintosmallersubinstancesP1,P2,...,Pk;//分解问题for(i=1,i<=k,i++)yi=divide-and-conquer(Pi);//递归的解各子问题returnmerge(y1,...,yk);//将各子问题的解合并为原问题的解}//------------------------------------------------------------------1、划分(Divide):将原问题分解为若干个规模较小,相互独立,与原问题性质相同的子问题。2、解决(Conquer):若子问题规模较小,则直接求解;否则递归求解子问题。3、合并(merge):将各个子问题的解合并为原问题的解。该问题的递归表达式为:T(N)=当n=2时,即每一份只有一枚硬币,比较一次,重者为假币。3.定义0/1背包问题为:。限制条件为:,且。设f(i,y)表示剩余容量为y,剩余物品为:i,i+1,…,n时的最优解的值。1)给出f(i,y)的递推表达式;2)设W=[10,20,30],P=[6,10,18],c=38,请用该递推表达式求解,要求写出计算过程。答:问题同第9题。4.子集和问题:对于集合S={3,4,2,5},求子集,要求该子集的元素之和d=9。1)画出子集和问题的解空间树;2)对该树用回溯算法求解,并写出依回溯算法遍历节点的序列;3)对该树用FIFO分枝定界法求解,并写出依该算法遍历节点的序列;4)用C语言或伪代码描述求解子集和问题的回溯算法;5)用C语言或伪代码描述求解子集和问题的FIFO分枝定界算法。答:利用回溯法解问题,首先要画出解空间树。集合S的子集合为:{3},{3,4}{3,4,2}{3,4,2,5}等。S的子集树如下图所示:1)回溯法的伪代码:voidbacktrack(intt){if(t>n)output(x);elsefor(inti=f(n,t);i<=g(n,t);i++){x[t]=h(i);if(d=9or遇到叶子节点)backtrack(t+1);}}按照深度优先的策略对子集树进行遍历,在遍历过程中,如果d已经等于9,则马上回溯,返回到父节点,继续按照深度优先的策略进行遍历。(图中节点没有用字母标识,故没有写出遍历节点路径。)通过遍历得到在子集树中,有两个分枝满足条件d=9,分别是{3,4,2}和{-,4,-,5}。从子集树可以看出,它和0-1背包问题的解集树相同,是一棵完全二叉树,左子树为1,右子树为0。该问题可以转化为类0-1背包问题,即{3,4,2,5}四个数中选出几个数,使得和为9。2)分枝限界解法由于该问题不是求取最优解,而是搜索满足约束条件的解,因此,利用分枝限界和利用回溯法只在搜索的策略上有所区别,并没有提高搜索效率。利用分枝限界法,需要额外提供活节点表来保存待扩展的节点。该题S中的元素太多,假如S={1,2,3}要求满足d=3,问题性质没变,子集树简单了一些,但同样能说明问题。伪代码://---------------------------------------------------------------------procedureDDif根节点T是答案节点then输出T;returnendifelse初始化活节点表L,置为空loopforE的每个子节点XDOifX是答案节点then输出从X到T的路径rethrnendifcallADD(X)//新的活节点X加入Lparent(X)=E//指示到根的路径repeatif不再有活节点thenprint('noanswernode');breakendifrepeatendLC//---------------------------------------------------------------------利用分枝限界解策略,剪枝条件d=3对活节点表起作用,在对活节点进行扩展之前,先检验其是否满足约束条件,如果满足,则对其扩展,否则杀死该节点。活节点表L按照FIFO原则进行扩展。上图被矩形框覆盖的区域是被剪枝的分枝。如L={D,E,F,G},对D进行扩展,检验d,发现其已经等于3,故杀死D,L变为{E,F,G}。5.旅行商问题:给出一个n个顶点网络(有向或无向),要求找出一个包含所有n个顶点的具有最小耗费的环路。任何一个包含所有n个顶点的环路被称作一个旅行。在旅行商问题中,要设法找到一条最小耗费的旅行。1)对图示的例,画出旅行商问题的解空间树;2)对该树运用回溯算法,写出依回溯算法遍历节点的顺序表及节点。确定回溯算法未遍历的节点。对应的解集树如下图所示:6.子集和问题:对于集合S={1,2,5,6,8},求子集,要求该子集的元素之和d=9。a)画出子集和问题的解空间树;b)对该树运用回溯算法,写出依回溯算法遍历节点的顺序表及节点。确定回溯算法未遍历的节点;c)如果S中有n个元素,指定d,用伪代码写出求解子集和问题的回溯算法。见第4题。7.旅行商问题:给出一个n个顶点的网络,要求找出一个包含所有n个顶点的具有最小耗费的环路。1)对图示的例,画出旅行商问题的解空间树;2)对该树用FIFO分枝定界法求解,并写出依该算法遍历节点的顺序表;3)用C语言或伪代码描述旅行商问题的FIFO分枝定界算法。8.设要计算矩阵连乘积,其中各矩阵的维数分别为:30X3535X1515X55X1010X2020X25利用动态规划算法计算矩阵连乘过程中,得出的计算次序如下图所示:试根据递归式:见教材p44。9.用动态规划解下列0-1背包问题例题:n=3,w=[100,14,10],p=[20,18,15],c=116。假设表示的是背包容量为,可选择物品为时0-1背包问题的最优值。由0-1背包问题的最优子结构性质,可以建立计算的递归式如下:答:1.由题意:2.利用递归式,可得:因此最优解m(1,116)=max{m(2,116),m(2,116-w1)+p1}=max{m(2,116),m(2,16)+20}=max{33,38}=38现在计算x1值,步骤如下:若m(1,c)=m(2,c),则x1=0;否则x1=1。接下来计算x2:m(2,c-w1)=m(3,c-w1)?依次类推得到x3,┅,xn该例中,m(2,116)=33≠m(1,116),所以x1=1。因剩余容量=116-100=16,又因m(2,16)=18,而m(3,16)=14≠m(2,16),因此x2=1;此时r=16-14=2,不足以放物品3,所以x3=0。
4.求两个n阶矩形的乘法C=A*B,其算法如下:
#defineMAX100
voidmaxtrixmult(intn,floata[MAX][MAX],floatc[MAX][MAX])
{inti,j,k;floatx;
for(i=1;i<=n;i++)8
{for(j=1;j<=n;j++)
{x=0;
for(k=1;k<=n;k++)
x+=a[i][k]*b[k][j];
c[i][j]=x;
}
该算法的时间复杂度为O(n3)
5.通常用来表示时间算法的有以下六种多项式:
按从小到大的顺序排列
6.快速排序算法是基于分治策略的一个算法。
其基本思想是,对于输入的子数组a[p:
r],按以下3个步骤进行排序:
分解、递归求解、合并。
7.合并排序算法的基本思想是将待排序的元素分成大小大致相等的2个子集合,分别对两个子集合排序,最终将排好序的子集合合并成为所要求的集合。
7.最优装载问题可用贪心算法求解。
采用重量最轻者先装的贪心选择策略,可产生最优装载问题的最优解。
8.贪心算法和动态规划算法都要求问题具有最优子结构性质。
这是两类算法的一个共同点。
9.动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式做出相继的贪心选择,每做出一次贪心选择就将所求问题简化为规模更小的子问题。
计算机的资源,最重要的是时间和空间资源。
因而,算法的复杂性有时间、空间之分。
10.算法的时间复杂性函数用T(n)表示,它是的函数。
11.f(n)=O(g(n))表示当且仅当存在正的常数C和N0,使得对于所有的n>=No,有f(n)12.写出下列f(n)的渐进性态:f(n)=C0,为常数:f(n)=O(1)f(n)=3n+2:f(n)=O(n)f(n)=6*2n+n:f(n)=O(2n)13.贪心方法是一种求最优解方法。它首先根据题意,选取一种度量标准。然后按这种度量标准对这N个输入排序,并按序一次选入一个量。如果这个输入量的加入,不满足约束条件,则不把此输入加到这部分解中。选择能产生问题最优解的度量标准是使用贪心法设计求解的核心问题。14.最优子结构性质:。15.子问题重叠性质:。16.背包问题可以获得最优解的输入排序是按价值密度排序。二选择题1.直接或间接的调用自身的算法称为A。A递归算法B贪心算法C迭代算法D动态规划算法2.阶乘函数用递归定义Publicstaticintfactorial(intn){if(n==0)return1;returnB;}An*factorial(n)Bn*factorial(n-1)Cn*factorial(n-2)Dn*factorial(n+1)3.与分治法不同的是,适合于用动态规划求解的问题,DA经分解得到子问题往往是任意的B经分解得到子问题往往是互相独立的C经分解得到子问题往往是互相交叉的D经分解得到子问题往往不是互相独立的4.合并排序法的基本思想是:将待排序元素分成大小大致相同的C个子集合,分别对每个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合。A4B3C2D55.二分搜索算法的基本思想是将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较:如果(C),则只要在数组a的右半部继续搜索x。Ax<a[n/2]Bx=a[n/2]Cx>a[n/2]Dx>=a[n/2]6.当问题的规模n趋向无穷大时,B的数量级(阶)称为算法的渐进时间复杂度。A空间复杂度B时间复杂度C冗余度D迭代次数7.实现快速排序算法如下:privatestaticvoidquickSort(intp,intr){ if(p { intq=partition(p,r);//以确定的基准元素a[p]对//子数组a[p;r]进行划分 A//对左半段排序 quickSort(q+1,r);//对右半段排序 }}AquickSort(p,q-1)BquickSort(p+1,q-1)CquickSort(p,q+1)DquickSort(p,q-2)8.计算机算法指的是CA.计算方法B.排序方法C.解决问题的方法和过程D.调度方法9.在动态规划算法中,问题的最优子结构性质使我们能够以D的方式递归地从子问题的最优解逐步构造出整个问题的最优解。A自左向右B自右向左C自上向下D自底向上10.用贪心法解最优装载问题的时候,我们采用的贪心选择的策略是CA重量大者先装B总价值大的先装C重量轻者先装D单位价值大的先装三、判断题1.从分治法的一般设计模式可以看出,用它设计出的程序一般是一个递归过程。因此,分治法的计算效率通常可以用递归方程来进行分析。(对)2.对同一个问题,动态规划算法和分治算法的计算复杂性是一样的。(错)3.0-1背包问题与背包问题这两类问题都可以用贪心算法求解。(错)4.分治法的基本思想是将一个规模较大的问题分解成若干个规模较小的子问题,这些子问题之间并不一定相互独立。(错)5.通常用T(n)来表示某一算法的“时间复杂性”,当输入量n逐渐增大时,时间复杂性的极限称为算法的“渐近时间复杂性”。(对)6.证明贪心选择后的问题简化为规模更小的类似子问题的关键在于利用该问题的最优子结构性质。(对)7.,其中P是一个正的常数。(对)8.贪心算法能对所有问题都得到整体最优解。(错)四、简述题1、请简述动态规划算法解题通常包含的四个步骤:答:1、找出最优解的性质,并刻画其结构特征;2、递归地定义最优值(写出动态规划方程);3、以自底向上的方式计算出最优值;4、根据计算最优值时得到的信息,构造一个最优解。2、试简述二分搜索算法的基本思想答:二分搜索算法的基本思想是将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较:如果x>a[n/2],则只要在数组a的右半部继续搜索x。3、用PRIM算法求下列带权图的最小生成树,要求画出选边的具体过程。答:最终结果为(g)或(h)都是正确的。4、用Kruskal算法求所给的下列图像的最小生成树,并画出选边的过程。答:五、问答题1、有n种不同的货物,规定每种最多只能拿一件,车容量为c,第i件货物占空间为wi(0<=i<=n),价值为pi(0<=i<=n),目标为装载的物品价值最大。请用下述不同的贪婪装载策略求解。1.有n种不同的货物,规定每种最多只能拿一件,车容量为c,第i件货物占空间为wi(0<=i<=n),价值为pi(0<=i<=n),目标为装载的物品价值最大。请用下述不同的贪婪装载策略求解。1)贪婪策略1:从剩余的物品中选择价值最大的物品。设n=3,w=[55,30,40],p=[30,20,15],c=80;2)贪婪策略2:从剩余的物品中选择占空间最小的物品。设n=3,w=[10,20,15],p=[5,25,10],c=25;3)贪婪策略3:从剩余的物品中选择价值密度最大(pi/wi)的物品。设n=3,w=[25,15,15],p=[40,25,25],c=35;4)分析不同策略的解,它们是最优解吗?如果不是,请直接写出最优解。5)用C语言或伪代码分别描述上述三个算法。答:首先确定问题的实质,是0-1背包问题而不是最优装载问题。最优装载问题的前提是重量受限制,而体积不受限制。伪代码:voidGreedyMethod{将问题的输入按贪心规则排序;For每个输入R[i]IfR[i]满足约束条件then加入解;Else抛弃;Endfor}上述三种策略,分别给出了三种对输入的排序规则:按价值最大、按占用空间最小、按价值密度最大。对于利用贪心策略解决0-1被包问题,很显然,只能得到局部最优解,而不能得到全局最优解。如果将问题进行以下变通,即从0-1背包问题变为背包问题,这样,就可以在装包的过程中,将物品i的一部分装入包中。书中第P90页给出了证明,即选择价值密度最大的贪心策略产生的解是全局最优解。因此,按此种方法产生的最优解也是0-1背包问题解的上界。2.有n=32个硬币,其中1个是假币,且假币较重。用分而治之方法设计一个找出假币的算法。1)请写出求解的步骤;2)用C程序或伪代码描述算法。答:将硬币递归的分成两份,比较这两份的重量,重量重者含有假币,因此,该问题可以转化为二分搜索问题。利用分治法解决该问题的伪代码如下://------------------------------------------------------------------divide-and-conquer(P){if(|P|<=n0)adhoc(P);//解决小规模的问题dividePintosmallersubinstancesP1,P2,...,Pk;//分解问题for(i=1,i<=k,i++)yi=divide-and-conquer(Pi);//递归的解各子问题returnmerge(y1,...,yk);//将各子问题的解合并为原问题的解}//------------------------------------------------------------------1、划分(Divide):将原问题分解为若干个规模较小,相互独立,与原问题性质相同的子问题。2、解决(Conquer):若子问题规模较小,则直接求解;否则递归求解子问题。3、合并(merge):将各个子问题的解合并为原问题的解。该问题的递归表达式为:T(N)=当n=2时,即每一份只有一枚硬币,比较一次,重者为假币。3.定义0/1背包问题为:。限制条件为:,且。设f(i,y)表示剩余容量为y,剩余物品为:i,i+1,…,n时的最优解的值。1)给出f(i,y)的递推表达式;2)设W=[10,20,30],P=[6,10,18],c=38,请用该递推表达式求解,要求写出计算过程。答:问题同第9题。4.子集和问题:对于集合S={3,4,2,5},求子集,要求该子集的元素之和d=9。1)画出子集和问题的解空间树;2)对该树用回溯算法求解,并写出依回溯算法遍历节点的序列;3)对该树用FIFO分枝定界法求解,并写出依该算法遍历节点的序列;4)用C语言或伪代码描述求解子集和问题的回溯算法;5)用C语言或伪代码描述求解子集和问题的FIFO分枝定界算法。答:利用回溯法解问题,首先要画出解空间树。集合S的子集合为:{3},{3,4}{3,4,2}{3,4,2,5}等。S的子集树如下图所示:1)回溯法的伪代码:voidbacktrack(intt){if(t>n)output(x);elsefor(inti=f(n,t);i<=g(n,t);i++){x[t]=h(i);if(d=9or遇到叶子节点)backtrack(t+1);}}按照深度优先的策略对子集树进行遍历,在遍历过程中,如果d已经等于9,则马上回溯,返回到父节点,继续按照深度优先的策略进行遍历。(图中节点没有用字母标识,故没有写出遍历节点路径。)通过遍历得到在子集树中,有两个分枝满足条件d=9,分别是{3,4,2}和{-,4,-,5}。从子集树可以看出,它和0-1背包问题的解集树相同,是一棵完全二叉树,左子树为1,右子树为0。该问题可以转化为类0-1背包问题,即{3,4,2,5}四个数中选出几个数,使得和为9。2)分枝限界解法由于该问题不是求取最优解,而是搜索满足约束条件的解,因此,利用分枝限界和利用回溯法只在搜索的策略上有所区别,并没有提高搜索效率。利用分枝限界法,需要额外提供活节点表来保存待扩展的节点。该题S中的元素太多,假如S={1,2,3}要求满足d=3,问题性质没变,子集树简单了一些,但同样能说明问题。伪代码://---------------------------------------------------------------------procedureDDif根节点T是答案节点then输出T;returnendifelse初始化活节点表L,置为空loopforE的每个子节点XDOifX是答案节点then输出从X到T的路径rethrnendifcallADD(X)//新的活节点X加入Lparent(X)=E//指示到根的路径repeatif不再有活节点thenprint('noanswernode');breakendifrepeatendLC//---------------------------------------------------------------------利用分枝限界解策略,剪枝条件d=3对活节点表起作用,在对活节点进行扩展之前,先检验其是否满足约束条件,如果满足,则对其扩展,否则杀死该节点。活节点表L按照FIFO原则进行扩展。上图被矩形框覆盖的区域是被剪枝的分枝。如L={D,E,F,G},对D进行扩展,检验d,发现其已经等于3,故杀死D,L变为{E,F,G}。5.旅行商问题:给出一个n个顶点网络(有向或无向),要求找出一个包含所有n个顶点的具有最小耗费的环路。任何一个包含所有n个顶点的环路被称作一个旅行。在旅行商问题中,要设法找到一条最小耗费的旅行。1)对图示的例,画出旅行商问题的解空间树;2)对该树运用回溯算法,写出依回溯算法遍历节点的顺序表及节点。确定回溯算法未遍历的节点。对应的解集树如下图所示:6.子集和问题:对于集合S={1,2,5,6,8},求子集,要求该子集的元素之和d=9。a)画出子集和问题的解空间树;b)对该树运用回溯算法,写出依回溯算法遍历节点的顺序表及节点。确定回溯算法未遍历的节点;c)如果S中有n个元素,指定d,用伪代码写出求解子集和问题的回溯算法。见第4题。7.旅行商问题:给出一个n个顶点的网络,要求找出一个包含所有n个顶点的具有最小耗费的环路。1)对图示的例,画出旅行商问题的解空间树;2)对该树用FIFO分枝定界法求解,并写出依该算法遍历节点的顺序表;3)用C语言或伪代码描述旅行商问题的FIFO分枝定界算法。8.设要计算矩阵连乘积,其中各矩阵的维数分别为:30X3535X1515X55X1010X2020X25利用动态规划算法计算矩阵连乘过程中,得出的计算次序如下图所示:试根据递归式:见教材p44。9.用动态规划解下列0-1背包问题例题:n=3,w=[100,14,10],p=[20,18,15],c=116。假设表示的是背包容量为,可选择物品为时0-1背包问题的最优值。由0-1背包问题的最优子结构性质,可以建立计算的递归式如下:答:1.由题意:2.利用递归式,可得:因此最优解m(1,116)=max{m(2,116),m(2,116-w1)+p1}=max{m(2,116),m(2,16)+20}=max{33,38}=38现在计算x1值,步骤如下:若m(1,c)=m(2,c),则x1=0;否则x1=1。接下来计算x2:m(2,c-w1)=m(3,c-w1)?依次类推得到x3,┅,xn该例中,m(2,116)=33≠m(1,116),所以x1=1。因剩余容量=116-100=16,又因m(2,16)=18,而m(3,16)=14≠m(2,16),因此x2=1;此时r=16-14=2,不足以放物品3,所以x3=0。
12.写出下列f(n)的渐进性态:
f(n)=C0,为常数:
f(n)=O
(1)
f(n)=3n+2:
f(n)=O(n)
f(n)=6*2n+n:
f(n)=O(2n)
13.贪心方法是一种求最优解方法。
它首先根据题意,选取一种度量标准。
然后按这种度量标准对这N个输入排序,并按序一次选入一个量。
如果这个输入量的加入,不满足约束条件,则不把此输入加到这部分解中。
选择能产生问题最优解的度量标准是使用贪心法设计求解的核心问题。
14.最优子结构性质:
。
15.子问题重叠性质:
16.背包问题可以获得最优解的输入排序是按价值密度排序。
二选择题
1.直接或间接的调用自身的算法称为A。
A递归算法B贪心算法
C迭代算法D动态规划算法
2.阶乘函数用递归定义
Publicstaticintfactorial(intn)
{
if(n==0)return1;
returnB;
An*factorial(n)Bn*factorial(n-1)
Cn*factorial(n-2)Dn*factorial(n+1)
3.与分治法不同的是,适合于用动态规划求解的问题,
D
A经分解得到子问题往往是任意的
B经分解得到子问题往往是互相独立的
C经分解得到子问题往往是互相交叉的
D经分解得到子问题往往不是互相独立的
4.合并排序法的基本思想是:
将待排序元素分成大小大致相同的C
个子集合,分别对每个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合。
A4B3C2D5
5.二分搜索算法的基本思想是将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较:
如果(C),则只要在数组a的右半部继续搜索x。
Ax<a[n/2]Bx=a[n/2]
Cx>a[n/2]Dx>=a[n/2]
6.当问题的规模n趋向无穷大时,B的数量级(阶)称为算法的渐进时间复杂度。
A空间复杂度B时间复杂度
C冗余度D迭代次数
7.实现快速排序算法如下:
privatestaticvoidquickSort(intp,intr)
if(p { intq=partition(p,r);//以确定的基准元素a[p]对//子数组a[p;r]进行划分 A//对左半段排序 quickSort(q+1,r);//对右半段排序 }}AquickSort(p,q-1)BquickSort(p+1,q-1)CquickSort(p,q+1)DquickSort(p,q-2)8.计算机算法指的是CA.计算方法B.排序方法C.解决问题的方法和过程D.调度方法9.在动态规划算法中,问题的最优子结构性质使我们能够以D的方式递归地从子问题的最优解逐步构造出整个问题的最优解。A自左向右B自右向左C自上向下D自底向上10.用贪心法解最优装载问题的时候,我们采用的贪心选择的策略是CA重量大者先装B总价值大的先装C重量轻者先装D单位价值大的先装三、判断题1.从分治法的一般设计模式可以看出,用它设计出的程序一般是一个递归过程。因此,分治法的计算效率通常可以用递归方程来进行分析。(对)2.对同一个问题,动态规划算法和分治算法的计算复杂性是一样的。(错)3.0-1背包问题与背包问题这两类问题都可以用贪心算法求解。(错)4.分治法的基本思想是将一个规模较大的问题分解成若干个规模较小的子问题,这些子问题之间并不一定相互独立。(错)5.通常用T(n)来表示某一算法的“时间复杂性”,当输入量n逐渐增大时,时间复杂性的极限称为算法的“渐近时间复杂性”。(对)6.证明贪心选择后的问题简化为规模更小的类似子问题的关键在于利用该问题的最优子结构性质。(对)7.,其中P是一个正的常数。(对)8.贪心算法能对所有问题都得到整体最优解。(错)四、简述题1、请简述动态规划算法解题通常包含的四个步骤:答:1、找出最优解的性质,并刻画其结构特征;2、递归地定义最优值(写出动态规划方程);3、以自底向上的方式计算出最优值;4、根据计算最优值时得到的信息,构造一个最优解。2、试简述二分搜索算法的基本思想答:二分搜索算法的基本思想是将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较:如果x>a[n/2],则只要在数组a的右半部继续搜索x。3、用PRIM算法求下列带权图的最小生成树,要求画出选边的具体过程。答:最终结果为(g)或(h)都是正确的。4、用Kruskal算法求所给的下列图像的最小生成树,并画出选边的过程。答:五、问答题1、有n种不同的货物,规定每种最多只能拿一件,车容量为c,第i件货物占空间为wi(0<=i<=n),价值为pi(0<=i<=n),目标为装载的物品价值最大。请用下述不同的贪婪装载策略求解。1.有n种不同的货物,规定每种最多只能拿一件,车容量为c,第i件货物占空间为wi(0<=i<=n),价值为pi(0<=i<=n),目标为装载的物品价值最大。请用下述不同的贪婪装载策略求解。1)贪婪策略1:从剩余的物品中选择价值最大的物品。设n=3,w=[55,30,40],p=[30,20,15],c=80;2)贪婪策略2:从剩余的物品中选择占空间最小的物品。设n=3,w=[10,20,15],p=[5,25,10],c=25;3)贪婪策略3:从剩余的物品中选择价值密度最大(pi/wi)的物品。设n=3,w=[25,15,15],p=[40,25,25],c=35;4)分析不同策略的解,它们是最优解吗?如果不是,请直接写出最优解。5)用C语言或伪代码分别描述上述三个算法。答:首先确定问题的实质,是0-1背包问题而不是最优装载问题。最优装载问题的前提是重量受限制,而体积不受限制。伪代码:voidGreedyMethod{将问题的输入按贪心规则排序;For每个输入R[i]IfR[i]满足约束条件then加入解;Else抛弃;Endfor}上述三种策略,分别给出了三种对输入的排序规则:按价值最大、按占用空间最小、按价值密度最大。对于利用贪心策略解决0-1被包问题,很显然,只能得到局部最优解,而不能得到全局最优解。如果将问题进行以下变通,即从0-1背包问题变为背包问题,这样,就可以在装包的过程中,将物品i的一部分装入包中。书中第P90页给出了证明,即选择价值密度最大的贪心策略产生的解是全局最优解。因此,按此种方法产生的最优解也是0-1背包问题解的上界。2.有n=32个硬币,其中1个是假币,且假币较重。用分而治之方法设计一个找出假币的算法。1)请写出求解的步骤;2)用C程序或伪代码描述算法。答:将硬币递归的分成两份,比较这两份的重量,重量重者含有假币,因此,该问题可以转化为二分搜索问题。利用分治法解决该问题的伪代码如下://------------------------------------------------------------------divide-and-conquer(P){if(|P|<=n0)adhoc(P);//解决小规模的问题dividePintosmallersubinstancesP1,P2,...,Pk;//分解问题for(i=1,i<=k,i++)yi=divide-and-conquer(Pi);//递归的解各子问题returnmerge(y1,...,yk);//将各子问题的解合并为原问题的解}//------------------------------------------------------------------1、划分(Divide):将原问题分解为若干个规模较小,相互独立,与原问题性质相同的子问题。2、解决(Conquer):若子问题规模较小,则直接求解;否则递归求解子问题。3、合并(merge):将各个子问题的解合并为原问题的解。该问题的递归表达式为:T(N)=当n=2时,即每一份只有一枚硬币,比较一次,重者为假币。3.定义0/1背包问题为:。限制条件为:,且。设f(i,y)表示剩余容量为y,剩余物品为:i,i+1,…,n时的最优解的值。1)给出f(i,y)的递推表达式;2)设W=[10,20,30],P=[6,10,18],c=38,请用该递推表达式求解,要求写出计算过程。答:问题同第9题。4.子集和问题:对于集合S={3,4,2,5},求子集,要求该子集的元素之和d=9。1)画出子集和问题的解空间树;2)对该树用回溯算法求解,并写出依回溯算法遍历节点的序列;3)对该树用FIFO分枝定界法求解,并写出依该算法遍历节点的序列;4)用C语言或伪代码描述求解子集和问题的回溯算法;5)用C语言或伪代码描述求解子集和问题的FIFO分枝定界算法。答:利用回溯法解问题,首先要画出解空间树。集合S的子集合为:{3},{3,4}{3,4,2}{3,4,2,5}等。S的子集树如下图所示:1)回溯法的伪代码:voidbacktrack(intt){if(t>n)output(x);elsefor(inti=f(n,t);i<=g(n,t);i++){x[t]=h(i);if(d=9or遇到叶子节点)backtrack(t+1);}}按照深度优先的策略对子集树进行遍历,在遍历过程中,如果d已经等于9,则马上回溯,返回到父节点,继续按照深度优先的策略进行遍历。(图中节点没有用字母标识,故没有写出遍历节点路径。)通过遍历得到在子集树中,有两个分枝满足条件d=9,分别是{3,4,2}和{-,4,-,5}。从子集树可以看出,它和0-1背包问题的解集树相同,是一棵完全二叉树,左子树为1,右子树为0。该问题可以转化为类0-1背包问题,即{3,4,2,5}四个数中选出几个数,使得和为9。2)分枝限界解法由于该问题不是求取最优解,而是搜索满足约束条件的解,因此,利用分枝限界和利用回溯法只在搜索的策略上有所区别,并没有提高搜索效率。利用分枝限界法,需要额外提供活节点表来保存待扩展的节点。该题S中的元素太多,假如S={1,2,3}要求满足d=3,问题性质没变,子集树简单了一些,但同样能说明问题。伪代码://---------------------------------------------------------------------procedureDDif根节点T是答案节点then输出T;returnendifelse初始化活节点表L,置为空loopforE的每个子节点XDOifX是答案节点then输出从X到T的路径rethrnendifcallADD(X)//新的活节点X加入Lparent(X)=E//指示到根的路径repeatif不再有活节点thenprint('noanswernode');breakendifrepeatendLC//---------------------------------------------------------------------利用分枝限界解策略,剪枝条件d=3对活节点表起作用,在对活节点进行扩展之前,先检验其是否满足约束条件,如果满足,则对其扩展,否则杀死该节点。活节点表L按照FIFO原则进行扩展。上图被矩形框覆盖的区域是被剪枝的分枝。如L={D,E,F,G},对D进行扩展,检验d,发现其已经等于3,故杀死D,L变为{E,F,G}。5.旅行商问题:给出一个n个顶点网络(有向或无向),要求找出一个包含所有n个顶点的具有最小耗费的环路。任何一个包含所有n个顶点的环路被称作一个旅行。在旅行商问题中,要设法找到一条最小耗费的旅行。1)对图示的例,画出旅行商问题的解空间树;2)对该树运用回溯算法,写出依回溯算法遍历节点的顺序表及节点。确定回溯算法未遍历的节点。对应的解集树如下图所示:6.子集和问题:对于集合S={1,2,5,6,8},求子集,要求该子集的元素之和d=9。a)画出子集和问题的解空间树;b)对该树运用回溯算法,写出依回溯算法遍历节点的顺序表及节点。确定回溯算法未遍历的节点;c)如果S中有n个元素,指定d,用伪代码写出求解子集和问题的回溯算法。见第4题。7.旅行商问题:给出一个n个顶点的网络,要求找出一个包含所有n个顶点的具有最小耗费的环路。1)对图示的例,画出旅行商问题的解空间树;2)对该树用FIFO分枝定界法求解,并写出依该算法遍历节点的顺序表;3)用C语言或伪代码描述旅行商问题的FIFO分枝定界算法。8.设要计算矩阵连乘积,其中各矩阵的维数分别为:30X3535X1515X55X1010X2020X25利用动态规划算法计算矩阵连乘过程中,得出的计算次序如下图所示:试根据递归式:见教材p44。9.用动态规划解下列0-1背包问题例题:n=3,w=[100,14,10],p=[20,18,15],c=116。假设表示的是背包容量为,可选择物品为时0-1背包问题的最优值。由0-1背包问题的最优子结构性质,可以建立计算的递归式如下:答:1.由题意:2.利用递归式,可得:因此最优解m(1,116)=max{m(2,116),m(2,116-w1)+p1}=max{m(2,116),m(2,16)+20}=max{33,38}=38现在计算x1值,步骤如下:若m(1,c)=m(2,c),则x1=0;否则x1=1。接下来计算x2:m(2,c-w1)=m(3,c-w1)?依次类推得到x3,┅,xn该例中,m(2,116)=33≠m(1,116),所以x1=1。因剩余容量=116-100=16,又因m(2,16)=18,而m(3,16)=14≠m(2,16),因此x2=1;此时r=16-14=2,不足以放物品3,所以x3=0。
intq=partition(p,r);//以确定的基准元素a[p]对//子数组a[p;r]进行划分
A//对左半段排序
quickSort(q+1,r);//对右半段排序
AquickSort(p,q-1)BquickSort(p+1,q-1)
CquickSort(p,q+1)DquickSort(p,q-2)
8.计算机算法指的是C
A.计算方法B.排序方法
C.解决问题的方法和过程D.调度方法
9.在动态规划算法中,问题的最优子结构性质使我们能够以D的方式递归地从子问题的最优解逐步构造出整个问题的最优解。
A自左向右B自右向左
C自上向下D自底向上
10.用贪心法解最优装载问题的时候,我们采用的贪心选择的策略是C
A重量大者先装B总价值大的先装
C重量轻者先装D单位价值大的先装
三、判断题
1.从分治法的一般设计模式可以看出,用它设计出的程序一般是一个递归过程。
因此,分治法的计算效率通常可以用递归方程来进行分析。
(对)
2.对同一个问题,动态规划算法和分治算法的计算复杂性是一样的。
(错)
3.0-1背包问题与背包问题这两类问题都可以用贪心算法求解。
4.分治法的基本思想是将一个规模较大的问题分解成若干个规模较小的子问题,这些子问题之间并不一定相互独立。
5.通常用T(n)来表示某一算法的“时间复杂性”,当输入量n逐渐增大时,时间复杂性的极限称为算法的“渐近时间复杂性”。
6.证明贪心选择后的问题简化为规模更小的类似子问题的关键在于利用该问题的最优子结构性质。
7.
,其中P是一个正的常数。
8.贪心算法能对所有问题都得到整体最优解。
四、简述题
1、请简述动态规划算法解题通常包含的四个步骤:
答:
1、找出最优解的性质,并刻画其结构特征;
2、递归地定义最优值(写出动态规划方程);
3、以自底向上的方式计算出最优值;
4、根据计算最优值时得到的信息,构造一个最优解。
2、试简述二分搜索算法的基本思想
二分搜索算法的基本思想是将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较:
如果x>a[n/2],则只要在数组a的右半部继续搜索x。
3、用PRIM算法求下列带权图的最小生成树,要求画出选边的具体过程。
最终结果为(g)或(h)都是正确的。
4、用Kruskal算法求所给的下列图像的最小生成树,并画出选边的过程。
五、问答题
1、有n种不同的货物,规定每种最多只能拿一件,车容量为c,第i件货物占空间为wi(0<=i<=n),价值为pi(0<=i<=n),目标为装载的物品价值最大。
请用下述不同的贪婪装载策略求解。
1.有n种不同的货物,规定每种最多只能拿一件,车容量为c,第i件货物占空间为wi(0<=i<=n),价值为pi(0<=i<=n),目标为装载的物品价值最大。
1)贪婪策略1:
从剩余的物品中选择价值最大的物品。
设n=3,w=[55,30,40],p=[30,20,15],c=80;
2)贪婪策略2:
从剩余的物品中选择占空间最小的物品。
设n=3,w=[10,20,15],p=[5,25,10],c=25;
3)贪婪策略3:
从剩余的物品中选择价值密度最大(pi/wi)的物品。
设n=3,w=[25,15,15],p=[40,25,25],c=35;
4)分析不同策略的解,它们是最优解吗?
如果不是,请直接写出最优解。
5)用C语言或伪代码分别描述上述三个算法。
首先确定问题的实质,是0-1背包问题而不是最优装载问题。
最优装载问题的前提是重量受限制,而体积不受限制。
伪代码:
voidGreedyMethod
将问题的输入按贪心规则排序;
For每个输入R[i]
IfR[i]满足约束条件then加入解;
Else抛弃;
Endfor
上述三种策略,分别给出了三种对输入的排序规则:
按价值最大、按占用空间最小、按价值密度最大。
对于利用贪心策略解决0-1被包问题,很显然,只能得到局部最优解,而不能得到全局最优解。
如果将问题进行以下变通,即从0-1背包问题变为背包问题,这样,就可以在装包的过程中,将物品i的一部分装入包中。
书中第P90页给出了证明,即选择价值密度最大的贪心策略产生的解是全局最优解。
因此,按此种方法产生的最优解也是0-1背包问题解的上界。
2.有n=32个硬币,其中1个是假币,且假币较重。
用分而治之方法设计一个找出假币的算法。
1)请写出求解的步骤;
2)用C程序或伪代码描述算法。
将硬币递归的分成两份,比较这两份的重量,重量重者含有假币,因此,该问题可以转化为二分搜索问题。
利用分治法解决该问题的伪代码如下:
//------------------------------------------------------------------
divide-and-conquer(P)
if(|P|<=n0)adhoc(P);//解决小规模的问题
dividePintosmallersubinstancesP1,P2,...,Pk;//分解问题
for(i=1,i<=k,i++)
yi=divide-and-conquer(Pi);//递归的解各子问题
returnmerge(y1,...,yk);//将各子问题的解合并为原问题的解
1、划分(Divide):
将原问题分解为若干个规模较小,
相互独立,与原问题性质相同的子问题。
2、解决(Conquer):
若子问题规模较小,则直接求解;
否则递归求解子问题。
3、合并(merge):
将各个子问题的解合并为
原问题的解。
该问题的递归表达式为:
T(N)=
当n=2时,即每一份只有一枚硬币,比较一次,重者为假币。
3.定义0/1背包问题为:
限制条件为:
,且
设f(i,y)表示剩余容量为y,剩余物品为:
i,i+1,…,n时的最优解的值。
1)给出f(i,y)的递推表达式;
2)设W=[10,20,30],P=[6,10,18],c=38,请用该递推表达式求解,要求写出计算过程。
问题同第9题。
4.子集和问题:
对于集合S={3,4,2,5},求子集,要求该子集的元素之和d=9。
1)画出子集和问题的解空间树;
2)对该树用回溯算法求解,并写出依回溯算法遍历节点的序列;
3)对该树用FIFO分枝定界法求解,并写出依该算法遍历节点的序列;
4)用C语言或伪代码描述求解子集和问题的回溯算法;
5)用C语言或伪代码描述求解子集和问题的FIFO分枝定界算法。
利用回溯法解问题,首先要画出解空间树。
集合S的子集合为:
{3},{3,4}{3,4,2}{3,4,2,5}等。
S的子集树如下图所示:
1)
回溯法的伪代码:
voidbacktrack(intt)
if(t>n)output(x);
else
for(inti=f(n,t);i<=g(n,t);i++){
x[t]=h(i);
if(d=9or遇到叶子节点)backtrack(t+1);
按照深度优先的策略对子集树进行遍历,在遍历过程中,如果d已经等于9,则马上回溯,返回到父节点,继续按照深度优先的策略进行遍历。
(图中节点没有用字母标识,故没有写出遍历节点路径。
)
通过遍历得到在子集树中,有两个分枝满足条件d=9,分别是{3,4,2}和{-,4,-,5}。
从子集树可以看出,它和0-1背包问题的解集树相同,是一棵完全二叉树,左子树为1,右子树为0。
该问题可以转化为类0-1背包问题,即{3,4,2,5}四个数中选出几个数,使得和为9。
2)分枝限界解法
由于该问题不是求取最优解,而是搜索满足约束条件的解,因此,利用分枝限界和利用回溯法只在搜索的策略上有所区别,并没有提高搜索效率。
利用分枝限界法,需要额外提供活节点表来保存待扩展的节点。
该题S中的元素太多,假如S={1,2,3}要求满足d=3,问题性质没变,子集树简单了一些,但同样能说明问题。
//---------------------------------------------------------------------
procedureDD
if根节点T是答案节点then输出T;returnendif
初始化活节点表L,置为空
loop
forE的每个子节点XDO
ifX是答案节点then输出从X到T的路径rethrnendif
callADD(X)//新的活节点X加入L
parent(X)=E//指示到根的路径
repeat
if不再有活节点then
print('noanswernode');breakendif
endLC
利用分枝限界解策略,剪枝条件d=3对活节点表起作用,在对活节点进行扩展之前,先检验其是否满足约束条件,如果满足,则对其扩展,否则杀死该节点。
活节点表L按照FIFO原则进行扩展。
上图被矩形框覆盖的区域是被剪枝的分枝。
如L={D,E,F,G},对D进行扩展,检验d,发现其已经等于3,故杀死D,L变为{E,F,G}。
5.旅行商问题:
给出一个n个顶点网络(有向或无向),要求找出一个包含所有n个顶点的具有最小耗费的环路。
任何一个包含所有n个顶点的环路被称作一个旅行。
在旅行商问题中,要设法找到一条最小耗费的旅行。
1)对图示的例,画出旅行商问题的解空间树;
2)对该树运用回溯算法,写出依回溯算法遍历节点的顺序表及节点。
确定回溯算法未遍历的节点。
对应的解集树如下图所示:
6.子集和问题:
对于集合S={1,2,5,6,8},求子集,要求该子集的元素之和d=9。
a)画出子集和问题的解空间树;
b)对该树运用回溯算法,写出依回溯算法遍历节点的顺序表及节点。
确定回溯算法未遍历的节点;
c)如果S中有n个元素,指定d,用伪代码写出求解子集和问题的回溯算法。
见第4题。
7.旅行商问题:
给出一个n个顶点的网络,要求找出一个包含所有n个顶点的具有最小耗费的环路。
2)对该树用FIFO分枝定界法求解,并写出依该算法遍历节点的顺序表;
3)用C语言或伪代码描述旅行商问题的FIFO分枝定界算法。
8.设要计算矩阵连乘积,其中各矩阵的维数分别为:
30X3535X1515X55X1010X2020X25
利用动态规划算法计算矩阵连乘过程中,得出的计算次序如下图所示:
试根据递归式:
见教材p44。
9.用动态规划解下列0-1背包问题例题:
n=3,w=[100,14,10],p=[20,18,15],c=116。
假设
表示的是背包容量为
,可选择物品为
时0-1背包问题的最优值。
由0-1背包问题的最优子结构性质,可以建立计算
的递归式如下:
1.
由题意:
2.利用递归式,可得:
因此最优解m(1,116)=max{m(2,116),
m(2,116-w1)+p1}=max{m(2,116),m(2,16)+20}=max{33,38}=38
现在计算x1值,步骤如下:
若m(1,c)=m(2,c),则x1=0;否则x1=1。
接下来计算x2:
m(2,c-w1)=m(3,c-w1)?
依次类推得到x3,┅,xn
该例中,m(2,116)=33≠m(1,116),所以x1=1。
因剩余容量=116-100=16,又因m(2,16)=18,而m(3,16)=14≠m(2,16),因此x2=1;此时r=16-14=2,不足以放物品3,所以x3=0。
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2