算法设计综合实验报告.docx

上传人:b****8 文档编号:30395819 上传时间:2023-08-14 格式:DOCX 页数:30 大小:139.30KB
下载 相关 举报
算法设计综合实验报告.docx_第1页
第1页 / 共30页
算法设计综合实验报告.docx_第2页
第2页 / 共30页
算法设计综合实验报告.docx_第3页
第3页 / 共30页
算法设计综合实验报告.docx_第4页
第4页 / 共30页
算法设计综合实验报告.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

算法设计综合实验报告.docx

《算法设计综合实验报告.docx》由会员分享,可在线阅读,更多相关《算法设计综合实验报告.docx(30页珍藏版)》请在冰豆网上搜索。

算法设计综合实验报告.docx

算法设计综合实验报告

 

院系:

计算机科学学院

专业:

计算机科学与技术

年级:

2008

课程名称:

算法设计与分析基础

班号:

计科一班

组号:

32

指导教师:

 

2010年12月10日

组员

学号

姓名

实验名称

算法实验主菜单的设计

实验室

9#203

实验目的:

1)熟悉实验环境VC++6.0;

2)复习C、C++语言以及数据结构课程的相关知识,实现课程间的平滑过度;

实验要求:

1)设计的主菜单可以是图形模式的,也可以是控制台模式的。

以控制台为例,主菜单大致如下:

-------------------------

《算法设计与分析》实验

-------------------------

1.算法分析基础——Fibonacci序列问题

2.分治法在数值问题中的应用——最近点对问题

3.减治法在组合问题中的应用——8枚硬币问题

4.变治法在排序问题中的应用——堆排序问题

5.动态规划法在图问题中的应用——全源最短路径问题

99.退出本实验

-------------------------

请输入您所要执行的操作(1,2,3,4,5,99):

2)点击操作后进入相应的实验项目或是相应项目的下一级菜单;

3)可以反复执行,直到退出实验。

构造menu函数,以菜单形式输出控制界面(按需求分析要求);

构造switch(start)函数,控制各个子程序,以解决各个问题:

switch(start)

{

case1:

{}break;

case2:

{}break;

case3:

{}break;

case4:

{}break;

case5:

{}break;

case99:

return-1;

default:

printf("输入有误!

");

}

voidmenu()

{

printf("\n\n-----------------------------------------------------------");

printf("\n《算法设计与分析》实验");

printf("\n------------------------------------------------------------");

printf("\n1.算法分析基础——Fibonacci序列问题");

printf("\n2.分治法在数值问题中的应用——最近点对问题");

printf("\n3.减治法在组合问题中的应用——8枚硬币问题");

printf("\n4.变治法在排序问题中的应用——堆排序问题");

printf("\n5.动态规划法在图问题中的应用——全源最短路径问题");

printf("\n99.退出本实验");

printf("\n-------------------------------------------------------------------");

printf("\n请输入您所要执行的操作(1,2,3,4,5,99):

");

}

intmain()

{

intstart;

for(;;)

{

menu();

scanf("%d",&start);

switch(start)

{

case1:

{

system("cls");

printf("----------实验一.Fibonacci序列问题----------\n\n");

Fib();

fflush(stdin);

}break;

case2:

{

system("cls");

printf("----------实验二.最近点对问题----------\n");

closestPath();

fflush(stdin);

}break;

case3:

{

system("cls");

printf("----------实验三.8枚硬币问题----------\n");

Coins();

fflush(stdin);

}break;

case4:

{

system("cls");

printf("----------实验四.堆排序问题----------\n");

heapsort();

fflush(stdin);

}break;

case5:

{

system("cls");

printf("----------实验五.全源最短路径问题----------\n");

fflush(stdin);

}break;

case99:

return-1;

default:

printf("输入有误!

");

}

 

实验结果如下:

实现了以菜单形式的显示格式,清晰明了;

用户选择相应操作以解决相应问题;

 

实验名称

计算第n个斐波那契数

实验室

9#203

实验目的

1)理解递归算法和迭代算法的设计思想以及递归程序的调式技术

2)掌握并应用递归算法和迭代算法效率的理论分析(前验分析)和实际分析(后验分析)方法;

3)理解这样一个观点:

不同的算法可以解决相同的问题,这些算法的解题思路不同,复杂程度不同,效率也不同;

实验要求

1)使用教材2.5节中介绍的迭代算法Fib(n),找出最大的n,使得第n个Fibonacci数不超过计算机所能表示的最大整数,并给出具体的执行时间;

2)对于要求1),使用教材2.5节中介绍的递归算法F(n)进行计算,同样给出具体的执行时间,并同1)的执行时间进行比较;

3)对于输入同样的非负整数n,比较上述两种算法基本操作的执行次数;

4)对1)中的迭代算法进行改进,使得改进后的迭代算法其空间复杂度为Θ

(1);

5)设计可供用户选择算法的交互式菜单(放在相应的主菜单下)。

实验分别用递归算法和迭代算法求解,并对两种算法的运行时间进行比较;

递归算法:

设f(n)为斐波那契数列的第n个数。

那么有递归式f(n)=f(n-1)+f(n-2)。

按照这个朴素的递归思想可以得出结论。

但是时间复杂度是O(2^n),计算缓慢,解决不了大规模问题。

迭代算法

求解fib(n),把它推到求解fib(n-1)和fib(n-2)。

也就是说,为计算fib(n),必须先计算fib(n-1)和fib(n-2),而计算fib(n-1)和fib(n-2),又必须先计算fib(n-3)和fib(n-4)。

依次类推,直至计算fib

(1)和fib(0),分别能立即得到结果1和0。

迭代算法消除了大量重复的计算,效率上有了大幅提高。

unsignedlongF_RE(intn)

{

if(n==1)return0;

if(n==2)return1;

if(n>2)return(F_RE(n-1)+F_RE(n-2));

}

unsignedlongF_ITER(intn)

{unsignedlongf1=1,f2=1,fn;

if(n<=1)return0;

if(n==2||n==3)return1;

for(inti=4;i<=n;i++)

{

fn=f1+f2;

f1=f2;

f2=fn;

}

returnfn;

}

voidF_MAX(unsignedlongf,intn)

{

unsignedlongTemp,max;

max=pow(2,31)-1;//printf("%ld",max);

while(f<=max){

Temp=f;

n++;

f=F_ITER(n);

}

printf("\n\n不超出该32位计算机所能表示的最大整数\n及其所在序列中的位置为(%ld,%d)\t",Temp,n-1);

}

voidFib()

{unsignedlongF_i;

inti=0;

charch;

printf("选择输出第N个斐波拉契数:

\n");

printf("1.迭代算法;\n2.递归算法\t");

fflush(stdin);

ch=getchar();

if(ch=='1'){

printf("\n需要输出第几个数(1-50)?

\t");

scanf("%d",&i);

F_i=F_ITER(i);

printf("%ld\t",F_i);

F_MAX(F_i,i);

}

elseif(ch=='2'){

printf("\n需要输出第几个数(1-50)?

\t");

scanf("%d",&i);

F_i=F_ITER(i);

printf("%ld\t",F_RE(i));

F_MAX(F_i,i);

}

elseprintf("\n输入有误!

");

}

输出结果如下:

迭代算法

递归算法

递归算法在n超过20,效率低的缺点显露无疑;迭代法的优势就体现出来了。

实验名称

平面最近点问题

实验室

9#203

实验目的

1)提高应用蛮力法设计算法的技能;

2)深刻理解并掌握分治法的设计思想;

3)理解这样一个观点:

用蛮力法设计的算法,一般来说,经过适度的努力后,都可以对其进行改进,以提高算法的效率。

实验要求

1)设计并实现用BF方法求解最近点对问题的算法;

2)设计并实现用DAC方法求解最近点对问题的算法;

3)以上两种算法的输入既可以手动输入,也可以自动生成;

4)算法不仅要输出最近点对的距离,还要输出最近点对的两个点;

5)对上述两个算法进行时间复杂性分析,并设计实验程序验证分析结果;

6)设计可供用户选择算法的交互式菜单(放在相应的主菜单下)

 

 

分治法

已知集合S中有n个点,分治法的思想就是将S进行拆分,分为2部分求最近点对。

算法每次选择一条垂线L,将S拆分左右两部分为SL和SR,L一般取点集S中所有点的中间点的x坐标来划分,这样可以保证SL和SR中的点数目各为n/2,

(否则以其他方式划分S,有可能导致SL和SR中点数目一个为1,一个为n-1,不利于算法效率,要尽量保持树的平衡性)

依次找出这两部分中的最小点对距离:

δL和δR,记SL和SR中最小点对距离δ=min(δL,δR),如图1:

   

     对于SL虚框范围内的p点,在SR虚框中与p点距离小于δ的顶多只有六个点,就是图二右图中的2个正方形的6的顶点。

这个可以反推证明,如果右边这2个正方形内有7个点与p点距离小于δ,例如q点,则q点与下面正方形的四个顶点距离小于δ,则和δ为SL和SR中的最小点对距离相矛盾。

因此对于SL虚框中的p点,不需求出p点和右边虚线框内所有点距离,只需计算SR中与p点y坐标距离最近的6个点,就可以求出最近点对,节省了比较次数。

 

structnode

{intx_value;

inty_value;

doubleshortest_distance;

intresult_x_value;

intresult_y_value;

};

 

int*PARTITION(structnode*A,intstart,intend,intkey)

{

if(key==1)//按x排序

{

int*partition;

partition=newint;

doublex=A[end].x_value;

inti=start-1;

for(intj=start;j

{

if(A[j].x_value<=x)

{

i++;

structnodetant=A[i];

A[i]=A[j];

A[j]=tant;

}

}

structnodetant=A[i+1];

A[i+1]=A[end];

A[end]=tant;

*partition=i+1;

returnpartition;

}

else//按y排序

{

int*partition;

partition=newint;

doubley=A[end].y_value;

inti=start-1;

for(intj=start;j

{

if(A[j].y_value<=y)

{

i++;

structnodetant=A[i];

A[i]=A[j];

A[j]=tant;

}

}

structnodetant=A[i+1];

A[i+1]=A[end];

A[end]=tant;

*partition=i+1;

returnpartition;

}

}

 

voidquick_sort(structnode*A,intstart,intend,intkey)//可以根据x和y对结构体数组排序

{

if(end>start)

{

int*partition;

partition=newint;

partition=PARTITION(A,start,end,key);

quick_sort(A,start,*partition-1,key);

quick_sort(A,*partition,end,key);

}

}

 

voidcombine(structnode*A,structnode*result1,structnode*result2,structnode*result,intstart,intmiddle,intend)//合并两个部分的结果

{

doublemin_distance;

intn=end-start;

intlength=0;

intj,k;

structnodetant[100];//用以保存x_value在[middle-min_distance,middle+min_distance]的点

doublebelow,above;//below和above分别为[middle-min_distance,middle+min_distance]的上界和下界

intkeyword;

if(result1->shortest_distance>result2->shortest_distance)//寻找最小值

{result->x_value=result2->x_value;

result->y_value=result2->y_value;

result->result_x_value=result2->result_x_value;

result->result_y_value=result2->result_y_value;

result->shortest_distance=result2->shortest_distance;

min_distance=result2->shortest_distance;

}

else

{

result->x_value=result1->x_value;

result->y_value=result1->y_value;

result->result_x_value=result1->result_x_value;

result->result_y_value=result1->result_y_value;

result->shortest_distance=result1->shortest_distance;

min_distance=result1->shortest_distance;//min_distance=min{result1.shortes_distance,result2.shortest_distance}

}

below=A[middle].x_value-min_distance;

above=A[middle].x_value+min_distance;

for(inti=0;i<=n;i++)

if(A[i].x_value>=below&&A[i].x_value<=above)

tant[length++]=A[i];//构造临时数组,即x_value在[middle-min_distance,middle+min_distance]的点

keyword=2;

length--;

quick_sort(tant,0,length,keyword);

//按y对tant数组排序

for(k=0;k<=length+1;k++)

{

j=k+1;

while(j<=length&&(tant[j].y_value-tant[k].y_value<=min_distance||tant[k].y_value-tant[j].y_value<=min_distance))//?

?

2miin_distance

{

doubletant_distance;

doubletemp=(double)((tant[k].x_value-tant[j].x_value)*(tant[k].x_value-tant[j].x_value)+(tant[k].y_value-tant[j].y_value)*(tant[k].y_value-tant[j].y_value));

tant_distance=sqrt(temp);

if(tant_distance<=min_distance)

{

result->x_value=tant[k].x_value;

result->y_value=tant[k].y_value;

result->result_x_value=tant[j].x_value;

result->result_y_value=tant[j].y_value;

result->shortest_distance=tant_distance;

min_distance=tant_distance;

}

j++;

}

}

}

 

voidshortest_distance(structnode*A,structnode*result,intstart,intend)

{

if(end-start>2)

{

intmiddle;

structnode*result1=newstructnode;

structnode*result2=newstructnode;

//structnode*final_result=newstructnode;

result1->shortest_distance=1000000;

result2->shortest_distance=1000000;//初始化结果result1,result2

middle=(start+end)/2;

shortest_distance(A,result1,start,middle);

shortest_distance(A,result2,middle+1,end);

combine(A,result1,result2,result,start,middle,end);

}

else//分组内点数不足3个,直接得结果

{

for(inti=start;i<=end;i++)

for(intk=i+1;k<=end;k++)

{

doubletant_distance;

doubletemp=(double)((A[i].x_value-A[k].x_value)*(A[i].x_value-A[k].x_value)+(A[i].y_value-A[k].y_value)*(A[i].y_value-A[k].y_value));

tant_distance=sqrt(temp);

if(tant_distance<=result->shortest_distance)

{

result->x_value=A[i].x_value;

result->y_value=A[i].y_value;

result->result_x_value=A[k].x_value;

result->result_y_value=A[k].y_value;

result->shortest_distance=tant_distance;

}

}

}

}

 

voidclosestPath()

{

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1