算法设计与分析实验报告Word下载.docx
《算法设计与分析实验报告Word下载.docx》由会员分享,可在线阅读,更多相关《算法设计与分析实验报告Word下载.docx(26页珍藏版)》请在冰豆网上搜索。
那末,对于这类问题分治法是十分有效的。
掌握分治法的一般控制流程。
DanC(p,q)
globaln,A[1:
n];
integerm,p,q;
验内容
编程实现归并排序算法和快速排序算法,程序中加入比较次数的计数功能,输出排序结果和比较次数。
输入10组相同的数据,验证排序结果和完成排序的比较次数。
与复杂性函数所计算的比较次数比较。
用表格列出比较结果。
给出文字分析。
三.程序算法
1.归并排序算法
procedureMERGESORT(low,high)
快速排序算法
QuickSort(p,q)
序代码
归并排序
#include<
>
#defineM11
typedefintKeyType;
typedefintElemType;
structrec{
KeyTypekey;
ElemTypedata;
};
typedefrecsqlist[M];
classguibing{
public:
guibing(sqlistb)
{
for(inti=0;
i<
M;
i++)
r[i]=b[i];
}
voidoutput(sqlistr,intn)
{
for(inti=0;
n;
cout<
<
setw(4)<
r[i].key;
cout<
endl;
}
voidxuanze(sqlistb,intm,intn)
inti,j,k;
for(i=m;
n-1;
{
k=i;
for(j=i;
j<
j++)
if(b[k].key>
b[j].key)k=j;
if(k!
=i)
{
rectemp=b[k];
b[k]=b[i];
b[i]=temp;
}
}
voidmerge(intl,intm,inth,sqlistr2)
xuanze(r,l,m);
xuanze(r,m,h);
output(r,M);
k=i=l;
for(j=m;
m&
&
h;
k++)
if(r[i].key<
=r[j].key)
{
r2[k]=r[i];
i++;
}
else
r2[k]=r[j];
j++;
output(r2,M);
while(j<
h)
r2[k]=r[j];
j++;
k++;
while(i<
=m)
r2[k]=r[i];
i++;
output(r2,M);
private:
sqlistr;
};
voidmain()
cout<
"
guibingfa1运行结果:
\n"
;
sqlista,b;
inti,j=0,k=M/2,n=M;
srand(time(0));
for(i=0;
a[i].key=rand()%80;
b[i].key=0;
guibinggx(a);
排序前数组:
(a,M);
数组排序过程演示:
(j,k,n,b);
排序后数组:
(b,M);
();
快速排序
#defineMAXI10
typedefrecsqlist[MAXI];
classkuaisu
{
kuaisu(sqlista,intm):
n(m)
i++)b[i]=a[i];
voidquicksort(ints,intt)
inti;
if(s<
t){
i=part(s,t);
quicksort(s,i-1);
quicksort(i+1,t);
elsereturn;
intpart(ints,intt)
inti,j;
recp;
i=s;
j=t;
p=b[s];
while(i<
j)
j&
b[j].key>
=j--;
b[i]=b[j];
b[i].key<
=i++;
b[j]=b[i];
b[i]=p;
output();
returni;
voidoutput()
b[i].key;
sqlistb;
intn;
voidmain()
cout<
运行结果:
sqlista1;
inti,n=MAXI,low=0,high=9;
srand(time(0));
for(i=0;
a1[i].key=rand()%80;
kuaisupx(a1,n);
(low,high);
();
}
五.实验结果
实验二贪心法
优化问题
有n个输入,而它的解就由这n个输入满足某些事先给定的约束条件的某个子集组
成,而把满足约束条件的子集称为该问题的可行解。
可行解一般来说是不唯一的。
那些使目标函数取极值(极大或极小)的可行解,称为最优解。
贪心法求优化问题
算法思想:
在贪心算法中采用逐步构造最优解的方法。
在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。
决策一旦作出,就不可再更改。
作出贪心决策的依据称为贪心准则(greedycriterion)。
一般方法
1)根据题意,选取一种量度标准。
2)按这种量度标准对这n个输入排序
3)依次选择输入量加入部分解中。
如果当前这个输入量的加入,不满足约束条件,则不把此输入加到这部分解中。
procedureGREEDY(A,n)/*贪心法一般控制流程*/
编程实现背包问题贪心算法和最小生成树prim算法。
通过具体算法理解如何通过局部最优实现全局最优,并验证算法的时间复杂性。
输入5个的图的邻接矩阵,程序加入统计prim算法访问图的节点数和边数的语句。
将统计数与复杂性函数所计算的比较次数比较,用表格列出比较结果,给出文字分析。
背包问题的贪心算法
procedureKNAPSACK(P,W,M,X,n)
序代码
背包问题贪心算法
#include<
structgoodinfo
floatp;
>
goods[i].p)
goods[i+1]=goods[i];
i--;
goods[i+1]=goods[0];
}=0;
cu=M;
cu)=1;
cu=cu-goods[i].w;
=cu/goods[i].w;
lag<
goods[i].flag)
cout<
最优解为:
for(i=1;
=n;
第"
件物品要放:
goods[i].X<
{
|--------运用贪心法解背包问题---------|"
|-------------------------------------|"
intj;
floatM;
goodinfo*goods;
lag=i;
请输入第"
件物品的重量:
cin>
goods[i].w;
件物品的效益:
goods[i].p;
goods[i].p=goods[i].p/goods[i].w;
dj;
"
MiniSpanTree_PRIM(G,'
a'
);
voidCreateGraph(MGraph&
G)
intweigh;
inti,j=0,k=0;
charhand,tide;
inputthenumberforvexnumandarcnum:
for(i=0;
i<
;
i++)
for(j=0;
j<
j++)
[i][j].adj=88;
input"
charforvexs:
[i];
arc(char,char,weigh):
j=0;
k=0;
:
hand;
tide;
weigh;
while(hand!
=[j])
j++;
while(tide!
=[k])
k++;
[j][k].adj=weigh;
[k][j].adj=weigh;
voidMiniSpanTree_PRIM(MGraphG,VerTexTypeu)
inti,j,k=0;
closedgeclose;
k=LocateVex(G,u);
for(j=0;
j++)
if(j!
=k)
close[j].adjvex=[k];
close[j].lowcost=[k][j].adj;
close[j].lowcost=88;
close[j].adjvex='
\0'
close[k].lowcost=0;
close[k].adjvex=u;
for(i=1;
{
k=minimum(close);
close[k].adjvex;
---->
[k]<
close[k].lowcost<
for(j=0;
j<
if[k][j].adj<
close[j].lowcost)
intLocateVex(MGraphG,VerTexTypeu)
intk=0;
while[k++]==u)
returnk-1;
return0;
intminimum(closedgeclose)
intj1=0,client=88,j2;
while(close[j1].adjvex!
='
)
if(client>
close[j1].lowcost&
close[j1].lowcost!
=0)
client=close[j1].lowcost;
j2=j1;
j1++;
returnj2;
1.背包问题贪心算法
2.Prim算法
实验三动态规划
理解最优子结构的问题。
有一类问题的活动过程可以分成若干个阶段,而且在任一阶段后的行为依赖于该阶段的状态,与该阶段之前的过程如何达到这种状态的方式无关。
这类问题的解决是多阶段的决策过程。
在50年代,贝尔曼(RichardBellman)等人提出了解决这类问题的“最优化原理”,从而创建了最优化问题的一种新的算法设计方法-动态规划。
对于一个多阶段过程问题,是否可以分段实现最优决策,依赖于该问题是否有最优子结构性质,能否采用动态规划的方法,还要看该问题的子问题是否具有重叠性质。
最优子结构性质:
原问题的最优解包含了其子问题的最优解。
子问题重叠性质:
每次产生的子问题并不总是新问题,有些子问题被反复计算多次。
问题的最优子结构性质和子问题重叠性质是采用动态规划算法的两个基本要素。
理解分段决策Bellman方程。
每一点最优都是上一点最优加上这段长度。
即当前最优只与上一步有关。
us初始值,uj第j段的最优值。
找出最优解的性质,并刻画其结构特征;
递归地定义最优值(写出动态规划方程);
以自底向上的方式计算出最优值;
根据计算最优值时得到的信息,构造一个最优解。
步骤1-3是动态规划算法的基本步骤。
在只需要求出最优值的情形,步骤4可以省略,步骤3中记录的信息也较少;
若需要求出问题的一个最优解,则必须执行步骤4,步骤3中记录的信息必须足够多以便构造最优解。
二.实验内容
编程实现多段图的最短路径问题的动态规划算法。
图的数据结构采用邻接表。
要求用文件装入5个多段图数据,编写从文件到邻接表的函数。
验证算法的时间复杂性。
三.核心算法
多段图算法
procedureFGRAPH(E,k,n,P)
多段图问题
#defineMAX_VERTEX_NUM50
typedefstructArcNode
intadjvex;
ata=m;
G->
vertices[m].firstArc=NULL;
for(m=1;
m<
=a;
m++)
i=1;
printf("
输入第%d条弧:
m);
scanf("
%d,%d,%d"
&
t,&
h,&
v);
p=(ArcNode*)malloc(sizeof(ArcNode));
p->
adjvex=h;
value=v;
nextarc=NULL;
while(G->
vertices[i].data!
=t)i++;
irstArc)irstArc=p;
else
{irstArc;
q->
nextarc;
q=q->
nextarc);
q->
nextarc=p;
irstArc;
[%d]"
i);
while(p)
printf("
->
%d,%d"
p->
adjvex,p->
value);
irstArc;
min=p->
value+cost[p->
adjvex];
验结果
实验四深度优先搜索
理解深度优先搜索策略:
深度优先搜索策略是尽可能“深”地搜索图。
在深度优先搜索中,对于最新发现的顶点v,如果边(v,w)是还未探测的边,则沿(v,w)继续搜索下去。
当所有的边(v,w)都己被探寻过,搜索将回溯到发现结点v的顶点。
这一过程一直进行到回到源点为止。
如果还存在未被发现的顶点,则选择其中一个作为源结点并重复以上过程,整个进程反复进行直到所有结点都被发现为止。
理解深度优先搜索过程中顶点的三种状态:
还未到达的顶点,当前路径上经过的顶点,深度优先在搜索过程中也为结点着色以表示结点的状态。
每个顶点开始均为白色,搜索中被发现时置为灰色,当其邻接表被完全检索之后又被置成黑色。
编程实现深度优先搜索算法。
修改算法使之可以找出图的所有树。
修改算法使之可以判断图是否为一棵树。
修改算法使之可以判断图是否存在一个环。
procedureDFS(G);
for每个顶点u∈Gdo
color[u]←White;
repeat
for每个顶点u∈Gdo
ifcolor[u]=White
thenDFS_Visit(G,u);
end;
procedureDFS_Visit(u);
color[u]←Gray;
for(u,w)∈Edo序代码
#defineMAX50验结果
实验五回溯法
理解可用回溯法求解的问题
问题P通常要能表达为对已知的、由n元组(x1,…,xn)组成的状态空间E={(x1,…,xn)|xiSi,i=1,2,…n},给定关于n元组中的分量的一个约束集D,求满足D的全部约束条件的所有n元组。
Si是xi的定义域且Si是有穷集,称E中满足D的全部约束条件的所有n元组为问题P的一个解。
理解回溯法的基本思想
回溯法是一个既带有系统性又带有跳跃性的搜索算法。
它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。
算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。
如果肯定不包含,则跳过对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。
否则,进入该子树,继续按深度优先的策略进行搜索。
回溯法的形式描述:
procedureBACAKTRACE(n)
k=1;
while(k>
0)do
ifTk(x1,x2,…,xk-1)的值还未取遍then
{xk←Tk(x1,x2,…,xk-1)中未取遍过的值;
ifBk(x1,x2,…,xk)then
{(x1,x2,…,xk)被激活;
ifk==nthen输出(x1,x2,…,xn);
elsek=k+1;
编程实现n皇后算法。
用图形输出中间过程。
在程序中添加统计扩展节点数,估计算法的复杂性。
n皇后算法
procedureNQUEENS(n)
X
(1)←0;
k←1序代码
/*检查可不可以放置一个新的皇后*/
boolplace(intk,int*X)
inti;
i=1;
while(i<
k)
if((X[i]==X[k])||(abs(X[i]-X[