算法设计与分析软件.docx
《算法设计与分析软件.docx》由会员分享,可在线阅读,更多相关《算法设计与分析软件.docx(41页珍藏版)》请在冰豆网上搜索。
算法设计与分析软件
《算法设计与分析》
实验报告
项目名称分治算法实验
专业班级软件工程1503
学号3903150333
姓名曾永豪
实验成绩:
批阅教师:
年月日
实验1《分治算法实验》
一、实验目的
1.了解分治策略算法思想
2.掌握快速排序、归并排序算法
3.了解其他分治问题典型算法
二、实验内容
1.编写一个简单的程序,实现归并排序。
2.编写一段程序,实现快速排序。
3.编写程序实现循环赛日程表。
设有n=2k个运动员要进行网球循环赛。
现要设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其它n-1个选手各赛一次
(2)每个选手一天只能赛一场(3)循环赛进行n-1天
三、算法思想分析
大问题分解为子问题,这些子问题相互独立且与原问题相同。
分别求解子问题,合并解,自底向上逐步求出原来问题的解。
四、实验过程分析
写在代码注释中
五、算法源代码及用户屏幕
1、归并排序:
#include
usingnamespacestd;
#defineN7//待排序数据个数
voidmerge(intarray[],intp,intq,intr);
voidmerge_sort(intdata[],intp,intr);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
voidmain()
{intdata[]={44,12,145,-123,-1,0,121};
cout<<"--------------------array---------------------"<for(inti=0;icout<cout<<"\n-------------------mergesort--------------------\n";
merge_sort(data,0,N-1);
for(i=0;icout<cout<}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
voidmerge(intarray[],intp,intq,intr)
{inti,k;
intbegin1,end1,begin2,end2;
int*temp=newint[r-p+1];//申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
begin1=p;end1=q;//设定两个指针,最初位置分别为两个已经排序序列的起始位置
begin2=q+1;end2=r;
k=0;
while((begin1<=end1)&&(begin2<=end2))//比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
{if(array[begin1]{temp[k]=array[begin1];begin1++;
}
else
{temp[k]=array[begin2];begin2++;
}
k++;
}
while(begin1<=end1)//若第一个序列有剩余,直接拷贝出来粘到合并序列尾
{temp[k++]=array[begin1++];
}
while(begin2<=end2)//若第二个序列有剩余,直接拷贝出来粘到合并序列尾
{temp[k++]=array[begin2++];
}
for(i=0;i<(r-p+1);i++)//将排序好的序列拷贝回数组中
array[p+i]=temp[i];
delete[](temp);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
voidmerge_sort(intdata[],intleft,intright)
{if(left{intmid=(left+right)/2;
merge_sort(data,left,mid);
cout<<"0-left,mid:
"<merge_sort(data,mid+1,right);
cout<<"1-left,mid:
"<merge(data,left,mid,right);
inti;
for(i=left;i<=right;i++)//观察语句,用来理解递归
cout<cout<}
}
2、快速排序:
#include
#include
#include
usingnamespacestd;
#defineMAX10
#defineSWAP(x,y){intt;t=x;x=y;y=t;}
intpartition(int[],int,int);
voidquicksort(int[],int,int);
voidmain()
{intnumber[MAX]={0};
inti;
srand(time(NULL));
cout<<"排序前:
";
for(i=0;i{number[i]=rand()%100;
cout<}
quicksort(number,0,MAX-1);
cout<<"\n排序后:
";
for(i=0;icout<cout<<"\n";
}
intpartition(intnumber[],intleft,intright)
{inti,j,s;
s=number[right];
i=left-1;
for(j=left;j{if(number[j]<=s)
{i++;
SWAP(number[i],number[j]);
}
}
SWAP(number[i+1],number[right]);
returni+1;
}
voidquicksort(intnumber[],intleft,intright)
{intq;
if(left{q=partition(number,left,right);
quicksort(number,left,q-1);
quicksort(number,q+1,right);
}
}
3、循环赛日程表:
#include
#include
usingnamespacestd;
#defineMAXN64
#defineMAX32
inta[MAX][MAX];//日程表数组
voidCopy(inttox,inttoy,intfromx,intfromy,intn)
{inti,j;
for(i=0;ifor(j=0;ja[tox+i][toy+j]=a[fromx+i][fromy+j];
}
voidTable(intk,inta[][MAX])
{inti,n=1<for(i=0;ia[0][i]=i+1;
for(r=1;r{for(i=0;i{Copy(r,i+r,0,i,r);
Copy(r,i,0,i+r,r);
}
}
}
voidOut(inta[][MAX],intn)
{inti,j;
for(i=0;i{for(j=0;jcout<cout<<"\n";
}
printf("\n");
}
voidmain()
{inti;
for(i=0;i<5;i++)
{intlen=1<
Table(i,a);Out(a,len);
}
}
六、实验小结
这次实验使得我们能把算法联系到实际并实现具体功能,使得我们对分治算法有更深地了解,深刻理解了分治算法“分而治之”的思想,锻炼了我们动手操作的能力。
《算法设计与分析》
实验报告
项目名称贪心算法实验
专业班级软件工程1503
学号3903150333
姓名曾永豪
实验成绩:
批阅教师:
年月日
实验2《贪心算法实验》
一、实验目的
1.了解贪心算法思想
2.掌握贪心法典型问题,如背包问题、作业调度问题等。
二、实验内容
1.编写一个简单的程序,实现单源最短路径问题。
2.编写一段程序,实现找零。
【问题描述】当前有面值分别为2角5分,1角,5分,1分的硬币,请给出找n分钱的最佳方案(要求找出的硬币数目最少)。
3.编写程序实现多机调度问题
【问题描述】要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。
约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。
作业不能拆分成更小的子作业。
三、算法思想分析
Dijkstra算法等。
四、实验过程分析
写在代码注释中
五、算法源代码及用户屏幕
1、单源最短路径问题:
#include
usingnamespacestd;
////////////////////////////////////////////////////////////
//Graph.h
#definemaxPoint100
classCGraph
{
public:
CGraph(void);
~CGraph(void);
boolSetGraph(doubleg[maxPoint][maxPoint],intstartPoint,intsize);
boolDijkstra();
voidDisplay();
intGetStartPoint();
doubleGetBestWay(intdest,intpath[],int&pathLen);
private:
boolsolved;//标志当前图是否已经求解
doublegraph[maxPoint][maxPoint];//当前图布局
intsize;//地图大小
intstartPoint;//起点
doubledist[maxPoint];//当前图的解
intprev[maxPoint];
};
////////////////////////////////////////////////////////////
//Graph.cpp
CGraph:
:
CGraph(void)
{
for(inti=0;i{
for(intj=0;jgraph[i][j]=-1;
}
startPoint=-1;
size=-1;
solved=false;//当前图还没有求解
}
CGraph:
:
~CGraph(void)
{
}
//
boolCGraph:
:
SetGraph(doubleg[maxPoint][maxPoint],intstartPoint,intsize)
{
for(inti=0;i{
for(intj=0;jgraph[i][j]=g[i][j];
}
this->startPoint=startPoint;
this->size=size;
solved=false;
Dijkstra();
returntrue;
}
//
boolCGraph:
:
Dijkstra()
{
bools[maxPoint];
for(intj=0;j{
dist[j]=graph[startPoint][j];
s[j]=false;
if(dist[j]<0)//dist[i]<0,表示没有路径连接结点startPoint与结点j
prev[j]=0;
else
prev[j]=startPoint;
}
//从起点出发
dist[startPoint]=0;
s[startPoint]=true;
for(inti=0;i{
doubletemp;
intu=startPoint;
boolflag=false;
for(intj=0;j{
if(!
s[j])
{
//如果不是第一次比较,temp、u,都已经赋值,则
if(flag)
{
if(dist[j]>0&&dist[j]{
u=j;
temp=dist[j];
}
}
else
{
u=j;
temp=dist[j];
flag=true;
}
}
}
s[u]=true;
for(j=0;j{
if(!
s[j]&&graph[u][j]>0)
{
doublenewDist=dist[u]+graph[u][j];
if(dist[j]<0||newDist{
dist[j]=newDist;
prev[j]=u;
}
}
}
}
solved=true;
returntrue;
}
//
voidCGraph:
:
Display()
{
printf("当前地图的邻接矩阵\n");
for(inti=0;i{
for(intj=0;j{
printf("%5.f",graph[i][j]);
}
printf("\n");
}
}
//
doubleCGraph:
:
GetBestWay(intdest,intpath[],int&pathLen)
{
intp=dest;
inttheway[maxPoint];
intlen=0;
while(p!
=startPoint)
{
theway[len]=p;
p=prev[p];
len++;
}
theway[len]=startPoint;
len++;
for(inti=0,j=len-1;ipath[i]=theway[j];
pathLen=len;
returndist[dest];
}
//
//
intCGraph:
:
GetStartPoint()
{
returnstartPoint;
}
//
////////////////////////////////////////////////////////////
//Dijkstra.cpp:
定义控制台应用程序的入口点。
voidmain()
{
doublegraph[][maxPoint]=
{
{0,10,-1,30,100},
{-1,0,50,-1,-1},
{-1,-1,0,-1,10},
{-1,-1,20,0,60},
{-1,-1,-1,-1,0}
};
intsize=5;
intstart=0;
intdest=1;
intpathlen;
intpath[maxPoint];
doubledist;
CGraphg;
g.SetGraph(graph,start,size);
g.Display();
printf("----------------------------------------\n");
for(dest=0;dest{
dist=g.GetBestWay(dest,path,pathlen);
printf("从%d到%d的最短路径长%.f\n",g.GetStartPoint(),dest,dist);
printf("所经结点为:
\n");
for(inti=0;iprintf("%3d",path[i]);
printf("\n----------------------------------------\n");
}
}
2、找零问题:
#include
usingnamespacestd;
#defineNUM4
voidmain()
{intm[NUM]={25,10,5,1};
intn;//假设n=99
cin>>n;
cout<";
for(inti=0;iwhile(n>=m[i]&&n>0)
{cout<n-=m[i];
}
}
3、多机调度问题:
#include
usingnamespacestd;
#defineN10//作业数
#defineM3//机器数
voidsort(intt[],intn);
intset_work1(intt[],intn);
intmax(intt[],intnum);
intmin(intt[],intm);
intset_work2(intt[],intn);
//S数组存储每台机器当前已分配任务总耗时
staticinttime[N]={2,8,18,32,50,72,98,128,182,200},s[M]={0,0,0};
voidmain()
{sort(time,N);
if(M>=N)//作业数小于机器数
cout<else
cout<}
voidsort(intt[],intn)
{for(intk=0;k{intj=k;
for(inti=k;iif(t[i]>t[j])j=i;
{inttemp=t[j];t[j]=t[k];t[k]=temp;}
}
}
intmax(intt[],intnum)//max函数求解处理时间总和最长
{intmax=t[0];
for(inti=1;iif(maxreturnmax;
}
intmin(intt[],intm)
{intmin=0;//min记录目前处理作业时间和最小的机器号
for(inti=1;iif(s[min]>s[i])min=i;
returnmin;
}
intset_work1(intt[],intn)
{intm=0;
for(inti=0;is[m++]+=t[i];
returnmax(s,N);
}
intset_work2(intt[],intn)
{for(inti=0;is[min(s,M)]+=t[i];
returnmax(s,M);
}
《算法设计与分析》
实验报告
项目名称动态规划算法实验
专业班级软件工程1503
学号3903150333
姓名曾永豪
实验成绩:
批阅教师:
年月日
实验3《动态规划算法实验》
一、实验目的
1.掌握动态规划方法贪心算法思想
2.掌握最优子结构原理
3.了解动态规划一般问题
二、实验内容
1.编写一个简单的程序,解决0-1背包问题。
设N=5,C=10,w={2,2,6,5,4},v={6,3,5,4,6}
2.合唱队形安排问题
【问题描述】N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱