算法设计实验报告.docx

上传人:b****3 文档编号:5516689 上传时间:2022-12-18 格式:DOCX 页数:25 大小:467.09KB
下载 相关 举报
算法设计实验报告.docx_第1页
第1页 / 共25页
算法设计实验报告.docx_第2页
第2页 / 共25页
算法设计实验报告.docx_第3页
第3页 / 共25页
算法设计实验报告.docx_第4页
第4页 / 共25页
算法设计实验报告.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

算法设计实验报告.docx

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

算法设计实验报告.docx

算法设计实验报告

目录

二分查找算法和快速排序算法1

(二)、快速排序问题6

矩阵连乘问题和0-1背包问题8

(一)、矩阵连乘问题8

(二)、0-1背包问题14

贪心算法——最优装载问题18

贵州师范大学数学与计算机科学学院实验报告

课程名称:

算法设计与分析班级:

13计本实验日期:

2015.11.3

学号:

130702010047姓名:

二指导教师:

熊祥光成绩:

一、实验名称

二分查找算法和快速排序算法

二、实验目的及要求

1、掌握分治法的基本思想;

2、利用分治法思想,编程实现二分查找算法和快速排序算法;

3、能对所设计算法的计算复杂性进行分析;

4、对于给定的实例,能给出相应算法的计算过程。

三、实验工具

XP系统或Win7系统,编程语言不限

四、实验内容

(一)、二分查找问题

1、编程语言不限,实现二分查找算法并对算法的复杂性进行分析。

源程序:

#include

#defineN5

intBinarysearch(inta[],intk,intn);

main()

{

inta[N];

printf("请输入数组元素:

");

for(inti=0;i

{

scanf("%d",&a[i]);

}

intn;

printf("请输入数组长度:

");

scanf("%d",&n);

intx;

printf("请输入要查询的数:

");

scanf("%d",&x);

n=Binarysearch(a,x,n);

if(n<0)

printf("无法找到该数!

\n");

else

printf("所查找的值:

%d的位置是:

%d\n",x,n);

return0;

}

intBinarysearch(inta[],intx,intn)

{

intleft=0;intright=n-1;

while(left<=right)

{

intmiddle=(left+right)/2;

if(x==a[middle])

returnmiddle;

if(x>a[middle])

left=middle+1;

else

right=middle-1;

}

return-1;

}

二分查找算法复杂性分析:

每执行一次算法的while循环,待搜索数组的大小就减小一半,所以在最坏情况下,while循环被执行了O(logn)次。

循环体内需要O

(1)时间。

所以最坏情况下时间复杂度为O(logn)。

2、在二分查找算法的基础上,实现三分查找算法并对算法的复杂性进行分析。

源程序如下:

#include

#defineN6

intsearch(intb[N],intx)

{

intlow=0;

inthigh=N-1;

while(low<=high)

{

intm1=(high-low)/3+low;

intm2=high-(high-low)/3;

if(x==b[m1])

returnm1;

elseif(x

high=m1-1;

elseif(x==b[m2])

returnm2;

elseif(x>b[m2])

high=m2-1;

else

{

low=m1+1;

high=m2-1;

}

}

return-1;

}

intmain()

{

ints[N];inty;

printf("请输入序列:

\n");

for(inti=0;i

{

scanf("%d",&s[i]);

}

printf("要查找的数为:

\n");

scanf("%d",&y);

inta;

a=search(s,y);

if(a>-1)

{

printf("位置为:

%d\n",a);

}

else

{

printf("没有找到该数\n");

}

return0;

}

三分搜索技术时间复杂性分析:

T(n)=O

(1),当n=1时,T(n)=T(

)+O

(1),当n>1时。

总的来说T(n)=O(

3、给定有序序列A={1,2,3,4,5,6},给出分别用二分和三分查找算法查找元素a=4和a=0的过程。

1、二分查找

(1)a=4设置两个变量i,j,排序开始的时候i=0,j=n-1=5;

i=0;j=5;

(1)假设指针low和high分别为待查元素4所在范围的上界和下界,指针mid=(low+high)/2=3;

(2)先将ST.elem[mid].key与给定值key比较,3<4,说明待查元素若存在,必在区间[mid+1,high]之间,则令指针low指向mid+1个元素,重新求得mid=(4+6)/2=5

(3)仍将ST.elem[mid].key与给定值key比较,5>4,说明待查元素若存在,必在区间[mid-1,low]之间,则令指针high指向mid-1个元素,重新求得mid=(4+4)/2=4;比较ST.elem[mid].key与给定值key,相等,查找成功,所查元素在序列中第三个位置。

2.a=0

i=0;j=5;

(1)假设指针low和high分别为待查元素0所在范围的上界和下界,指针mid=(low+high)/2=3;

(2)先将ST.elem[mid].key与给定值key比较,3>0,说明待查元素若存在,必在区间[mid-1,low]

之间,则令指针high指向mid-1个元素,重新求得mid=(1+2)/2=1

(3仍将ST.elem[mid].key与给定值key比较,1>0,说明待查元素若存在,必在区间[mid-1,low]之间,则令指针high指向mid-1个元素,上界和下界都指向同第一个元素仍没有找到,此时可以得出不存在该元素。

2、三分查找分析过程

A={1,2,3,4,5,6}

查找4left=0m1=1m2=4right=5

A[m1]<4

4=A[m2]已找到位置为m2=3;

查找0left=0m1=1m2=4right=5

0

均不满足判断,所以0不存在

(二)、快速排序问题

1、编程语言不限,实现快速排序算法并对算法的复杂性进行分析。

#include

#defineN6

voidquicksort(inta[],intlow,inthigh)

{

inti,j,temp;

i=low;

j=high;

temp=a[low];

if(low>high)

return;

while(i!

=j)

{

while(a[j]>=temp&&j>i)

j--;

if(j>i)

a[i++]=a[j];

while(a[i]<=temp&&j>i)

i++;

if(j>i)

a[j--]=a[i];

}

a[i]=temp;

quicksort(a,low,i-1);

quicksort(a,i+1,high);

}

voidmain()

{

inta[N];

printf("请输入数组:

");

for(intk=0;k<6;k++)

{

scanf("%d",&a[k]);

}

quicksort(a,0,6);

inti;

for(i=0;i<6;i++)

printf("%4d",a[i]);

}

时间复杂性分析:

最坏情况下T(n)=O(

2、若有序列A={5,2,6,4,1,3},根据快速排序算法的思想,给出升序排序的过程。

排序过程如下:

(1)设置两个变量i,j,排序开始的时候i=0,j=n-1=5;

(2)以第一个数组元素5作为关键数据,赋值给key,即key=A[0]=5;

(3)从j开始向前搜索,由后开始向前搜索j--;找到第一个小于key的A[j],将A[j]和A[i]互换,即是3和5互换;

(4)从i开始向后搜索,由前向后i++,找到第一个大于key的A[i],将A[i]和A[j]互换;

(5)重复(3)、(4)直到i=j;

开始序列为526413i=0;j=n-1=5;关键字为5;

(1)5>3,将5和3的位置互换;序列变为326415

(2)2<5,所以不用交换位置,序列为326415

(3)6>5,所以将5和6互换位置,序列变为325416

(4)5>1,所以互换位置,序列变为321456

(5)4<5,所以不用互换位置,序列仍是321456

(6)再以3为关键字,分别与4,5,6比较,均不用互换位置

(7)3>1,互换位置后序列变为123456

(8)然后2<3也不必换位置,i=j比较结束,序列为123456

五、实验心得

贵州师范大学数学与计算机科学学院实验报告

课程名称:

算法设计与分析班级13计本实验日期:

2015/11/13

学号:

130702010047姓名:

二指导教师:

熊祥光成绩:

一、实验名称

矩阵连乘问题和0-1背包问题

二、实验目的及要求

1、掌握动态规划的基本思想;

2、采用动态规划思想,编程实现矩阵连乘算法和0-1背包算法;

3、能分析所设计算法的计算复杂性;

4、对于给定的实例,能给出相应算法的计算过程。

三、实验工具

XP系统或Win7系统,编程语言不限

四、实验内容

(一)、矩阵连乘问题

1、编程语言不限,实现矩阵连乘问题的动态规划算法并对算法的复杂性进行分析。

源程序:

#include

#defineN30

voidmatrixChain(intp[],intm[N+1][N+1],intb[N+1][N+1])//函数定义;

{

intn=N;

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

m[i][i]=0;

intr;

for(r=2;r<=n;r++)

{

inti;

for(i=1;i<=n-r+1;i++)

{

intj=i+r-1;

m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];

b[i][j]=i;

intk;

for(k=i+1;k

{

intd=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];

if(d

{

m[i][j]=d;

b[i][j]=k;

}

}

}

}

}

voidtraceback(inti,intj,intb[][N+1])

{

if(i==j)

{

printf("A%d",i);

}

else

{

printf("(");

traceback(i,b[i][j],b);

traceback(b[i][j]+1,j,b);

printf(")");

}

}

main()

{

intn;

inta[2*N];

intc[N+1],flag=1;

intm[N+1][N+1];

intb[N+1][N+1];

printf("请输入矩阵的个数:

");

scanf("%d",&n);

for(inti=0;i<=2*n-1;i++)

{

if(i%2==0)

{

printf("请输入A%d的行:

",(i/2)+1);

}

else

{

printf("列:

");

}

scanf("%d",&a[i]);

}

for(i=1;i<=2*n-2;i++)

{

if(i%2!

=0&&a[i]!

=a[i+1])

{

flag=0;

break;

}

}

intj;

for(j=1;j<=n-1;j++)

{

c[j]=a[2*j];

}

if(flag!

=0)

{

c[0]=a[0];

c[n]=a[2*n-1];

matrixChain(c,m,b);

printf("最优解的结构为:

\n");

traceback(1,n,b);

printf("\n");

printf("最小数乘次数为%d\n",m[1][n]);

}

else

{

printf("这%d个矩阵不能连乘!

\n",n);

}

return0;

}

两个矩阵能够相乘的条件是第一个矩阵的列要等于第二个矩阵的行,如下图所输入的矩阵的值就不能相乘。

算法复杂度分析:

算法matrixChain的主要计算量取决于算法中对r,i和k的3重循环。

循环体的计算量为O

(1),而3重循环的总次数为O(n3)。

因此算法的计算时间上界为O(n3)。

算法所占用的空间显然为O(n2)。

 

2、若A1的大小为30×20,A2的大小为20×5,A3的大小为5×15,A4的大小为15×20,A5的大小为20×20,A1的大小为20×35,根据矩阵连乘问题的动态规划的算法思想,给出最优计算次序的过程。

计算最优次序过程为:

A1

A2

A3

A4

A5

A6

30×20

20×5

5×15

15×20

20×20

20×35

根据公式:

m[1][2]=A1A2=30×20×5=3000

m[2][3]=A2A3=20×5×15=1500

m[3][4]=A3A4=5×15×20=1500,

m[4][5]=A4A5=15×20×20=6000

m[5][6]=A5A6=20×20×35=14000

m[1][3]=A1A2A3=min

=min{5250,10500}=5250

m[2][4]=A2A3A4=min

=min{7500,3500}=3500

m[3][5]=A3A4A5=min

=min{7500,3500}=3500

m[4][6]=A4A5A6=min

=min{16500,24500}=16500

=7500

=5500

=7000

=9500

=10500

=15250

最优解为:

(A1A2)(((A3A4)A5)A6)

 

(二)、0-1背包问题

1、编程语言不限,实现0-1背包问题的动态规划算法并对算法的复杂性进行分析。

源程序:

#include

intV[15][15];

intmax(intm,intg)//求最大值

{

if(m>=g)

returnm;//m表示物品的重量

elsereturng;//g表示背包的容量

}

intKnapSack(intn,intw[],intv[],intx[],intC)

{

inti,j;

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

V[i][0]=0;//表示有物品i,但是背包容量为0

for(j=0;j<=C;j++)

V[0][j]=0;//表示背包有容量,但是没有物品

for(i=0;i<=n-1;i++)

for(j=0;j<=C;j++)

if(j

V[i][j]=V[i-1][j];

else

V[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+v[i]);

j=C;

for(i=n-1;i>=0;i--)

{

if(V[i][j]>V[i-1][j])

{

x[i]=1;//将物品i装入背包的情况

j=j-w[i];

}

else

x[i]=0;//物品i没有被装入背包

}

printf("选中的物品是:

\n");

for(i=0;i

printf("%d",x[i]);

printf("\n");

returnV[n-1][C];

}

main()

{

ints;

intw[15];

intv[15];

intx[15];

intn,i;

intC;

n=5;

printf("请输入背包的最大容量:

\n");

scanf("%d",&C);

printf("输入物品数:

\n");

scanf("%d",&n);

printf("请分别输入物品的重量:

\n");

for(i=0;i

scanf("%d",&w[i]);

printf("请分别输入物品的价值:

\n");

for(i=0;i

scanf("%d",&v[i]);

s=KnapSack(n,w,v,x,C);//函数调用

printf("最大物品价值为:

\n");

printf("%d\n",s);

}

算法复杂度分析:

从m(i,j)的递归式容易看出,算法Knapsack需要O(nc)计算时间;Traceback需O(n)计算时间;算法总体需要O(nc)计算时间。

当背包容量c很大时,算法需要的计算时间较多

2、若n=5,c=5,w={2,1,2,2,3},v={2,3,1,3,4},根据0-1背包问题的动态规划算法思想,给出构造最优解的过程。

(1)枚举法:

有5种物品,背包容量c=5

{x1,x2,x3,x4,x5}={0,0,0,0,0},{0,0,0,0,1},{0,0,0,1,0},{0,0,0,1,1},{0,0,1,0,0},{0,0,1,0,1},{0,0,1,1,0},{0,1,0,0,0},{0,1,0,0,1},{0,1,0,1,0},{0,1,0,0,0},{0,1,1,0,0},{0,1,0,0,0},{0,1,1,1,0},{1,1,0,1,0}

{x1,x2,x3,x4,x5}={1,1,0,1,0}

v1*x1+v2*x2+v3*x3+v4*x4+v5*x5=8

(2)构造最优解

 

5

4

3

2

1

 

m[1][5]>m[2][5]物品1被选x[1]=1c=5-w[1]=3

m[2][3]>m[3][3]物品2被选x[2]=1c=3-w[2]=2

m[3][2]=m[4][2]物品3未被选x[3]=0

m[4][2]>m[5][2]物品4被选x[4]=1c=2-w[2]=0

m[5][2]=0物品5未被选x[5]=0

X1

X2

X3

x4

X5

1

1

0

1

0

贵州师范大学数学与计算机科学学院实验报告

课程名称:

算法设计与分析班级:

13计本实验日期:

2015/12/5

学号:

130702010047姓名陈美指导教师:

熊祥光成绩:

一、实验名称

贪心算法——最优装载问题

二、实验目的及要求

1、掌握贪心算法的基本思想;

2、利用贪心算法思想,编程实现最优装载问题;

3、能对所设计算法的计算复杂性进行分析;

4、对于给定的实例,能给出相应算法的计算过程。

三、实验工具

XP系统或Win7系统,编程语言不限

四、实验内容

1、编程语言不限,实现教材P95页的货船最优装载算法并对该算法的复杂性进行分析。

程序源代码如下:

#include

voidSort(int*w,int*t,intn)

{

inti,j,count=0;

int*s=newint[n+1];

for(i=1;i<=n;i++)

s[i]=w[i];

for(i=1;i<=n;i++)

t[i]=0;

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

{

count=0;

for(j=0;j<=n;j++)

if(i!

=j)

if(s[i]>s[j])

count++;

while(t[count]!

=0)

count++;

t[count]=i;

}

}

voidloading(intw[],intx[],intc,intn)

{

int*t=newint[n+1];

Sort(w,t,n);//排序

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

{

x[i]=0;

}

for(intj=1;j<=n&&w[t[j]]<=c;j++)

{

x[t[j]]=1;

c=c-w[t[j]];

}

}

intmain()

{

intX[20],W[20],n,c;

printf("请输入船只载重:

");

scanf("%d",&c);

printf("请输入集装箱数量:

");

scanf("%d",&n);

printf("输入物品的重量序列:

");

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

{

scanf("%d",&W[i]);

}

loading(W,X,c,n);

printf("最优装载为");

for(intj=1;j<=n;j++)

{

printf("%d",X[j]);

}

printf("\n");

return0;

}

实验截图如下:

时间复杂度分析:

算法的主要计算量在于将集装箱依其重量从小到大排序,程序中有两个嵌套for循环,所以复杂性为:

O(n*n)。

2、假设某公司现有8个集装箱急需搬上一艘大货船,它们的重量分别是[W0,W2,…,W7]=[100,200,50,90,150,50,20,80],船只载重C=400。

求该条件下的最优装载问题。

(要求给出具体的过程)

解答过程如下:

从剩下的集装箱中,选择重量最小的集装箱。

这种选择次序可以保证所选的集装箱总重量最小,从而可以装载更多的集装箱。

根据这种贪心策略,首先选择最轻的集装箱,然后选择次轻的,如此下去直到所有集装箱均装上船或船上不能容纳其他集箱。

n=8,[W1,W2,…,W8]=[100,200,50,90,150,50,20,80],c=400。

利用贪心算法时,所考察集装箱的顺序为7,3,6,8,4,1,5,2。

集装箱7,3,6,8,4,1的总重量为390个单位且已被装载,剩下的装载能力为10个单

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

当前位置:首页 > 经管营销

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

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