算法分析与设计复习

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、名词解释:
2.程序:程序是算法用某种程序设计语言的具体实现。

3.递归函数:用函数自身给出定义的函数称为递归函数。

4.子问题的重叠性质:递归算法求解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计
算多次,这种性质称为子问题的重叠性质。

5.队列式分支限界法:队列式(FIFO)分支限界法是将活结点表组织成一个队列,并按照队列的先进先出
(FIFO)原则选取下一个结点为扩展结点。

6.多机调度问题:多机调度问题要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m
台机器加工处理完成。

同时约定每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。

作业不能拆分成更小的子作业。

7.最小生成树:G=(V,E)是无向连通带权图,G的子图称为G的生成树,生成树上各边权的总和称为该生
成树的耗费,在G的所有生成树中,耗费最小的生成树称为G的最小生成树。

二、简答题:
(1)什么是算法?算法的特征有哪些?
(2)什么是P类问题?什么是NP类问题?请描述集合覆盖问题的近似算法的基本思想。

答案:(1)算法是解决某类问题的一系列运算的集合【2分】。

具有有穷行、可行性、确定性、0个或者多个输入、1个或者多个输出【8分】。

(2)用确定的图灵机可以在多项式实践内可解的判定问题称为P类问题【2分】。

用不确定的图灵机在多项式实践内可解的判定问题称为P类问题。

【2分】
集合覆盖问题的近似算法采用贪心思想:对于问题<X,F>,每次选择F中覆盖了尽可能多的未被覆盖元素的子集S,然后将U中被S覆盖的元素删除,并将S加入C中,最后得到的C就是近似最优解。

【6分】
1、简单描述分治法的基本思想。

2、简述动态规划方法所运用的最优化原理。

3、何谓最优子结构性质?
4、简单描述回溯法基本思想。

5、何谓P、NP、NPC问题
6、分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且
与原问题相同;对这k个子问题分别求解。

如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止;将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。

7、“最优化原理”用数学化的语言来描述:假设为了解决某一优化问题,需要依次作出n个决策D1,D2,…,
Dn,如若这个决策序列是最优的,对于任何一个整数k,1 < k < n,不论前面k个决策是怎样的,以后的最优决策只取决于由前面决策所确定的当前状态,即以后的决策Dk+1,Dk+2,…,Dn也是最优的。

8、某个问题的最优解包含着其子问题的最优解。

这种性质称为最优子结构性质。

9、回溯法的基本思想是在一棵含有问题全部可能解的状态空间树上进行深度优先搜索,解为叶子结点。

搜索过程中,每到达一个结点时,则判断该结点为根的子树是否含有问题的解,如果可以确定该子树中不含有问题的解,则放弃对该子树的搜索,退回到上层父结点,继续下一步深度优先搜索过程。

在回溯法中,并不是先构造出整棵状态空间树,再进行搜索,而是在搜索过程,逐步构造出状态空间树,即边搜索,边构造。

10、P(Polynomial问题):也即是多项式复杂程度的问题。

NP就是Non-deterministic Polynomial的问题,也即是多项式复杂程度的非确定性问题。

NPC(NP Complete)问题,这种问题只有把解域里面的所有可能都穷举了之后才能得出答案,这样的问题是NP里面最难的问题,这种问题就是NPC问题。

1.备忘录方法和动态规划算法相比有何异同?简述之。

备忘录方法是动态规划算法的变形。

与动态规划算法一样,备忘录方法用表格保存已解决的子问题的答案,在下次需要解此问题时,只要简单地查看该子问题的解答,而不必重新计算。

备忘录方法与动态规划算法不同的是,备忘录方法的递归方式是自顶向下的,而动态规划算法则是自底向上递归的。

因此,备忘录方法的控制结构与直接递归方法的控制结构相同,区别在于备忘录方法为每个解过的子问题建立了备忘录以备需要时查看,避免了相同的子问题的重复求解,而直接递归方法没有此功能。

2.简述回溯法解题的主要步骤。

回溯法解题的主要步骤包括:
1)针对所给问题,定义问题的解空间;
2)确定易于搜索的解空间结构;
3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。

3.简述动态规划算法求解的基本要素。

动态规划算法求解的基本要素包括:
1)最优子结构是问题能用动态规划算法求解的前提;
2)动态规划算法,对每一个子问题只解一次,而后将其解保存在一个表格中,当再次需要解此子问题时,只是简单地用常数时间查看一下结果,即重叠子问题。

4.简述回溯法的基本思想。

回溯法的基本做法是搜索,在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。

算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。

如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。

5.简要分析在递归算法中消除递归调用,将递归算法转化为非递归算法的方法。

将递归算法转化为非递归算法的方法主要有:
1)采用一个用户定义的栈来模拟系统的递归调用工作栈。

该方法通用性强,但本质上还是递归,只不过人工做了本来由编译器做的事情,优化效果不明显。

2)用递推来实现递归函数。

3)通过Cooper变换、反演变换能将一些递归转化为尾递归,从而迭代求出结果。

后两种方法在时空复杂度上均有较大改善,但其适用范围有限。

6.简要分析分支限界法与回溯法的异同。

1)求解目标:回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。

2)搜索方式的不同:回溯法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树。

7.简述算法复杂性的概念,算法复杂性度量主要指哪两个方面?
算法复杂性是算法运行所需要的计算机资源的量,需要时间资源的量称为时间复杂性,需要的空间资源的量称为空间复杂性。

这个量应该只依赖于算法要解的问题的规模、算法的输入和算法本身的函数。

如果分别用N、I和A表示算法要解问题的规模、算法的输入和算法本身,而且用C表示复杂性,那么,应该有C=F(N,I,A)。

算法复杂性度量主要包括算法的时间复杂性和算法的空间复杂性。

8.贪心算法求解的问题主要具有哪些性质?简述之。

贪心算法求解的问题一般具有二个重要的性质:
一是贪心选择性质,这是贪心算法可行的第一个基本要素;
另一个是最优子结构性质,问题的最优子结构性质是该问题可用贪心算法求解的关键特征。

9.分治法的基本思想是什么?合并排序的基本思想是什么?请分别简述之。

分治法的基本思想:将n个输入分成k个不同子集合,得到k个不同的可独立求解的子问题,其中1<k ≤n,而且子问题与原问题性质相同,原问题的解可由这些子问题的解合并得出。

合并排序基本思想:将待排序元素分成大小大致相同的2个子集合,分别对2个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合。

10.简述分析贪心算法与动态规划算法的异同。

贪心算法和动态规划算法都要求问题具有最优子结构性质,这是两类算法的一个共同点。

动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。

蛮力法:
直接基于问题的描述
(1)蛮力法依赖的基本技术——扫描技术,即采用一定的策略将待求解问题的所有元素依次处理一次,从而找出问题的解
关键——依次处理所有元素
(2)基本的扫描技术——遍历
集合的遍历:按元素序号
线性表的遍历:按元素序号
树的遍历:按前序、中序、后序、层次
图的遍历:按深度优先、广度优先
(3)蛮力法可以作为某类问题时间性能的底限,来衡量同样问题的更高效算法。

(4)顺序查找:从表的一端向另一端逐个将元素与给定值进行比较,若相等,则查找成功,给出该元素在表中的位置;若整个表检测完仍未找到与给定值相等的元素,则查找失败,给出失败信息。

三、算法编写及算法应用分析题:
四、算法理解题(本题10分)
根据优先队列式分支限界法,求下图中从v1点到v9点的单源最短路径,请画出求得最优解的解空间树。

要求中间被舍弃的结点用×标记,获得中间解的结点用单圆圈○框起,最优解用双圆圈◎框起。

3. 根据优先队列式分支限界法,求下图中从v1点到v9点的单源最短路径,请画出求得最优解的解空间树。

要求中间被舍弃的结点用×标记,获得中间解的结点用单圆圈○框起(如○v2),最优解用双圆圈◎框起。

12
3.已知
()
1
*
()k
k ij i i
r r
A a
+
=
,k=1,2,3,4,5,6,r1=5,r2=10,r3=3,r4=12,r5=5,r6=50,r7=6,求
矩阵链积A1×A2×A3×A4×A5×A6的最佳求积顺序(要求给出计算步骤)。

解:使用动态规划算法进行求解。

求解矩阵为:
因此,最佳乘积序列为(A1A2)((A3A4)(A5A6)),共执行乘法2010次。

8、试写出用分治法对数组A[n]实现快速排序的算法。

解:用分治法求解的算法代码如下:
int partition(float A[],int p,int r) {
int i=p,j=r+1; float x=a[p]; while (1) {
while(a[++i]<x); while(a[--j]>x); if(i>=j) break; a[i]];[j a };
a[p]=a[j];
a[j]=x;
return j;
}
void Quicksort( float a[], int p, int r )
{
if( p<r) {
int q=partition(a,p,r);
Quicksort(a,p,q-1);
Quicksort(a,q+1,r);
}
};
Quicksort(a,0,n-1);
16、试写出用分治法对一个有序表实现二分搜索的算法。

解:解答如下:
Template<class>
int BinarySearch(Type a[],const Type& x,int n)
{//假定数组a[]已按非递减有序排列,本算法找到x后返回其在数组a[]中的位置,//否则返回-1 int left=0,right=n-1;
while(left<=right){
int middle=(left+right)/2;
if(x= =a[middle]) return middle+1;
if(x>a[middle]) left=middle+1;
else right=middle-1;
}
return -1;
}
18、假设有7个物品,它们的重量和价值如下表所示。

若这些物品均不能被分割,且背包容量M=150,使用回溯方法求解此背包问题,请写出状态空间搜索树。

1~7。

则可生产如下的状态空间搜索树。

其中各个节点处的限界函数值通过如下方式求得:
x 5x =6x =7x =
a .1501154040305035190.62540
-++++⨯= 7(1,1,1,1,,0,0)8
b. 1501154040305030177.560
-++++⨯=7(1,1,1,1,0,,0)12
c .4040305010170++++=
(1,1,1,1,0,0,1)
d. 1501054040303530167.560
-++++⨯= 3(1,1,1,0,1,,0)4
e. 150130404050353017560
-++++⨯=
1
(1,1,0,1,1,,0)3
f. 1501304040503510170.7135
-++++⨯=
4(1,1,0,1,1,0,)7
g. 40405030160+++=
(1,1,0,1,0,1,0)
h. 1501404040353010146.8535-++++⨯= 2(1,1,0,0,1,1,)7
i.1501254030503530167.560-++++⨯=5(1,0,1,1,1,,0)12
j. 150145
4030503530157.560-++++⨯=1(0,1,1,1,1,,0)12
在Q 1处获得该问题的最优解为(1,1,1,1,0,0,1),背包效益为170。

即在背包中装入物品F 、B 、G 、D 、A 时达到最大效益,为170,重量为150。

实验程序
1. 某地刑侦大队对涉及六个嫌疑人的一桩疑案进行分析:(1)A、B至少有一人作案;(2)A、E、F三人中至少有两人参与作案;(3)A、D不可能是同案犯;(4)B、C或同时作案,或与本案无关;(5)C、D 中有且仅有一人作案;(6)如果D没有参与作案,则E也不可能参与作案。

试设计算法将作案人找出来。

2.将1,2...9共9个数分成三组,分别组成三个三位数,且使这三个三位数构成1:2:3的比例,试求出所有满足条件的三个三位数。

(2)
1.实验分析
实验一中,将那些涉及的条件用括号括起来,再用&&连接起来,由于有六个人,则需用六个for循环,将那作案与非作案设为0和1,然后用蛮力法去判断。

实验二中,首先要得出3个3元数中分别由哪三个数组成,再判断这九个数有没有重复的数,然后,再用蛮力法去判断是否成倍数关系,再将满足条件的输出。

特别要注意怎么判断那九个数字是不是有重复的用什么方法。

七、算法设计题(本题10分)
通过键盘输入一个高精度的正整数n(n的有效位数≤240),去掉其中任意s个数字后,剩下的数字按原左右次序将组成一个新的正整数。

编程对给定的n 和s,寻找一种方案,使得剩下的数字组成的新数最小。

【样例输入】
178543
S=4
【样例输出】
13
1. 7分
为了尽可能地逼近目标,选取的贪心策略为:每一步总是选择一个使剩下的数最小的数字删去,即按高位到低位的顺序搜索,若各位数字递增,则删除最后一个数字,否则删除第一个递减区间的首字母。

然后回到串首,按上述规则再删除下一个数字。

重复以上过程s次,剩下的数字串便是总是的解。

2. 8分
string MinNum(string n,int s)
{
while(s>0)
{
unsigned int i=0; //从串首开始找
while(i<n.length()&&(n.at(i)<n.at(i+1)))
i++;
n.erase(i,1); //删除字符串n中索引为i的字符
s--;
}
while(n.length()>1&&n.at(0)=='0')
n.erase(0,1); //删除串首可能产生的无用零
return n;
}。

相关文档
最新文档