算法设计与分析实验报告中南民族大学Word格式文档下载.docx
- 文档编号:16735893
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:30
- 大小:567.92KB
算法设计与分析实验报告中南民族大学Word格式文档下载.docx
《算法设计与分析实验报告中南民族大学Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《算法设计与分析实验报告中南民族大学Word格式文档下载.docx(30页珍藏版)》请在冰豆网上搜索。
法
基
本
思
想
)
一.迭代算法求最大Fibonacci在数列中位置
1.先利用迭代求得计算机能表示的最大数MaxUnsignedInt.
unsignedlongintMaxUnsignedInt=1;
while(MaxUnsignedInt*2+1!
=MaxUnsignedInt)
{
MaxUnsignedInt=MaxUnsignedInt*2+1;
}
2.从1起进行(n-1)+(n-2)=n迭代,直到条件(temp3>
temp)时发生溢出(及超过最大数),退出循环。
求得此时的迭代次数-1即为最大Fibonacci的位置。
unsignedlongintn=MaxUnsignedInt;
for(i=1;
temp<
=n;
i++)//temp<
=n
temp=temp1+temp2;
if(temp3>
temp)//当temp3>
temp时,则发现temp发生溢出,结束计算
break;
temp3=temp;
temp2=temp1;
temp1=temp;
二.递归算法
1.根据
/0n=0
f(n)=1n=1
\f(n-1)+f(n-2)n=2
进行递归调用求解。
longFF(unsignedinttt)//usedigui
if(tt<
=1)
returntt;
else
returnFF(tt-1)+FF(tt-2);
三.改进空间复杂度为Θ
(1)。
利用公式:
F(n)=(1/√5)*{[(1+√5)/2]^n-[(1-√5)/2]^n}
intfib(intn)
{
doublegh5=sqrt((double)5);
return(pow((1+gh5),n)-pow((1-gh5),n))/(pow((double)2,n)*gh5);
}
程
序
代
码
voidfibo()
unsignedlongintMaxUnsignedInt,n,times,t=100;
clock_tstart=clock();
MaxUnsignedInt=1;
while(MaxUnsignedInt*2+1!
{
MaxUnsignedInt=MaxUnsignedInt*2+1;
}
cout<
<
"
时间消耗:
clock()-start<
endl;
n=MaxUnsignedInt;
intchoose;
boolend_this=true;
while(end_this)
cout<
************************************************************\n"
;
1.输入一个你想要判断的数\n"
2.判断从0到N的Fibonacci\n"
3.计算机能判断的最大数\n"
4.用递归计算你想要判断的数\n"
5.结束\n"
again:
youwantdo:
cin>
>
choose;
if(choose!
=1&
&
choose!
=2&
=3&
=4)//输入菜单检查
{
cout<
输入错误\n"
gotoagain;
}
switch(choose)
case1:
{
cout<
inputyournumber:
cin>
t;
start=clock();
times=F(t);
t<
是第"
times<
个Fibonacci数"
break;
}
case2:
start=clock();
F(t);
cout<
break;
case3:
最大数是"
n<
//times=F(n);
unsignedlonginttemp=1,temp1=0,temp2=1,temp3=temp;
inti;
for(i=1;
{
temp=temp1+temp2;
if(temp3>
break;
temp3=temp;
temp2=temp1;
temp1=temp;
}
i-1<
case4:
intx;
Youwantdo:
cin>
x;
times=FF(x);
第"
x<
个Fibonacci数是"
case5:
end_this=false;
intF(unsignedintuu)
unsignedlonginttemp=0,temp1=0,temp2=1;
inti;
//if(uu==0||uu==1)
//returnuu;
for(i=1;
i<
=uu;
i++)
temp=temp1+temp2;
number"
i<
is"
temp<
if(temp>
=uu)
returni;
temp2=temp1;
temp1=temp;
return0;
结
果
及
分
析
1.求最大数
2.递归法与迭代法性能比较
递归迭代
3.改进算法
1.利用公式法对第n项Fibonacci数求解时可能会得出错误结果。
主要原因是由于double类型的精度还不够,所以程序算出来的结果会有误差,要把公式展开计算。
2.由于递归调用栈是一个费时的过程,通过递归法和迭代法的比较表明,虽然递归算法的代码更精简更有可读性,但是执行速度无法满足大数问题的求解。
3.在当前计算机的空间较大的情况下,在一些速度较慢的问题中,空间换时间是一个比较周全的策略。
分治法在数值问题中的应用
——矩阵相乘问题
一.实验题目
设M1和M2是两个n×
n的矩阵,设计算法计算M1×
M2的乘积。
二.实验目的
1)提高应用蛮力法设计算法的技能;
2)深刻理解并掌握分治法的设计思想;
用蛮力法设计的算法,一般来说,经过适度的努力后,都可以对其进行改进,以提高算法的效率。
三.实验要求
1)设计并实现用BF方法求解矩阵相乘问题的算法;
2)设计并实现用DAC方法求解矩阵相乘问题的算法;
3)以上两种算法的输入既可以手动输入,也可以自动生成;
4)对上述两个算法进行时间复杂性分析,并设计实验程序验证
分析结果;
定义:
若A=(aij),B=(bij)是n×
n的方阵,则对i,j=1,2,…n,定义乘积C=A⋅B中的元素cij为:
1.分块解法
通常的做法是将矩阵进行分块相乘,如下图所示:
二.Strassen解法
分治法思想
将问题实例划分为同一问题的几个较小的实例。
对这些较小实例求解,通常使用递归方法,但在问题规模足够小时,也会使用另一种算法。
如果有必要,合并这些问题的解,以得到原始问题的解。
求解矩阵相乘的DAC算法,使用了strassen算法。
DAC(A[],B[],n)
Ifn=2使用7次乘法的方法求得解
Else
Divide(A)//把A分成4块
Divide(B)//把B分成4块
调用7次strassen算法求得解的4块
合并这4块得到解并返回
伪代码
Serial_StrassenMultiply(A,B,C)
T1=A0+A3;
T2=B0+B3;
StrassenMultiply(T1,T2,M1);
T1=A2+A3;
StrassenMultiply(T1,B0,M2);
T1=(B1-B3);
StrassenMultiply(A0,T1,M3);
T1=B2-B0;
StrassenMultiply(A3,T1,M4);
T1=A0+A1;
StrassenMultiply(T1,B3,M5);
T1=A2–A0;
T2=B0+B1;
StrassenMultiply(T1,T2,M6);
T1=A1–A3;
T2=B2+B3;
StrassenMultiply(T1,T2,M7);
C0=M1+M4-M5+M7
C1=M3+M5
C2=M2+M4
C3=M1-M2+M3+M6
//矩阵相乘问题
voidPrintIn(ArrayA,ArrayB)
intn=A.n;
inti,j;
printf("
请输入A数据:
\n"
);
for(i=0;
n;
i++)
for(j=0;
j<
j++)
cin>
A.a[i*n+j];
请输入B数据:
cin>
B.a[i*n+j];
voidRandomIn(ArrayA,ArrayB)
srand((unsigned)time(NULL));
for(j=0;
A.a[i*n+j]=rand()%10;
j++)
B.a[i*n+j]=rand()%10;
voidPrintOut(ArrayA)
{for(j=0;
A.a[i*n+j]<
'
'
printf("
voiddivide(Arrayd,Arrayd00,Arrayd01,Arrayd10,Arrayd11)/*分割矩阵*/
intn=d00.n;
d00.a[n*i+j]=d.a[2*n*i+j];
d01.a[n*i+j]=d.a[2*n*i+n+j];
d10.a[n*i+j]=d.a[2*n*n+2*n*i+j];
d11.a[n*i+j]=d.a[2*n*n+2*n*i+n+j];
Arraymerge(Arrayd00,Arrayd01,Arrayd10,Arrayd11)
Arrayd;
d.a=(int*)malloc(sizeof(int)*(4*n*n));
d.a[2*n*i+j]=d00.a[n*i+j];
d.a[2*n*i+n+j]=d01.a[n*i+j];
d.a[2*n*n+2*n*i+j]=d10.a[n*i+j];
d.a[2*n*n+2*n*i+n+j]=d11.a[n*i+j];
d.n=2*n;
returnd;
Arrayoperator+(ArrayA,ArrayB)
ArrayC;
C.a=(int*)malloc(sizeof(int)*(n*n));
for(inti=0;
n*n;
C.a[i]=A.a[i]+B.a[i];
C.n=A.n;
returnC;
Arrayoperator-(ArrayA,ArrayB)
C.a[i]=A.a[i]-B.a[i];
Arraystrassen(ArrayA,ArrayB)
C.n=n;
if(n==2)
intm1,m2,m3,m4,m5,m6,m7;
m1=(A.a[0]+A.a[3])*(B.a[0]+B.a[3]);
m2=(A.a[2]+A.a[3])*B.a[0];
m3=A.a[0]*(B.a[1]-B.a[3]);
m4=A.a[3]*(B.a[2]-B.a[0]);
m5=(A.a[0]+A.a[1])*B.a[3];
m6=(A.a[2]-A.a[0])*(B.a[0]+B.a[1]);
m7=(A.a[1]-A.a[3])*(B.a[2]+B.a[3]);
C.a[0]=m1+m4-m5+m7;
C.a[1]=m3+m5;
C.a[2]=m2+m4;
C.a[3]=m1+m3-m2+m6;
else
n=n/2;
Arraya00,a01,a10,a11;
Arrayb00,b01,b10,b11;
Arrayc00,c01,c10,c11;
Arrays1,s2,s3,s4,s5,s6,s7;
a00.a=(int*)malloc(sizeof(int)*(n*n));
a00.n=n;
a01.a=(int*)malloc(sizeof(int)*(n*n));
a01.n=n;
a10.a=(int*)malloc(sizeof(int)*(n*n));
a10.n=n;
a11.a=(int*)malloc(sizeof(int)*(n*n));
a11.n=n;
b00.a=(int*)malloc(sizeof(int)*(n*n));
b00.n=n;
b01.a=(int*)malloc(sizeof(int)*(n*n));
b01.n=n;
b10.a=(int*)malloc(sizeof(int)*(n*n));
b10.n=n;
b11.a=(int*)malloc(sizeof(int)*(n*n));
b11.n=n;
divide(A,a00,a01,a10,a11);
divide(B,b00,b01,b10,b11);
s1=strassen(a00+a11,b00+b11);
s2=strassen(a10+a11,b00);
s3=strassen(a00,b01-b11);
s5=strassen(a00+a01,b11);
s4=strassen(a11,b10-b00);
s6=strassen(a10-a00,b00+b01);
s7=strassen(a01-a11,b10+b11);
c00=s1+s4-s5+s7;
c01=s3+s5;
c10=s2+s4;
c11=s1+s3-s2+s6;
C=merge(c00,c01,c10,c11);
Arraymul(ArrayA,ArrayB)//普通的矩阵乘法计算
inti,j,k;
{
C.a[i*n+j]=0;
for(k=0;
k<
k++)
C.a[i*n+j]=C.a[i*n+j]+A.a[i*n+k]*B.a[k*n+j];
voidmatrix()
{intn;
charch;
ArrayA,B,C;
\t\t计算M1×
M2的乘积\n"
\t\t输入矩阵阶数n:
A.a=(int*)malloc(sizeof(int)*(n*n));
A.n=n;
B.a=(int*)malloc(sizeof(int)*(n*n));
B.n=n;
C.a=(int*)malloc(sizeof(int)*(n*n));
\t\t---1手动输入---\n"
\t\t---2随机生成---\n"
\t\t请选择\n\n"
ch=getch();
switch(ch)
case'
1'
:
手动输入\n"
PrintIn(A,B);
printf("
break;
2'
自动生成\n"
RandomIn(A,B);
default:
printf("
按键错误\n"
break;
结果数组A中数据为:
PrintOut(A);
结果数组B中数据为:
PrintOut(B);
do
doublestart,finish,duration;
\n---1用BF方法---\n"
---2用DAC方法---\n"
---3退出---\n"
\n请选择:
ch=getch();
switch(ch)
case'
start=clock();
C=mul(A,B);
finish=clock();
duration=(double)(finish-start);
\n用BF方法得出的结果\n"
PrintOut(C);
printf("
用BF方法计算矩阵所花费的时间是:
%fms\n"
duration);
start=clock();
C=strassen(A,B);
dura
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 设计 分析 实验 报告 中南 民族大学