算法设计与分析的实验报告.docx

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

算法设计与分析的实验报告.docx

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

算法设计与分析的实验报告.docx

算法设计与分析的实验报告

实验一递归与分治策略

一、实验目的

1.加深学生对分治法算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;

2.提高学生利用课堂所学知识解决实际问题的能力;

3.提高学生综合应用所学知识解决实际问题的能力。

二、实验内容

1、

①设a[0:

n-1]是已排好序的数组。

请写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。

当搜索元素在数组中时,i和j相同,均为x在数组中的位置。

②写出三分搜索法的程序。

三、实验要求

(1)用分治法求解上面两个问题;

(2)再选择自己熟悉的其它方法求解本问题;

(3)上机实现所设计的所有算法;

四、实验过程设计(算法设计过程)

1、已知a[0:

n-1]是一个已排好序的数组,可以采用折半查找(二分查找)算法。

如果搜索元素在数组中,则直接返回下表即可;否则比较搜索元素x与通过二分查找所得最终元素的大小,注意边界条件,从而计算出小于x的最大元素的位置i和大于x的最小元素位置j。

2、将n个元素分成大致相同的三部分,取在数组a的左三分之一部分中继续搜索x。

如果x>a[2(n-1)/3],则只需在数组a的右三分之一部分中继续搜索x。

上述两种情况不成立时,则在数组中间的三分之一部分中继续搜索x。

五、实验结果分析

二分搜索法:

三分搜索法:

时间复杂性:

二分搜索每次把搜索区域砍掉一半,很明显时间复杂度为O(logn)。

(n代表集合中元素的个数)

三分搜索法:

O(3log3n)

空间复杂度:

O

(1)。

 

六、实验体会

本次试验解决了二分查找和三分查找的问题,加深了对分治法的理解,收获很大,同时我也理解到学习算法是一个渐进的过程,算法可能一开始不是很好理解,但是只要多看几遍,只看是不够的还要动手分析一下,这样才能学好算法。

七、附录:

(源代码)

二分搜索法:

#include

#include

intbinarySearch(inta[],intx,intn)

{

intleft=0;intright=n-1;inti,j;

while(left<=right)

{

intmiddle=(left+right)/2;

if(x==a[middle]){i=j=middle;return1;}

if(x>a[middle])left=middle+1;

elseright=middle-1;

}

i=right;j=left;

return0;

}

intmain()

{inta[10]={0,1,2,3,4,5,6,7,8,9};

intn=10;

intx=9;

if(binarySearch(a,x,n))

cout<<"找到"<

else

cout<<"找不到"<

 

return0;

}

 

实验二动态规划——求解最优问题

一、实验目的

1.加深学生对动态规划算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;

2.提高学生利用课堂所学知识解决实际问题的能力;

3.提高学生综合应用所学知识解决实际问题的能力。

二、实验内容

1、用两台处理机A和B处理n个作业。

设第i个作业交给机器A处理时所需要的时间是a[i],若由机器B来处理,则所需要的时间是b[i]。

由于各作业的特点和机器的性能关系,很可能对于某些i,有a[i]>=b[i],而对于某些就j,j!

=i,有a[i]

既不能将一个作业分开由两台机器处理,也没有一台机器能同时处理2个作业。

设计一个动态规划算法,使得这两台机器处理完这n个作业的时间最短(从任何一台机器开工到最后一台机器停工的总的时间)。

研究一个实例:

(a[1],a[2],a[3],a[4],a[5],a[6])=(2,5,7,10,5,2);(b[1],b[2],b[3],b[4],b[5],b[6])=(3,8,4,11,3,4)。

2、长江游艇俱乐部在长江上设置了n个游艇出租站1,2……n。

游客可在游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。

游艇出租站i到游艇出租站j之间的租金r(i,j)1<=i

设计一个算法,计算出游艇1到游艇n所需最少租金。

三、实验要求

(1)用动态规划思想求解最优问题;

(2)再选择自己熟悉的程序设计语言实现所有算法;

(3)分析所设计的算法的时间/空间复杂性。

四、实验过程设计(算法设计过程)

1、对于给定的2台处理机A和B处理n个作业,找出一个最优调度方案,使2台机器处理完这n个作业的时间最短。

2、对于给定的游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i

五、实验结果分析

独立任务最优调度问题:

租用游艇问题:

时间复杂性:

独立任务最优调度问题:

O(n*Sum)

六、实验体会

对于算法来说,没有最好,只有更好,算法的结果不一定是最佳答案,但至少是最接近最佳答案的。

在权衡算法时间复杂度和空间复杂度的情况下,找到一个在时间和空间都能接受的算法才是上上之策。

七、附录:

(源代码)

独立任务最优调度问题:

usingSystem;

namespacezydd

{

classProgram

{

staticvoidDlrwZydd(int[]a,int[]b,intn,int[]least,string[]result)

{

for(inti=0;i

{

least[i]=99;

}

intaSum=0,bSum=0;

for(inti=0;i

{

aSum+=a[i];

bSum+=b[i];

}

intSum=1+Math.Min(aSum,bSum);

int[,]timeA=newint[n,Sum];

int[,]timeB=newint[n,Sum];

int[,]timeMax=newint[n,Sum];

char[,]who=newchar[n,Sum];

char[]tempRlt=newchar[n];

for(inti=0;i<=a[0];i++)

{

timeA[0,i]=i;

if(i

{

timeB[0,i]=b[0];

who[0,i]='b';

}

else

{

timeB[0,i]=0;

who[0,i]='a';

}

timeMax[0,i]=Math.Max(timeA[0,i],timeB[0,i]);

}

if(a[0]<=b[0])

{

least[0]=a[0];

tempRlt[0]='a';

}

else

{

least[0]=b[0];

tempRlt[0]='b';

}

result[0]=newString(tempRlt);

for(intk=1;k

{

inttempSum=0;

for(inttemp=0;temp<=k;temp++)

{

tempSum+=a[temp];

}

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

{timeA[k,i]=i;

if(i

{

timeB[k,i]=timeB[k-1,i]+b[k];

who[k,i]='b';

}

else

{

if((timeB[k-1,i]+b[k])<=timeB[k-1,i-a[k]])

{

timeB[k,i]=timeB[k-1,i]+b[k];

who[k,i]='b';

}

else

{

timeB[k,i]=timeB[k-1,i-a[k]];

who[k,i]='a';

}

}

timeMax[k,i]=Math.Max(timeA[k,i],timeB[k,i]);

}

for(inti=tempSum+1;i

{

timeA[k,i]=tempSum;

timeB[k,i]=0;

}

intflag=0;

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

{

if(timeMax[k,i]>0&&timeMax[k,i]

{

least[k]=timeMax[k,i];

flag=i;

}

}

tempRlt[k]=who[k,flag];

for(inti=k;i>0&&flag>0;i--)

{

if(tempRlt[i]=='a')

{

flag-=a[i];

tempRlt[i-1]=who[i-1,flag];

}

if(tempRlt[i]=='b')

{

tempRlt[i-1]=who[i-1,flag];

}

}

result[k]=newString(tempRlt);

}

}

staticvoidMain(string[]args)

{

constintN=6;

int[]a=newint[N]{2,5,7,10,5,2};

int[]b=newint[N]{3,8,4,11,3,4};

int[]least=newint[N];

string[]result=newstring[N];

DlrwZydd(a,b,N,least,result);

Console.WriteLine();

for(inti=0;i

{

Console.WriteLine("按要求完成前{0}项任务的机器顺序为:

"+result[i]+"时间为:

{1}",i+1,least[i]);

}

}

}

}

 

实验三贪心算法

一、实验目的

1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求

2.加深对贪婪法算法设计方法的理解与应用

3.掌握将算法转化为计算机上机程序的方法

4.培养学生应用所学知识解决实际问题的能力。

二、实验内容

1、设有n个顾客同时等待一项服务。

顾客i需要的服务时间为ti,1<=i<=n。

应如何安排n个顾客的服务次序才能使总的等待时间达到最小?

总的等待时间是每个顾客等待服务时间的综合。

2、一辆汽车加满油后可行驶n公里。

旅途中有若干个加油站。

设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。

并证明算法能产生一个最优解。

三、实验要求

(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;

(2)上机实现所设计的算法;

(3)分析所设计的算法的时间/空间复杂性。

四、实验过程设计(算法设计过程)

1、首先将每个顾客所需要的服务时间从小到大排序。

然后申请2个数组:

st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;

2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n

1.始点到终点的距离小于N,则加油次数k=0;

2.始点到终点的距离大于N,

①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;

②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;

③加油站间的距离相等,即a[i]=a[j]=L

=0);

④加油站间的距离不相等,即a[i]!

=a[j],则加油次数k通过下面的算法求解。

五、实验结果分析

最优服务次序问题:

时间复杂度为O(nlogn)

汽车加油问题:

时间复杂度为O(n)。

六、实验体会

 

七、附录:

(源代码)

汽车加油问题:

#include

#include

namespaceConsoleApplication1

{

classProgram

{

staticvoidMain(string[]args)

{

Console.Write("请输入汽车加满油后可行驶路程:

");

intn=Convert.ToInt32(Console.ReadLine());

Console.Write("请输入途经加油站总数:

");

intk=Convert.ToInt32(Console.ReadLine());

int[]distance=newint[k+1];//加油站间距

int[]note=newint[k];//记录加油站点

Console.WriteLine("请输入加油站间距!

");

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

{//从始点起,加油站间距

Console.Write("站点间距{0}:

",i+1);

distance[i]=Convert.ToInt32(Console.ReadLine());

}

intcount;//记录加油次数

Problemp=newProblem();

count=p.Greedy(distance,note,n);

if(count>=0)

{

if(count==0)

Console.WriteLine("汽车不用加油就可到达终点!

");

else

{

Console.WriteLine("汽车在旅途中需加{0}次油!

",count);

Console.WriteLine("分别在以下加油站加了油:

");

for(inti=0;i

{

if(note[i]!

=0)

{//输出需加油站点

Console.WriteLine("第"+note[i]+"个加油站!

");

}

}

}

}

else

Console.WriteLine("汽车无法到达终点!

");

Console.ReadKey();

}

}

classProblem

{

publicintGreedy(int[]d,int[]note,intn)

{

inti,j,s,add=0,p=0,k=d.Length;

for(i=0;i

{

if(d[i]>n)

{//不能到达目的地

return-1;

}

}

for(j=0,s=0;j

{

s+=d[j];

if(s>n)

{//需要加油

add++;

note[p++]=j;

s=d[j];

}

}

returnadd;

}

}

}

实验四回溯法

一、实验目的

1.掌握能用回溯法求解的问题应满足的条件;

2.加深对回溯法算法设计方法的理解与应用;

3.锻炼学生对程序跟踪调试能力;

4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。

二、实验内容

1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。

设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。

试设计一个算法,给出总价格不超过c的最小重量机器设计。

2、设有n件工作分配给n个人。

将工作i分配给第j个人所需的费用为c[i][j]。

试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。

三、实验要求

(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;

(2)上机实现所设计的算法;

(3)分析所设计的算法的时间/空间复杂性。

四、实验过程设计(算法设计过程)

1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。

b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。

 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。

 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。

 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行;

 ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。

c.主函数调用一次Knapsack

(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。

2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分

  配工作;

 b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深

  度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用):

 ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行;

 ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层

  继续执行;

 ③采用for循环针对n个人对工作i进行分配(1≤j≤n):

  1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配;

  2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配;

  3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对

  第j+1个人进行分配;

  4>当j>n时,for循环结束;

 ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束;

 c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为

  所求最小总费用。

五、实验结果分析

最小重量机器设计问题:

程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!

),故该算法的时间复杂度为O(n!

)。

工作分配问题:

递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!

),主函数调用递归函

数backtrack(1,0),故该算法的时间复杂度为O(n!

)。

六、实验体会

七、附录:

(源代码)

最小重量机器设计问题:

#include

#defineN1000

usingnamespacestd;

intn,m,d,cp=0,cw=0,sum=0;

intc[N][N],w[N][N];

voidbacktrack(inti){

if(i>n){

if(cw

sum=cw;

return;

}

for(intj=1;j<=m;j++){

cw+=w[i][j];

cp+=c[i][j];

if(cw

backtrack(i+1);

cw-=w[i][j];

cp-=c[i][j];

}

}

intmain(){

cin>>n>>m>>d;

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

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

cin>>c[i][j];

sum+=c[i][1];

}

for(intk=1;k<=n;k++)

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

cin>>w[k][j];

backtrack

(1);

cout<

system("pause");

return0;

}

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

当前位置:首页 > 初中教育 > 其它课程

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

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