算法实验报告.docx
《算法实验报告.docx》由会员分享,可在线阅读,更多相关《算法实验报告.docx(51页珍藏版)》请在冰豆网上搜索。
算法实验报告
中南民族大学
学生实验报告
院系:
计算机科学学院
专业:
计算机科学与技术
年级:
课程名称:
算法设计与分析基础
指导教师:
组号:
学号:
姓名:
2012年6月12日
年级
班号
学号
专业
计算机科学与技术
姓名
实验名称
算法实验主菜单的设计
实验
类型
设计型
综合型
创新型
实
验
目
的
或
要
求
⑴熟悉实验环境VC++6.0;
⑵复习C、C++语言以及数据结构课程的相关知识,实现课程间的平滑过度;
实验要求
1)设计的主菜单可以是图形模式的,也可以是控制台模式的。
以控制台为例,主菜单大致如下:
-------------------------
《算法设计与分析》实验
-------------------------
算法分析基础——Fibonacci序列问题
分治法在数值问题中的应用——矩阵相乘问题
减治法在组合问题中的应用——8枚硬币问题
变治法在排序问题中的应用——堆排序问题
动态规划法在图问题中的应用——全源最短路径问题
99.退出本实验
-------------------------
请输入您所要执行的操作(1,2,3,4,5,99):
2)点击操作后进入相应的实验项目或是相应项目的下一级菜单;
3)可以反复执行,直到退出实验。
实
验
原
理
(
算
法
流
程
)
intmenu1()
{
intn;
printf("-------------------------\n");
printf("《算法设计与分析》实验\n");
printf("-------------------------\n");
printf("1.算法分析基础——Fibonacci序列问题\n");
printf("2.分治法在数值问题中的应用——矩阵相乘问题\n");
printf("3.减治法在组合问题中的应用——8枚硬币问题\n");
printf("4.变治法在排序问题中的应用——堆排序问题\n");
printf("5.动态规划法在图问题中的应用——全源最短路径问题\n");
printf("99.退出本实验\n");
printf("-------------------------\n");
printf("请输入您所要执行的操作(1,2,3,4,5,99):
\n");
scanf("%d",&n);
returnn;
}
intmain(){
intn;
for(;;)
{n=menu1();/*1菜单*/
switch(n)
{case1:
run1();
break;
case2:
run2();
break;
case3:
run3();
break;
case4:
run4();
break;
case5:
system("cls");
printf("全源最短路径问题\n");
puts("\n\n\n\n\n");
break;
case99:
printf("退出程序!
");
exit(0);
default:
printf("出错!
\n");
exit
(1);
}
}
return0;
}
(写不完时,可另加附页。
)
实
验
结
果
分
析
及
心
得
体
会
主菜单如下:
心得体会:
有一个良好的菜单界面,可以给人耳目一新的感觉,这一点上做的还不错,每一个菜单下都有其子菜单,避免了臃肿的程序体
成
绩
评
定
教师签名:
年月日
年级
班号
学号
专业
计算机科学与技术
姓名
实验名称
算法分析基础——Fibonacci序列问题
实验
类型
设计型
综合型
创新型
实
验
目
的
或
要
求
实验题目
给定一个非负整数n,计算第n个Fibonacci数
实验目的
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个斐波那契数
//输入:
一个非负数n
//输出:
第几个斐波那契数
ifn≤1
returnn
else
returnF(n-1)+F(n-2)
迭代算法:
Fib(n)
//根据定义,递归计算第n个斐波那契数
//输入:
一个非负数n
//输出:
第几个斐波那契数
F[0]ß0,F[1]ß1
Foriß2tondo
F[i]ßF[i-1]+F[i-2]
ReturnF[n]
voidrun1_1()
{
intn,i,num;
longstart,end,count;
system("cls");
for(;;)
{
n=menu1_1_1();/*1.1.1菜单*/
switch(n)
{
case1:
system("cls");
printf("请输入一个非负整数:
");
scanf("%d",&num);
if(num<0||num>46)
printf("超出计算机计算范围!
!
!
\n");
else
printf("历时%ld毫秒\n\n\n\n\n",end-start);
}break;
{
start=clock();
count=fib1(num);
end=clock();
printf("第%d个Fibonacci数是%ld\n",num,count);
printf("历时%ld毫秒\n\n\n\n\n",end-start);
}
break;
case2:
system("cls");
start=clock();
for(i=0;fib1(i)>=0;i++);
end=clock();
i--;
printf("本机计算最大Fibonacci数是第%ld个,值为%ld\n",i,fib1(i));
printf("历时%ld毫秒\n\n\n\n\n",end-start);
break;
case3:
system("cls");
break;
case99:
printf("退出程序!
");
exit(0);
default:
printf("出错!
\n");
exit
(1);
}
if(n==3)break;
}
}
voidrun1_2()
{
intn,i,num;
longstart,end,count;
system("cls");
for(;;)
{
n=menu1_1_2();/*1.1.2菜单*/
switch(n)
{
case1:
system("cls");
printf("请输入一个非负整数:
");
scanf("%d",&num);
if(num<0||num>46)
printf("超出计算机计算范围!
!
!
\n");
else
{
start=clock();
count=fib2(num);
end=clock();
printf("第%d个Fibonacci数是%ld\n",num,count);
printf("历时%ld毫秒\n\n\n\n\n",end-start);
}
break;
case2:
system("cls");
start=clock();
for(i=0;fib2(i)>=0;i++);
end=clock();
i--;
printf("本机计算最大Fibonacci数是第%ld个,值为%ld\n",i,fib2(i));
printf("历时%ld毫秒\n\n\n\n\n",end-start);
break;
case3:
system("cls");
break;
case99:
printf("退出程序!
");
exit(0);
default:
printf("出错!
\n");
exit
(1);
}
if(n==3)break;
}
}
(写不完时,可另加附页。
)
实
验
原
理
(
算
法
流
程
)
case2:
system("cls");
start=clock();
for(i=0;fib1(i)>=0;i++);
end=clock();
i--;
printf("本机计算最大Fibonacci数是第%ld个,值为%ld\n",i,fib1(i));
printf("历时%ld毫秒\n\n\n\n\n",end-start);
break;
case3:
system("cls");
break;
case99:
printf("退出程序!
");
exit(0);
default:
printf("出错!
\n");
exit
(1);
}
if(n==3)break;
}
}
voidrun1_2()
{intn,i,num;
longstart,end,count;
system("cls");
for(;;)
{
n=menu1_1_2();/*1.1.2菜单*/
switch(n)
{
case1:
system("cls");
printf("请输入一个非负整数:
");
scanf("%d",&num);
if(num<0||num>46)
printf("超出计算机计算范围!
!
!
\n");
else
{start=clock();
count=fib2(num);
end=clock();
printf("第%d个Fibonacci数是%ld\n",num,count);
printf("历时%ld毫秒\n\n\n\n\n",end-start);
}break;
(写不完时,可另加附页。
)
实
验
原
理
(
算
法
流
程
)
case2:
system("cls");
start=clock();
for(i=0;fib2(i)>=0;i++);
end=clock();
i--;
printf("本机计算最大Fibonacci数是第%ld个,值为%ld\n",i,fib2(i));
printf("历时%ld毫秒\n\n\n\n\n",end-start);break;
case3:
system("cls");break;
case99:
printf("退出程序!
");
exit(0);
default:
printf("出错!
\n");
exit
(1);
}if(n==3)break;
}
}
start=clock();
count=fib2(num);
end=clock();
printf("第%d个Fibonacci数是%ld\n",num,count);
printf("历时%ld毫秒\n\n\n\n\n",end-start);
}break;
case2:
system("cls");
start=clock();
for(i=0;fib2(i)>=0;i++);
end=clock();
i--;
printf("本机计算最大Fibonacci数是第%ld个,值为%ld\n",i,fib2(i));
printf("历时%ld毫秒\n\n\n\n\n",end-start);break;
case3:
system("cls");break;
case99:
printf("退出程序!
");
exit(0);default:
printf("出错!
\n");
exit
(1);
}
if(n==3)break;
}
}
(写不完时,可另加附页。
)
组
内
分
工
(
可
选
)
实
验
结
果
分
析
及
心
得
体
会
迭代算法算出最大的Fibonacci数是46个
递归算法算出Fibonacci最大为第46个,耗时644900毫秒
成
绩
评
定
教师签名:
年月日
备注:
源代码附后,源代码要求有注释说明
年级
班号
学号
专业
计算机科学与技术
姓名
实验名称
分治法在数值问题中的应用
——矩阵相乘问题
实验
类型
设计型
综合型
创新型
实
验
目
的
或
要
求
实验题目
设M1和M2是两个n×n的矩阵,设计算法计算M1×M2的乘积。
实验目的
1)提高应用蛮力法设计算法的技能;
2)深刻理解并掌握分治法的设计思想;
3)理解这样一个观点:
用蛮力法设计的算法,一般来说,经过适度的努力后,都可以对其进行改进,以提高算法的效率。
实验要求
1)设计并实现用BF方法求解矩阵相乘问题的算法;
2)设计并实现用DAC方法求解矩阵相乘问题的算法;
3)以上两种算法的输入既可以手动输入,也可以自动生成;
4)对上述两个算法进行时间复杂性分析,并设计实验程序验证;
5)设计可供用户选择算法的交互式菜单(放在相应的主菜单
实
验
原
理
(
算
法
流
程
)
M1~M7的公式:
M1=(A0+A3)×(B0+B3)
M2=(A2+A3)×B0
M3=A0×(B1-B3)
M4=A3×(B2-B0)
M5=(A0+A1)×B3
M6=(A2-A0)×(B0+B1)
M7=(A1-A3)×(B2+B3)
C0~C3的公式:
C0=M1+M4-M5+M7
C1=M3+M5
C2=M2+M4
C3=M1-M2+M3+M6
voidrun2()
{
intn;
system("cls");
for(;;)
{
n=menu1_2();/*1.2菜单*/
switch(n)
{
case1:
run2_1();
break;
case2:
run2_2();
break;
case3:
system("cls");
break;
case99:
printf("退出程序!
");
exit(0);
default:
printf("出错!
\n");
exit
(1);
}
if(n==3)break;
}
}
voidrun2_1()
{intn;
system("cls");
for(;;)
(写不完时,可另加附页。
)
实
验
原
理
(
算
法
流
程
)
{
n=menu1_2_1();/*1.2.1菜单*/
switch(n)
{
case1:
run2_1_1();
break;
case2:
run2_1_2();
break;
case3:
system("cls");
break;
case99:
printf("退出程序!
");
exit(0);
default:
printf("出错!
\n");
exit
(1);
}
if(n==3)break;
}
}
voidrun2_1_1()
{
longstart,end;
system("cls");
structTSMartrixM,N,Q;
do
{
Hand_CreateSMartrix(M);
Hand_CreateSMartrix(N);
if(M.nu!
=N.mu)
printf("前矩阵的列数不等于后矩阵的行数,无法做乘法!
!
!
\n");
}while(M.nu!
=N.mu);
Q.mu=M.mu;
Q.nu=N.nu;
start=clock();
BF_MultSMatrix(M,N,Q);
end=clock();
printf("矩阵M:
\n");
OutputSMartrix(M);
printf("矩阵N:
\n");
OutputSMartrix(N);
(写不完时,可另加附页。
)
实
验
原
理
(
算
法
流
程
)
printf("矩阵M*N:
\n");
OutputSMartrix(Q);
printf("历时%ld毫秒\n",end-start);
}
voidrun2_1_2()
{
longstart,end;
system("cls");
structTSMartrixM,N,Q;
do
{
Rand_CreateSMartrix(M);
Rand_CreateSMartrix(N);
if(M.nu!
=N.mu)
printf("前矩阵的列数不等于后矩阵的行数,无法做乘法!
!
!
\n");
}while(M.nu!
=N.mu);
Q.mu=M.mu;
Q.nu=N.nu;
start=clock();
BF_MultSMatrix(M,N,Q);
end=clock();
printf("矩阵M:
\n");
OutputSMartrix(M);
printf("矩阵N:
\n");
OutputSMartrix(N);
printf("矩阵M*N:
\n");
OutputSMartrix(Q);
printf("历时%ld毫秒\n",end-start);
}
voidrun2_2()
{
intn;
system("cls");
for(;;)
{
n=menu1_2_2();/*1.2.1菜单*/
switch(n)
{
case1:
run2_2_1();
break;
case2:
run2_2_2();
break;
(写不完时,可另加附页。
)
case3:
system("cls");
break;
case99:
printf("退出程序!
");
exit(0);
default:
printf("出错!
\n");
exit
(1);
}
if(n==3)break;
}
}
voidrun2_2_1()
{
longstart,end;
system("cls");
structTSMartrixM,N,Q;
do
{
Hand_CreateSMartrix(M);
Hand_CreateSMartrix(N);
if(M.mu!
=N.mu||M.mu!
=M.nu||N.mu!
=N.nu)
printf("两个矩阵不同维,无法用分治法!
!
!
\n");
}while(M.mu!
=N.mu||M.mu!
=M.nu||N.mu!
=N.nu);
Q.mu=M.mu;
Q.nu=M.mu;
start=clock();
DAC_MultSMatrix(M,N,Q);
end=clock();
printf("矩阵M:
\n");
OutputSMartrix(M);
printf("矩阵N:
\n");
OutputSMartrix(N);
printf("矩阵M*N:
\n");
OutputSMartrix(Q);
printf("历时%ld毫秒\n",end-start);
}
voidrun2_2_2()
{
longstart,end;
system("cls");
struct