分治算法贪心算法动态规划回溯法文档格式.docx
《分治算法贪心算法动态规划回溯法文档格式.docx》由会员分享,可在线阅读,更多相关《分治算法贪心算法动态规划回溯法文档格式.docx(20页珍藏版)》请在冰豆网上搜索。
递归的解这些子问题,然后将各子问题的解合并到原问题的解。
在递归算法中,原问题和子问题的区别关键在于尺寸的不同,实际上解决的是同样的问题,对于分解了的子问题分别求解,也可以在此分割,如此递归下去。
最后,自底向上逐步求出原问题的解。
5、实验器材(设备、元器件)
硬件环境:
i5-2450M双核处理器,2.5GHz,NVIDIAGT630M独立显卡芯片,1GB独立显存,2GBDDR3内存,500GB硬盘空间
软件环境:
Windows7操作系统及以上,MicrosoftVisualStudio2010
6、实验步骤:
(一)给定一个顺序表,编写一个求出其最大值和最小值的分治算法。
编写实验源代码如下:
/*
给定一个顺序表编写一个求出其最大值和最小值的分治算法
*/
#include"
stdafx.h"
#include<
stdio.h>
string.h>
math.h>
stdlib.h>
#defineLen1000000
#defineMIN(a,b)((a)>
(b)?
(b):
(a))
#defineMAX(a,b)((a)>
(a):
(b))
inta[Len],n;
intGetMin(intl,intr){
if(l==r)returna[l];
intmid=(l+r)>
>
1;
returnMIN(GetMin(l,mid),GetMin(mid+1,r));
}
intGetMax(intl,intr){
returnMAX(GetMax(l,mid),GetMax(mid+1,r));
intmain()
{
inti;
printf("
请输入您顺序表中元素的个数:
"
);
scanf("
%d"
&
n);
请依次输入您顺序表中的元素:
for(i=0;
i<
n;
i++)
a[i]);
printf("
MinValue=%d\n"
GetMin(0,n-1));
MaxValue=%d\n"
GetMax(0,n-1));
system("
pause"
运行结果如下:
我们可以多次运行程序,更改我们的输入,来检查程序的正确性。
(二)二分法求方程近似解:
实验源程序如下:
二分法求方程近¨
似解求方程f(x)=x^3+x^2-1=0在[0,1]上的近似解精确度为0.01。
doublefunction(doublex){
returnx*x*x+x*x-1;
doublel=0,r=1.0,mid;
while(r-l>
0.01){
mid=(r+l)/2;
if(function(mid)>
=0)
r=mid;
else
l=mid;
}
doubleans=r;
%.2f\n"
ans);
7、实验数据及结果分析:
程序的代码、数据、截图都放在实验步骤中具体体现,我们不妨来验证一下方程的解是否正确,将0.76带入函数中计算x^3+x^2-1中,得到结果为0.016576,这个结果在精度范围要求内是可以接受的,所以,我们可以说买这个程序得到的结果是可以接受的。
8、实验结论、心得体会和改进建议:
在本实验中,利用递归算法,很好地解决了求解序列表中最大、最小值以及求解方程的解的功能,当然递归算法虽然实现起来较为简单,但是效率上可能会造成一些资源的浪费,可能选用其他更高效的算法来解决这些问题。
实验二
动态规划算法实现
加深对动态规划算法原理及实现过程的理解
理解动态规划算法的原理,用动态规划算法实现最长公共子序列问题。
在动态规划算法中,对分治算法的效率进行了改善,同时能够解决更多种类的问题,一般适用于解最优化的问题。
动态规划算法一般分为四个步骤:
找出最优解的性质,并刻画其结构特征;
递归的定义最优值;
以自底向上的方式计算出最优值;
根据计算最优值时所得到的信息,构造最优解。
在这些步骤中,递归的定义最优值是动态规划算法的核心。
至于动态规划算法与分治算法的区别,动态规划算法一般解决分解出来的子问题数目太多,并且经分解的子问题往往不是相互独立的。
最长公共子序列问题描述:
若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有:
zj=xij。
设序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列为Z={z1,z2,…,zk},则:
(1)若xm=yn,则zk=xm=yn,且zk-1是xm-1和yn-1的最长公共子序列。
(2)若xm≠yn且zk≠xm,则Z是xm-1和Y的最长公共子序列。
(3)若xm≠yn且zk≠yn,则Z是X和yn-1的最长公共子序列。
最优值的计算:
由于在所考虑的子问题空间中,总共有θ(mn)个不同的子问题,因此,用动态规划算法自底向上地计算最优值能提高算法的效率
算法描述:
AlgorithmlcsLength(x,y,b)
mx.length-1;
ny.length-1;
c[i][0]=0;
c[0][i]=0;
for(inti=1;
=m;
for(intj=1;
j<
=n;
j++)
if(x[i]==y[j])
c[i][j]=c[i-1][j-1]+1;
b[i][j]=1;
elseif(c[i-1][j]>
=c[i][j-1])
c[i][j]=c[i-1][j];
b[i][j]=2;
else
c[i][j]=c[i][j-1];
b[i][j]=3;
源代码如下:
编程实现最长公共子序列。
#defineLen1000
intdp[Len][Len];
intn,m;
chara[Len],b[Len];
voidmain(){
inti,j;
%s"
a);
b);
n=strlen(a),m=strlen(b);
memset(dp,0,sizeof(0));
for(i=1;
=n;
for(j=1;
=m;
j++)
{
dp[i][j]=MAX(dp[i][j-1],dp[i-1][j]);
if(a[i-1]==b[j-1])
dp[i][j]=MAX(dp[i-1][j-1]+1,dp[i][j]);
LongestCommonSubsequence=%d\n"
dp[n][m]);
程序运行结果:
程序结果显示了两次输入的序列中最大的公共子序列长度。
例如,序列Z={B,C,D,B}是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。
给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。
例如:
X={A,B,C,B,D,A,B},Y={B,D,C,A,B,A}
{B,C,A}
{B,C,B,A}
由最长公共子序列问题的最优子结构性质建立子问题最优值的递归关系。
用c[i][j]记录序列X和Y的最长公共子序列的长度。
其中,Xi={x1,x2,…,xi};
Yj={y1,y2,…,yj}。
当i=0或j=0时,空序列是Xi和Yj的最长公共子序列。
故此时C[i][j]=0。
其他情况下,由最优子结构性质可建立递归关系如下:
用递归算法进行设计,很多子问题重复计算,无形的增加了算法计算量!
动态规划算法具有较好的效率可以解决规模较大的问题。
如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。
动态规划算法正是保留这样的特点,所以能够取得较好的效率。
实验三
贪心算法实现
加深对贪心算法原理及实现过程的理解;
编程实现Dijkstra算法,构造Huffman树;
(1)理解Dijkstra算法的原理,用Dijkstra算法编程找出从s到t的最短路径,图中每条边旁边的数字为此边的长度。
(2)根据给定的N个权值构造一棵哈夫曼树,要求输出每个节点的权值、父节点编号和左右孩子的编号,并输出相应的哈夫曼编码。
哈夫曼树,即最优树,是带权路径长度最短的树。
有着广泛的应用。
在解决某些判定问题