终稿 算法设计与分析实验报告格式 3Word格式文档下载.docx
《终稿 算法设计与分析实验报告格式 3Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《终稿 算法设计与分析实验报告格式 3Word格式文档下载.docx(27页珍藏版)》请在冰豆网上搜索。
//文本文件的标题序号
charctu='
y'
;
while(ctu=='
||ctu=='
Y'
)
{process(file_count);
cout<
"
是否继续(y/Y)"
cin>
>
ctu;
++file_count;
}
return0;
}
voidprocess(intm)
{
memset(result_num,0,sizeof(result_num));
//每次新的运算均需要把数组值都置为
ostringstreamtstr;
intpaper_page;
tstr<
input"
m<
.txt"
ofstreamfout_test(tstr.str().c_str());
//保存页码的文件
tstr.str("
);
output"
ofstreamfout_result(tstr.str().c_str());
//保存结果的文件
cout<
请输入页码数:
paper_page;
fout_test<
fout_test.close();
for(inti=1;
i<
=paper_page;
++i)
{
inttmp=i;
while(tmp)
{
intnum=tmp%10;
++result_num[num];
tmp=tmp/10;
//cout<
tmp<
}}
for(intj=0;
j<
10;
++j)
fout_result<
result_num[j]<
\n"
fout_result.close();
5.程序调试中的问题
出现一些小错误,修改后程序可运行。
六.实验结果
定义数组a[10]存放0到9这10个数出现的次数,个位为第0位,第j位的数字为r。
a.
统计从个位算起前j位0~9个数;
b.
如果j+1位为0,去掉第j+1位补0个数;
c.
统计第j+1位出现1~(r-1)个数;
基本满足实验要求。
算法设计与分析实验报告二
实验名称分治法实现归并排序算法评分
实验日期2013年11月4日指导教师
姓名专业班级计算机学号201
1.了解用分治法求解的问题:
当要求解一个输入规模为n,且n的取值相当大的问题时,
如果问题可以分成k个不同子集合,得到k个不同的可独立求解的子问题,其中1<
k≤n,而且子问题与原问题性质相同,原问题的解可由这些子问题的解合并得出。
那末,对于这类问题分治法是十分有效的。
2.掌握分治法的一般控制流程。
DanC(p,q)
globaln,A[1:
n];
integerm,p,q;
//1pqn
ifSmall(p,q)thenreturnG(p,q);
elsem=Divide(p,q);
//pm<
q
returnCombine(DanC(p,m),DanC(m+1,q));
endif
endDanC
3.实现典型的分治算法的编程与上机实验,验证算法的时间复杂性函数。
1.编程实现归并排序算法,程序中加入比较次数的计数功能,输出排序结果和比较次数。
2.输入10组相同的数据,验证排序结果和完成排序的比较次数。
3.与复杂性函数所计算的比较次数比较。
4.用表格列出比较结果。
5.给出文字分析。
三.程序算法
1.归并排序算法
procedureMERGESORT(low,high)
//A(low;
high)是一个全程数组,它含
有high-low+1≥0个待排序的元素//
integerlow,high;
iflow<
high;
thenmid←,//求这个集合的分割点//
callMERGESORT(low,mid)//将一个子集合排序//
callMERGESORT(mid+1,high)//将另一个子集合排序
callMERGE(low,mid,high)//归并两个已排序的子集合//
endMERGESORT
归并两个已排序的集合
procedureMERGE(low,mid,high)
//A(low:
high)是一个全程数组//
//辅助数组B(low;
high)//
integerh,i,j,k;
h←low;
i←low;
j←mid+1;
whileh≤midandj≤highdo//当两个集合都没取尽时//
ifA(h)≤A(j)thenB(i)←A(h);
h←h+1
elseB(i)←A(j);
j←j+1
i←i+1
repeat
ifh>
midthen
fork←jtohighdo//处理剩余的元素//
B(i)←A(k);
i←i+1
elsefork←htomiddo
将已归并的集合复制到A
endMERGE
2.快速排序算法
QuickSort(p,q)
//将数组A[1:
n]中的元素
A[p],A[p+1],,A[q]按不降次序排列,
并假定A[n+1]是一个确定的、且大于
A[1:
n]中所有的数。
//
intp,q;
globaln,A[1:
ifp<
qthen
j=Partition(p,q+1);
//划分后j成为划分元素的位置
QuickSort(p,j-1);
QuickSort(j+1,q);
endQuickSort
procedurePARTITION(m,p)
//退出过程时,p带着划分元素所在的下标位置。
integerm,p,i;
globalA(m:
p-1)
v←A(m);
i←m//A(m)是划分元素//
loop
loopi←i+1untilA(i)≥vrepeat//i由左向右移//
loopp←p-1untilA(p)≤vrepeat//p由右向左移//
ifi<
p
thencallINTERCHANGE(A(i),A(p))//A(i)和A(p)换位//
elseexit
A(m)←A(p);
A(p)←v//划分元素在位置p//
EndPARTITION
4.程序代码
1.归并排序
iostream.h>
iomanip.h>
stdlib.h>
time.h>
#defineM11
typedefintKeyType;
typedefintElemType;
structrec{
KeyTypekey;
ElemTypedata;
};
typedefrecsqlist[M];
classguibing{
public:
guibing(sqlistb)
for(inti=0;
M;
i++)
r[i]=b[i];
voidoutput(sqlistr,intn)
for(inti=0;
n;
cout<
setw(4)<
r[i].key;
cout<
}
voidxuanze(sqlistb,intm,intn)
inti,j,k;
for(i=m;
n-1;
{
k=i;
for(j=i;
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()
guibingfa1运行结果:
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);
排序前数组:
gx.output(a,M);
数组排序过程演示:
gx.merge(j,k,n,b);
排序后数组:
gx.output(b,M);
cin.get();
2.快速排序
#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>
=p.key)j--;
b[i]=b[j];
b[i].key<
=p.key)i++;
b[j]=b[i];
b[i]=p;
output();
returni;
voidoutput()
b[i].key;
sqlistb;
intn;
voidmain()
{cout<
kuaisu1.cpp运行结果:
sqlista1;
inti,n=MAXI,low=0,high=9;
srand(time(0));
for(i=0;
a1[i].key=rand()%80;
kuaisupx(a1,n);
px.quicksort(low,high);
px.output();
cin.get();
排序算法设计比较经典也比较难,调试中不乏出现各种问题,借鉴了经典算法最终完成实验。
算法设计与分析实验报告三
实验名称动态规划算法实现多段图的最短路径问题评分
姓名专业班级计算机学号2104
1.理解最优子结构的问题。
有一类问题的活动过程可以分成若干个阶段,而且在任一阶段后的行为依赖于该阶段的状态,与该阶段之前的过程如何达到这种状态的方式无关。
这类问题的解决是多阶段的决策过程。
在50年代,贝尔曼(RichardBellman)等人提出了解决这类问题的“最优化原理”,从而创建了最优化问题的一种新的算法设计方法-动态规划。
对于一个多阶段过程问题,是否可以分段实现最优决策,依赖于该问题是否有最优子结构性质,能否采用动态规划的方法,还要看该问题的子问题是否具有重叠性质。
最优子结构性质:
原问题的最优解包含了其子问题的最优解。
子问题重叠性质:
每次产生的子问题并不总是新问题,有些子问题被反复计算多次。
问题的最优子结构性质和子问题重叠性质是采用动态规划算法的两个基本要素。
2.理解分段决策Bellman方程。
每一点最优都是上一点最优加上这段长度。
即当前最优只与上一步有关。
Us初始值,uj第j段的最优值。
3.一般方法
1)找出最优解的性质,并刻画其结构特征;
2)递归地定义最优值(写出动态规划方程);
3)以自底向上的方式计算出最优值;
4)根据计算最优值时得到的信息,构造一个最优解。
步骤1-3是动态规划算法的基本步骤。
在只需要求出最优值的情形,步骤4可以省略,步骤3中记录的信息也较少;
若需要求出问题的一个最优解,则必须执行步骤4,步骤3中记录的信息必须足够多以便构造最优解。
1.编程实现多段图的最短路径问题的动态规划算法。
2.图的数据结构采用邻接表。
3.要求用文件装入5个多段图数据,编写从文件到邻接表的函数。
4.验证算法的时间复杂性。
五.程序调试中的问题
算法设计与分析实验报告四
实验名称贪心算法实现背包问题评分
姓名专业班级计算机101学号201013
1.优化问题
有n个输入,而它的解就由这n个输入满足某些事先给定的约束条件的某个子集组
成,而把满足约束条件的子集称为该问题的可行解。
可行解一般来说是不唯一的。
那些使目标函数取极值(极大或极小)的可行解,称为最优解。
2.贪心法求优化问题
算法思想:
在贪心算法中采用逐步构造最优解的方法。
在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。
决策一旦作出,就不可再更改。
作出贪心决策的依据称为贪心准则(greedycriterion)。
1)根据题意,选取一种量度标准。
2)按这种量度标准对这n个输入排序
3)依次选择输入量加入部分解中。
如果当前这个输入量的加入,不满足约束条件,则不把此输入加到这部分解中。
procedureGREEDY(A,n)/*贪心法一般控制流程*/
//A(1:
n)包含n个输入//
solutions←φ//将解向量solution初始化为空/
fori←1tondo
x←SELECT(A)
ifFEASIBLE(solution,x)
thensolutions←UNION(solution,x)
return(solution)
endGREEDY
4.实现典型的贪心算法的编程与上机实验,验证算法的时间复杂性函数。
1.编程实现背包问题贪心算法。
通过具体算法理解如何通过局部最优实现全局最优,并验证算法的时间复杂性。
2.输入5个的图的邻接矩阵,程序加入统计prim算法访问图的节点数和边数的语句。
3.将统计数与复杂性函数所计算的比较次数比较,用表格列出比较结果,给出文字分析。
从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。
当达到某算法中的某一步不能再继续前进时,算法停止。
该算法存在问题:
1.
不能保证求得的最后解是最佳的;
2.
不能用来求最大或最小解问题;
3.
只能求满足某些约束条件的可行解的范围。
(i)一种贪婪准则为:
从剩余的物品中,选出可以装入背包的价值最大的物品,利用这种规则,价值最大的物品首先被装入(假设有足够容量),然后是下一个价值最大的物品,如此继续下去。
这种策略不能保证得到最优解。
例如,考虑n=2,w=[100,10,10],p=[20,15,15],c=105。
当利用价值贪婪准则时,获得的解为x=[1,0,0],这种方案的总价值为20。
而最优解为[0,1,1],其总价值为30。
(ii)另一种方案是重量贪婪准则是:
从剩下的物品中选择可装入背包的重量最小的物品。
虽然这种规则对于前面的例子能产生最优解,但在一般情况下则不一定能得到最优解。
考虑n=2,w=[10,20],p=[5,100],c=25。
当利用重量贪婪策略时,获得的解为x=[1,0],比最优解[0,1]要差。
(iii)还有一种贪婪准则,就是我们教材上提到的,认为,每一项计算yi=vi/si,即该项值和大小的比,再按比值的降序来排序,从第一项开始装背包,然后是第二项,依次类推,尽可能的多放,直到装满背包。
有的参考资料也称为价值密度pi/wi贪婪算法。
这种策略也不能保证得到最优解。
利用此策略试解n=3,w=[20,15,15],p=[40,25,25],c=30时的最优解。
虽然按pi/wi非递(增)减的次序装入物品不能保证得到最优解,但它是一个直觉上近似的解。
而且这是解决普通背包问题的最优解,因为在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n。
iostream"
structgoodinfo
{
floatp;
//物品效益
floatw;
//物品重量
floatX;
//物品该放的数量
intflag;
//物品编号
//物品信息结构体
voidInsertionsort(goodinfogoods[],intn)
intj,i;
for(j=2;
=n;
j++)
{
goods[0]=goods[j];
i=j-1;
while(goods[0].p>
goods[i].p)
goods[i+1]=goods[i];
i--;
}
goods[i+1]=goods[0];
}//按物品效益,重量比值做升序排列
voidbag(goodinfogoods[],floatM,intn)
floatcu;
inti,j;
for(i=1;
i++)
goods[i].X=0;
cu=M;
//背包剩余容量
if(goods[i].w>
cu)//当该物品重量大与剩余容量跳出
break;
goods[i].X=1;
cu=cu-goods[i].w;
//确定背包新的剩余容量
if(i<
=n)
goods[i].X=cu/goods[i].w;
//该物品所要放的量
//按物品编号做降序排列
while(goods[0].flag<
goods[i].flag)
goods[i