递归算法的优缺点.docx
《递归算法的优缺点.docx》由会员分享,可在线阅读,更多相关《递归算法的优缺点.docx(18页珍藏版)》请在冰点文库上搜索。
![递归算法的优缺点.docx](https://file1.bingdoc.com/fileroot1/2023-6/3/af33d04a-8fa7-4971-aedf-ff71ab8379e4/af33d04a-8fa7-4971-aedf-ff71ab8379e41.gif)
递归算法的优缺点
递归算法的优缺点:
之巴公井开创作
创作时间:
贰零贰壹年柒月贰叁拾日
优点:
结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。
缺点:
递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。
鸿沟条件与递归方程是递归函数的二个要素
应用分治法的两个前提是问题的可分性和解的可归并性
以比较为基础的排序算法的最坏倩况时间复杂性下界为0(n·log2n)。
回溯法以深度优先的方式搜索解空间树T,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树T。
舍伍德算法设计的基本思想:
设A是一个确定性算法,当它的输入实例为x时所需的计算时间记为tA(x)。
设Xn是算法A的输入规模为n的实例的全体,则当问题的输入规模为n时,算法A所需的平均时间为
这显然不克不及排除存在x∈Xn使得的可能性。
希望获得一个随机化算法B,使得对问题的输入规模为n的每一个实例均有
拉斯维加斯(LasVegas)算法的基本思想:
设p(x)是对输入x调用拉斯维加斯算法获得问题的一个解的概率。
一个正确的拉斯维加斯算法应该对所有输入x均有p(x)>0。
设t(x)是算法obstinate找到具体实例x的一个解所需的平均时间,s(x)和e(x)分别是算法对于具体实例x求解成功或求解失败所需的平均时间,则有:
解此方程可得:
蒙特卡罗(MonteCarlo)算法的基本思想:
设p是一个实数,且1/2
如果一个蒙特卡罗算法对于问题的任一实例得到正确解的概率不小于p,则称该蒙特卡罗算法是p正确的,且称p1/2是该算法的优势。
如果对于同一实例,蒙特卡罗算法不会给出2个分歧的正确解答,则称该蒙特卡罗算法是一致的。
线性规划基本定理:
如果线性规划问题有最优解,则必有一基本可行最优解。
单纯形算法的特点是:
(1)只对约束条件的若干组合进行测试,测试的每一步都使目标函数的值增加;
(2)一般经过不大于m或n次迭代就可求得最优解。
单纯形算法的基本思想就是从一个基本可行解出发,进行一系列的基本可行解的变换。
每次变换将一个非基本变量与一个基本变量互调位置,且坚持当前的线性规划问题是一个与原问题完全等价的尺度线性规划问题。
图灵机由以下几部分组成:
一条无限长的带(有无穷个格子)、一个读写头、一个有限状态控制器以及一个程序。
NPC形式化定义:
定义1:
语言L是NP完全的当且仅当
(1)L【NP;
(2)对于所有L’【NP有L’~pL。
如果有一个语言L满足上述性质
(2),但纷歧定满足性质
(1),则称该语言是NP难的。
所有NP完全语言构成的语言类称为NP完全语言类,就是NPC。
定理1设L是NP完全的,则
(1)LP当且仅当P=NP;
(2)若LpL1,且L1NP,则L1是NP完全的。
团问题:
任给图G和整数k.试判定图G中是否存在具有k个顶点的团?
1)团问题NP。
显然,验证G的一个子图是否成团只需多项式时间即可。
2)SAT团问题。
任给表达式f.构造一个相应的图G如下:
①图G的每个顶点对应于f中的每个文字(多次出现的重复计算)。
②若G中两个顶点其原对应的文字不相互补且不出现于同一于句中,则将其连线。
设f有n个子句,则f可满足当且仅当f对应的图G中有n个顶点的团。
这是因为:
(a)若f可满足,即有某种赋值使得f取值为真,它等价于使得每个ci中都至少有一个文字为真,这n个文字(每个ci(1<i(b)若图G中有一n个顶点的团,则取给出使得这n个顶点对应的文字都为真的赋值,则f的取值为真(这由图G的定义易证)。
显见,上述构造图G的方法是多项式界的,因此SAT团问题。
由(a)、(b)有,团问题NPC。
证毕。
单源最短路径问题:
voidshortestpaths(v)
{
MinHeapH[1000];
//定义最小堆
MinHeapNodeE;
E.i=v;
E.length=0;
Dist[v]=0;
//搜索问题界空间
while(true)
{for(j=1;j<=n;j++)
if((c[E.i][j](E.length+c[E.i][j]{dist[j]=E.length+c[E.i][j];
prev[j]=E.i;
//加入活结点优先队列
MinHeapNodeN;
N.i=j;
N.length=dist[j];
H.Insert(N);
}
//取下一个扩展结点
try{H.DeleteMin(E);}
//优先队列为空
catch(OutOfBounds){break;}
}
}
(1)数值随机化算法:
ß求解数值问题,得到近似解
(2)MonteCarlo算法:
ß问题准确性,但却无法确定解正确性
(3)LasVegas算法:
ß获得正确解,但存在找不到解的可能性
(4)Sherwood算法:
ß包管能获得正确解
旅行售货员问题:
(优先队列式分支限界法)
TypeTravding(intv[])
{MinHeapNodeH(1000);
TypeMinout[N+1];
//计算Minout[i]=顶点i的最小出边费用
TypeMinsurn=0;//最小出边费用和
for(i=1;i<=n;i++){
Min=NoEdge;
for(j=1;j<=n;j++)
if(a[i][j]!
=NoEdge&&(a[i][j]if(Min==NoEdge)return(NoEdge);//无回路
MinOut[i]=Min;
MinSum+=Min;
}
//初始化
MinHeapNodeE;
for(i=0;i<n;i++)
E.x[i]=i+1;
E.s=0;
E.cc=0;
E.rcost=MinSum;
Bestc=NoEdge;
while(E.s<n1)//非叶结点
if(E.sif(a[E.x[n2][E.x[n1]]!
=NoEdge&&a[E.x[n2][1]!
=NoEdge&&(E.cc+
a[E.x[n2]][E.x[n1]]+a[E.x[n1]][1]<
bestc||bestc==NoEdge){
//费用更小的回路
bestc=Ecc+a[E.x[n2]][E.x[n1]]
+a[E.x[n1]][1];
E.c=bestc;
E.lcost=bestc;
E.s++;
Insert(H,E);}
elsedelete(E.x);}//舍弃扩展结点
else{//发生当前扩展结点的儿子结点
for(i=E.s+1;i<n;i++=
if(a[E.x[E.s]][E.x[i]]!
=NoEdge)
{//可行儿子结点
Typecc=E.cc+a[E.x[E.s]][E.x[i]];
Typercost=E.rcostMinOut[E.x[E.s]];
Typeb=cc+rcost;//下界
if(b<bestc||bestc==NoEdge)
{//子树可能含最优解
for(j=0;j<n;j++)
N.x[j]=E.x[j];
N.x[E.s+1]=E.x[i];
N.x[i]=E.x[E.s+1];
N.cc=cc;
N.s=E.s+1;
N.lcost=b;
N.rcost=rcost;
Insert(H,N);
}
}
delete(H,E.x);
}//完成结点扩展
DeleteMin(H,E);}//取下一扩展结点
if(堆已空)break;//堆已空
}
if(bestc==NoEdge)return(NoEdge);
//无回路
//将最优解复制到v[l:
n]
for(i=0;i<n;i++)
v[i+1]=E.x[i];
while(true){//释放最小堆中所有结点
delete(H,E.x);
DeleteMin(H,E);}//取下一扩展结点
if(堆已空)break;//堆已空
}
return(bestc);
}
回溯算法解批处理作业调度(解空间:
排列树):
voidFlowshop:
:
Backtrack(inti)
{
if(i>n){
for(intj=1;j<=n;j++)
bestx[j]=x[j];
bestf=f;
}
else
for(intj=i;j<=n;j++){
f1+=M[x[j]][1];
f2[i]=((f2[i1]>f1)?
f2[i1]:
f1)+M[x[j]][2];
f+=f2[i];
if(fSwap(x[i],x[j]);
Backtrack(i+1);
Swap(x[i],x[j]);
}
f1=M[x[j]][1];
f=f2[i];
}
}
所以在最坏的情况下,整个算法的计算时间复杂性为O(n!
)
回溯算法解01背包问题(解空间:
子集树):
template
TypepKnap:
:
Bound(inti)
{//计算上界
Typewcleft=ccw;//剩余容量
Typepb=cp;
//以物品单位重量价值递减序装入物品
while(i<=n&&w[i]<=cleft){
cleft=w[i];
b+=p[i];
i++;
}
//装满背包
if(i<=n)b+=p[i]/w[i]*cleft;
returnb;
}
voidbacktrack(i)
{if(i>n)
{bestp=cp;
return;}
if(cw+w[i]<=c)//x[i]=1
{cw+=w[i];cp+=p[i];
backtrack(i+1);
cw=w[i];cp=p[i];}
if(bound(i+1)>bestp)
backtrack(i+1);//x[i]=0
}
由于上界函数Bound()需要O(n)的时间,在最坏的情况下有O(2n)个右儿子结点需要计算上界函数,所以01背包问题的回溯算法Backtrack()所需要的时间是O(n2n)。
回溯算法解图的m着色问题:
voidColor:
:
Backtrack(intt)
{
if(t>n){
sum++;
for(inti=1;i<=n;i++)
cout<cout<}
else
for(inti=1;i<=m;i++){
x[t]=i;
if(Ok(t))Backtrack(t+1);
}
}
boolColor:
:
Ok(intk)
{//检查颜色可用性
for(intj=1;j<=n;j++)
if((a[k][j]==1)&&(x[j]==x[k]))returnfalse;
returntrue;
}
回溯法总的时间耗费是O(m^n*n)
回溯算法解最大团问题(解空间:
子集树):
voidClique:
:
Backtrack(inti)
{//计算最大团
if(i>n){//到达叶结点
for(intj=1;j<=n;j++)bestx[j]=x[j];
bestn=cn;return;}
//检查顶点i与当前团的连接
intOK=1;
for(intj=1;j
if(x[j]&&a[i][j]==0){
//i与j不相连
OK=0;break;}
if(OK){//进入左子树
x[i]=1;cn++;
Backtrack(i+1);
x[i]=0;cn;}
if(cn+ni>bestn){//进入右子树x[i]=0;
Backtrack(i+1);}
}
解最大团问题的回溯算法Backtrack所需的计算时间为O(n2n)。
回溯法的基本思想是:
不竭用修改过的判定函数Pi只(x1,x2,…,xi)(亦称为限界函数)去测试正在构造中的n元组的部分向量(x1,x2,…,xn).看其是否可能导致最优解。
如果判定(x1,x2,…,xn)不成能导致最优解,那么就不再测试可能要测试的mi+1mi+2...mn个向量。
解符号三角形问题的回溯算法Backtrack所需的计算时间为O(n2n)。
贪心法解最优装载问题:
template
voidLoading(intx[],Typew[],Typec,intn)
{
int*t=newint[n+1];
Sort(w,t,n);
for(inti=1;i<=n;i++)x[i]=0;
for(inti=1;i<=n&&w[t[i]]<=c;i++){x[t[i]]=1;c=w[t[i]];}
}
算法所需的计算时间为O(nlogn)
算法是指解决问题的一种方法或一个过程。
算法是若干指令的有穷序列,满足性质:
(1)输入
(2)输出(3)确定性(4)有限性:
问题的计算时间下界为W(f(n)),则计算时间复杂性为O(f(n))的算法是最优算法。
1.什么是动态规划法:
将问题分解成多级或许多子问题,然后顺序求解子问题,前一个子问题的解为后一个子问题的求解提供有用的信息。
2.什么是贪心法:
从问题某一初始或推测值出发,一步步的攀登给定目标,尽可能快的去迫近更好的解,当达到某一步不克不及继续时终止。
3.什么是分支定界法:
对有约束条件的最优化问题所有可行解定向、适当地进行搜索。
将可行解空间不竭地划分为越来越小的子集(分支),并为每一个子集的解计算一个上界和下界(定界)。
5、什么是NP类问题:
NP={L|L是一个能在多项式时间内被一台NDTM图灵机所接受的语言},其中NDTM是非确定性图灵机。
或者可说:
NP是所有可在多项式时间内用不确定的算法求解的判定问题的集合。
对于NP类,相当于要求验证模块在多项式时间内完成对应NDTM,有非确定性算法。
1.算法的分类:
1)(数值算法)2)非数值算法
2.算法的描述:
1)自然语言描述2)(流程图描述)3)程序语言描述
3.算法的分析尺度:
1)时空观念2)(发展观念)3)设计观点4)交流的观点
设计动态规划算法的步调。
(1)找出最优解的性质,并刻划其结构特征。
(2)递归地定义最优值。
(3)以自底向上的方式计算出最优值。
(4)根据计算最优值时得到的信息,构造最优解。
动态规划法求矩阵连乘问题:
voidMatrixChain(int*p,intn,int**m,int**s)
{for(inti=1;i<=n;i++)m[i][i]=0;
for(intr=2;r<=n;r++)
for(inti=1;i<=nr+1;i++){
intj=i+r1;
m[i][j]=m[i+1][j]+p[i1]*p[i]*p[j];
s[i][j]=i;
for(intk=i+1;kintt=m[i][k]+m[k+1][j]+p[i1]*p[k]*p[j];
if(t}
}
}
因此算法的计算时间上界为O(n3)。
算法所占用的空间显然为O(n2)。
1.简述算法的五个重要的特征。
:
①有穷性:
一个算法必须包管执行有限步之后结束;②确切性:
算法的每一步调必须有确切的定义;③输入:
一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法自己定义了初始条件;④输出:
一个算法有一个或多个输出,以反映对输入数据加工后的结果。
没有输出的算法是毫无意义的;⑤可行性:
算法原则上能够精确地运行,而且人们用笔和纸做有限次运算后即可完成。
备注:
算法可以没有输入。
因为有些算法中包含了输入,如随机发生输入。
2.简答贪心算法的基本元素:
①贪心选择性质:
所谓贪心选择性质指所求问题的整体最优解可以通过一系列局部最优的选择达到。
②最优子结构性质:
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构。
3.简述动态规划算法的基本思想和基本步调以及动态规划问题的特征。
动态规划的实质是分治思想和解决冗余,因此,动态规划是一种将问题实例分解为更小的、相似的子问题,并存储子问题的解而防止计算重复的子问题,以解决最优化问题的算法战略。
按以下几个步调进行:
①分析最优解的性质,并刻划其结构特征。
②递归地定义最优值。
③以自底向上的方式或自顶向下的记忆化方法(备忘录法)计算出最优值。
④根据计算最优值时得到的信息,构造一个最优解。
动态规划问题的特征:
动态规划算法的有效性依赖于问题自己所具有的两个重要性质:
最优子结构性质和子问题重叠性质。
1、最优子结构:
当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。
2、重叠子问题:
在用递归算法自顶向下解问题时,每次发生的子问题其实不总是新问题,有些子问题被反复计算多次。
动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只解一次,而后将其解保管在一个表格中,在以后尽可能多地利用这些子问题的解。
4.简述回溯算法的基本思想及解题步调。
回溯法的基本思想:
确定了解空间的组织结构后,回溯法就从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。
这个开始结点就成为一个活结点,同时也成为当前的扩展结点。
在当前的扩展结点处,搜索向纵深方向移至一个新结点。
这个新结点就成为一个新的活结点,并成为当前扩展结点。
如果在当前的扩展结点处不克不及再向纵深方向移动,则当前扩展结点就成为死结点。
换句话说,这个结点不再是一个活结点。
此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。
回溯法即以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已没有活结点时为止。
(9分)
运用回溯法解题通常包含以下三个步调:
(1)针对所给问题,定义问题的解空间;(2分)
(2)确定易于搜索的解空间结构;(2分)
(3)以深度优先的方式搜索解空间,而且在搜索过程中用剪枝函数防止无效搜索。
5.简述分治算法的基本思想及基本步调。
分治法的基本思想:
对于一个输入规模为
的问题,若该问题容易的解决,则直接解决,否则将其分解为
个规模较小的子问题,这些子问题相互独立且与原问题形式相同,递归求解这些子问题,然后将各个子问题的解合并,得到原问题的解。
(9分)
分治法在每一层递归上由以下三个步调组成:
①划分:
将原问题分解为若干规模较小、相互独立、与原问题形式相同的子问题;(2分)
②解决:
若子问题规模较小,则直接解决;否则递归求解各个子问题。
(2分)
③合并:
将各个子问题的解合并为原问题的解。
(2分)
6.分支限界法的基本思想:
分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
问题的解空间树是暗示问题解空间的一棵有序树,罕见的有排列树。
在搜索问题的解空间树时,分支限界法与回溯法对当前扩展结点所使用的扩展方式分歧。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。
活结点一旦成为扩展结点,就一次性发生其所有儿子结点。
在这些儿子结点中,那些导致不成行解或导致非最优解的儿子结点被舍弃,其余儿子结点被子加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,偏重复上述结点扩展过程。
这个过程一直持续到找到所求的解或活结点表为空时为止。
7.贪心算法的基本思想如下:
从问题的某一个初始解出发逐步迫近给定的目标,以尽可能快的地求得更好的解。
当达到某算法中的某一步不克不及再继续前进时,算法停止,得到问题的一个解。
贪心算法存在问题:
1.不克不及包管求得的最后解是最佳的;2.不克不及用来求最大或最小解问题;3.只能求满足某些约束条件的可行解的范围。
8.动态规划与分治法的异同:
相同点:
动态规划法与分治法类似,它们都是将问题划分为更小的、相似的子问题,并通过求解子问题发生一个全局最优解。
分歧点:
而分治法中的各个子问题是独立的(即不包含公共的子子问题),因此一旦递归地求出各子问题的解后,即可自下而上地将子问题的解合并成问题的解。
但分歧的是,如果各子问题是不是相互独立的,则分治法要做许多不需要的工作,重复地解公共的子问题。
9.分支限界法与回溯法的异同:
分支限界法类似于回溯法,也是一种在问题的解空间树T上搜索问题解的算法。
但在一般情况下,分支限界法与回溯法的求解目标分歧。
回溯法的求解目标是找出T中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使用某一目标函数值达到极大或极小的解,即在某种意义下的最优解。
因此,回溯法以深度优先的方式搜索解空间树T,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树T。
10.证明装载问题具有贪心选择性质.
证明:
设集装箱已依其重量从小到大排序,(x1,x2,…,xn)是最优装载问题的一个最优解.又设1.当k=1时,(x1,x2,…,xn)是一个满足贪心选择性质的最优解.
2.当k>1时,取y1=1;yk=0;yi=xi,1
因此,(y1,y2,…,yn)是所给最优装载问题的一个可行解
另一方面,由
(y1,y2,…,yn)是一个满足贪心选择性质的最优解
所以,最优装载问题具有贪心选择性质
Hanoi塔问题:
voidhanoi(intn,inta,intb,intc)
{
if(n>0)
{
hanoi(n1,a,c,b);
move(a,b);
hanoi(n1,c,b,a);
}
}
创作时间:
贰零贰壹年柒月贰叁拾日