华科算法实验报告.docx
- 文档编号:530438
- 上传时间:2022-10-10
- 格式:DOCX
- 页数:16
- 大小:167.40KB
华科算法实验报告.docx
《华科算法实验报告.docx》由会员分享,可在线阅读,更多相关《华科算法实验报告.docx(16页珍藏版)》请在冰豆网上搜索。
华科算法实验报告
华科算法实验报告
LT
一.实验一
1.实验题目
单源最短路径问题:
已知一个n结点有向图G=(V,E)和边的权函数c(e),求由G中某指定结点v0到其它各结点的最短路径。
假定边的权值为正。
2.设计思路
贪心算法流程图如图1:
图1生成最短路径算法流程
设计总方法:
使用贪心算法求解。
贪心方法:
1)度量标准
生成的所有路径长度之和作为度量标准。
为了使这一量度达到最小,其单独的每一条路径都必须具有最小长度。
2)算法
按照路径长度的非降次序生成这些路径。
首先,生成一条到最近结点的最短路径,然后,生成一条到第二近结点的最短路径,等等。
即只用求出从路径v0开始到G中其他所有结点的最短路径长度。
假定G中n个结点被标记上1到n,集合S作为一个数组存放,如果结点i不在S中,则S[i]=0,如果在S中,则S[i]=1,若COST(i,j)是(i,j)的权,则在边(i,j)不在成本邻接矩阵时,就被置某个大数,这里用N表示,当i=j时,COST(i,j)被置以0。
3.程序源代码
#include
#include
#defineN1000
voidshortestPaths(intv,int*COST,int*DIST,intn);//最短路径生成函数
voidoutput2(int*arr,introw,intcol);//输出成本的邻接矩阵
voidoutArray1(int*arr,intn);//输出更新后其它结点到起始结点的路径长度
intmain()
{
intCOST[7][7]={
{0,20,50,30,N,N,N},
{N,0,25,N,N,70,N},
{N,N,0,40,25,50,N},
{N,N,N,0,55,N,N},
{N,N,N,N,0,10,70},
{N,N,N,N,N,0,50},
{N,N,N,N,N,N,0}
};
intDIST[7];
intv=0;
/*printf("成本邻接矩阵:
\n");
output2(&COST[0][0],7,7);
*/
//生成0号结点到1至6号结点的最短路径
shortestPaths(v,&COST[0][0],DIST,7);
return0;
}
voidshortestPaths(intv,int*COST,int*DIST,intn)
{//G是一个n结点有向图,它由其成本邻接矩阵COST[n][n]表示,DIST[j]被置以结点v到
//结点j的最短路径长度,这里1<=j<=n;DIST[v]被置成0
intS[n];
intpre[n];//p[w]记录起始结点到结点w的最短路径中的w前一结点
intu,num,i,w;
inttv,td=0;
//初始化:
结点v以外的结点未被选中,并更新路径长度为v到其它结点的初始成本
for(i=0;i { S[i]=0; *(DIST+i)=*(COST+v*n+i); pre[i]=0; } S[v]=1; DIST[v]=0; //更新路径长度 for(num=1;num { //选择距离结点v最近的结点w for(w=1;w { if(S[w]==0) { td=DIST[w]; tv=w; break; } } for(w++;w { if(S[w]==0&&td>DIST[w]) { td=DIST[w]; tv=w; } } u=tv; S[u]=1; DIST[u]=td; //更新路径 for(w=1;w { if(S[w]==0) { //DIST[w]=min(DIST[w],DIST[u]+*(COST+u*n+w)); if(DIST[w]>(DIST[u]+*(COST+u*n+w))) { DIST[w]=(DIST[u]+*(COST+u*n+w)); pre[w]=u;//更新结点w最短路径并记录w结点的上一结点 } } } //输出第num次更新后的路径长度 printf("\n第%d次路径: ",num); output1(DIST,n); printf("\n\n"); } //输出路径 for(i=1;i { printf("从0到%d,最短的路径是: \n",i); w=i; printf("%d<-",w); while(pre[w]! =v) { w=pre[w]; printf("%d<-",w); } printf("%d\n",v); } } voidoutput2(int*a,introw,intcol) { inti,j; for(i=0;i { for(j=0;j { if(*((a+i*row)+j)==N) printf("N\t"); else printf("%3d\t",*((a+i*row)+j)); } puts("\n"); } } voidoutput1(int*arr,intn) { inti; for(i=0;i { if(*(arr+i)==N) printf("N\t"); else printf("%3d\t",*(arr+i)); } } 4.运行演示 我用了书上的一个例子,它的成本邻接矩阵已直接存入程序中,它的带权有向图如下: V0 V1 V2 V3 V5 V6 V4 20 70 25 50 30 40 55 50 25 10 50 70 图2带权有向图 运行结果如下所示: 图3运行结果图 二.实验二 1.实验题目 k路归并: 每次同时归并k个文件且使移动次数最少。 2.设计思路 1、流程图 总流程图如图1所示。 图1归并文件流程图 2、设计方法 贪心算法 3、度量标准 每次选出k个最小的文件归并,将归并后的结果作为新的文件加入待归并的文件序列中,直到归并完成。 值得注意的是,由于所有的内部点的度数必须为k,因此,对于n取某些值,就不和k元归并树相对应。 所以有必要引进一定量的虚结点,每个虚结点赋值0,这个虚结点的虚值,不会影响所产生度数为k的带权外部路径长度。 3.程序源代码 #include #include #include #include #defineMAX100 typedefintElemType; typedefstructTable { ElemTypeelem; structTable*next; }T; voidoutTable(T*head); voidfunc(T*head,intk); intmain() { intnum,k,r; T*head,*cur; head=(T*)malloc(sizeof(T)); head->elem=0; //获取文件数 do { printf("请输入文件的个数(>1): "); scanf("%d",&num); }while(num<=1); //获取归并值 do { printf("请输入是几路归并(>1,<=%d): ",num); scanf("%d",&k); }while(k<=1||k>num); //生成随机序列 srand(time(NULL)); cur=(T*)malloc(sizeof(T)); head->next=cur; head->elem++; cur->elem=(rand()%MAX+1); while(head->elem { cur->next=(T*)malloc(sizeof(T)); cur=cur->next; cur->elem=(rand()%MAX+1); head->elem++; } printf("随机生成的文件序列为: "); outTable(head); //补充虚结点 r=((k-1)-(num-1)%(k-1))%(k-1); while(head->elem { cur=(T*)malloc(sizeof(T)); cur->elem=0; cur->next=head->next; head->next=cur; head->elem++; } if(r==0) printf("不用补充虚结点\n"); else{ printf("补充%d个虚结点: ",r); outTable(head); } //归并 func(head,k); return0; } voidfunc(T*head,intk) { T*min[k],*mpre,*cur,*cpre; inti=0,j=1,times=(head->elem-1)/(k-1),t=times; while(times-->0)//当K小于等于待归并文件数时,取K个最小的文件归并 { if(k<=head->elem) { i=-1; //取k个最小的文件 while(++i { mpre=cpre=head; min[i]=cur=head->next; j=0; while(j { if(min[i]->elem>cur->elem) { mpre=cpre; min[i]=cur; } cpre=cur; cur=cur->next; j++; } mpre->next=min[i]->next; head->elem--; } } //输出归并的K个文件的大小 printf("第%d次归并: ",t-times); i=0; while(i { printf("%4d",min[i]->elem); i++; } i=1; //归并K个文件 while(i { min[0]->elem+=min[i]->elem; free(min[j]); i++; } //将归并K个文件得到的新文件加入节点中 min[0]->next=head->next; head->next=min[0]; head->elem++; //输出归并后的文件 printf("\t归并后的文件为: "); cur=head->next; i=head->elem; while(i-->0) { printf("%4d",cur->elem); cur=cur->next; } printf("\n"); } } void
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 实验 报告