管道铺设课程设计报告.docx
- 文档编号:10421259
- 上传时间:2023-02-11
- 格式:DOCX
- 页数:17
- 大小:21.23KB
管道铺设课程设计报告.docx
《管道铺设课程设计报告.docx》由会员分享,可在线阅读,更多相关《管道铺设课程设计报告.docx(17页珍藏版)》请在冰豆网上搜索。
管道铺设课程设计报告
编号:
江西理工大学
数据结构课程设计报告
班级:
学号:
姓名:
时间:
2015年6月22日
~2015年7月3日
指导教师:
2015年06月
一、摘要.....................................................................3
二、引言.......................................................................3
三、需求分析...............................................................3
四、概要设计...............................................................4
1.普利姆算法分析...............................................6
2.模块分析...........................................................6
3.抽象数据类型分析...........................................6
4.全部流程...........................................................6
五、详细设计...............................................................7
1.算法分析...........................................................7
(一)信息输入模块.........................................7
(二)建立最小生成树并输出结果.................8
2.源程序代码.......................................................9
六、测试结果...............................................................14
程序开始...............................................................14
信息输入...............................................................14
输出结果...............................................................14
七、设计体会...............................................................15
八、结束语...................................................................16
参考文献...............................................................16
一、摘要
N(N>10)个居民区之间需要铺设煤气管道。
假设任意两个居民区之间都可以铺设煤气管道,但代价不同。
问题的实质就是编写相应程序求解最小生成树问题。
程序要求:
事先任意两个居民区之间铺设煤气管道的代价存入磁盘文件中。
设计一个最佳方案使得这N个居民区之间铺设煤气管道所需代价最小,并将结果以图形方式在屏幕上输出。
二、引言
C语言作为一门最通用的语言,从语言产生到现在,它已经成为最重要和最流行的编程语言之一。
在各种流行编程语言中,都能看到C语言的影子。
学习掌握C语言是每一个计算机技术人员的基本功之一。
实际生活中最小生成树的问题具有很大的意义。
例如,本文所讨论的构架居民区之间铺设煤气管道代价最小,还有在若干地区铺设光缆等等。
最小生成树让许多诸如求造价最小、最短路径等最优化的现实问题找到了理论依据,并提供了有效的解决方法。
三需求分析
在N(N>10)个居民区之间铺设煤气管道所需代价最小,即求最小生成树问题。
在我们的课本中介绍了两种求解方法:
普利姆算法和克鲁斯卡尔算法。
普利姆算法与网的变数无关,适宜求解边稠密的网的最小生成树。
而克鲁斯卡尔算法正好相反,
适宜求解边稀疏的最小生成树。
由于在实际问题中,居民数量一般很有限,而任何两个居民区都可能有连线,即这样的图应该是边较为稠密的。
因此,我们选择了普利姆算法对问题进行求解。
四概要设计
1.普利姆算法分析
1普利姆算法思想
普利姆算法的思想是:
在图中人去一个定点k0作为开始点,令U={k0},W=V-U,
其中V为图中所有顶点集,然后找一个顶点在U中,另一个顶点在w中的边中最短
的一条,找到后,将该边作为最小生成树的树边保存起来,并将该边顶点全部加入U集合中,并从W中删除这些顶点,然后重新调整U中顶点到W中顶点的距离,使之保持最小,再重复此过程,直到W为空集。
2算法过程描述
1)在图G=(V,E)(V是顶点,E是边)中,从集合V中任取一个顶点,如k0放入集合U中,这时,U={k0},集合T(E)为空。
2)从k0出发寻找与U中顶点相邻权值最小的边的另一顶点k1,并使k1加入U。
即U={k0,k1},同时将该边加入集合T(E)中。
3)重复
(2),直到U=V为止。
4)这时T(E)中有n-1条边,T=(U,T(E))就是一一颗最小生成树。
2、模块分析
根据对模型的功能分析,该管道铺设设计可以具有以下功能:
1管道铺设信息的输入;
2最小生成树信息的输出;
功能模块图:
3.抽象数据类型分析
areanum居民区总数(顶点总数);
edgenum边的总数;
date[][20]邻接矩阵存储图结构;
s边的权值;
short-way[i]居民区i到目前生成树中所有点集U中某个居民区的路程最小值
near-area[i]U中能使其最小的居民区
5.全部流程
五、详细设计
1.算法分析
1信息输入模块
//读入图的信息,并将邻接矩阵输出
Voidread()
{//输入顶点个数和边的条数
Printf(“请输入:
定点数,变数:
\n”);
Scanf(“%d,%d”,&areanum,&dedgenm);
//初始化邻接矩阵各元素值
Inti,j,k;
for(i=0;i for(j=0;j date[i][j]=INFINITY; //读入边 Intfrom,to,s; Printf(“输入边,格式为i,j,k,表示i到j的权值是k: \n”); For(i=0;i { Scanf(“%d,%d,%d”,&from,&to,&s); date[from][to]=s; date[to][from]st; } //输出邻接矩阵 for(i=0;i { for(j=0;j Printf(“%d\t”,date[i][j]); Printf(“\n”); } } 2建立最小生成树并输出结果 //用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边 voidMiniSpanTree_PRIM(MGraphG,VertexTypeu) {//system("cls"); inti,j,k; minsideclosedge; k=LocateVex(G,u); for(j=0;j { if(j! =k) { strcpy(closedge[j].adjvex,u); closedge[j].lowcost=G.arcs[k][j].adj; } } closedge[k].lowcost=0;//初始,U={u} printf("最小代价生成树的各条边为: \n"); for(i=1;i {//选择其余G.vexnum-1个顶点 k=minimum(closedge,G);//求出T的下一个结点: 第K顶点 printf("(%s-%s)\n",closedge[k].adjvex,G.vexs[k]);//输出生成树的边 closedge[k].lowcost=0;//第K顶点并入U集 for(j=0;j if(G.arcs[k][j].adj { //新顶点并入U集后重新选择最小边 strcpy(closedge[j].adjvex,G.vexs[k]); closedge[j].lowcost=G.arcs[k][j].adj; } } system("pause"); } 2.源程序代码 #include #include #include #include #include #defineMAX_VERTEX_NUM20//最大顶点个数 #defineMAX_NAME3//顶点字符串的最大长度+1 //#defineMAX_INFO20//相关信息字符串的最大长度+1 #defineINFINITYINT_MAX//用整型最大值代替∞ typedefintVRType; typedefcharInfoType; typedefcharVertexType[MAX_NAME]; //邻接矩阵的数据结构 typedefstruct { VRTypeadj;//顶点关系类型。 对无权图,用1(是)或0(否)表示相邻否; //对带权图,则为权值类型 InfoType*info;//该弧相关信息的指针(可无) }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //图的数据结构 typedefstruct { VertexTypevexs[MAX_VERTEX_NUM];//顶点向量 AdjMatrixarcs;//邻接矩阵 intvexnum,//图的当前顶点数 arcnum;//图的当前弧数 }MGraph; //记录从顶点集U到V-U的代价最小的边的辅助数组定义 typedefstruct { VertexTypeadjvex; VRTypelowcost; }minside[MAX_VERTEX_NUM]; //若G中存在顶点u,则返回该顶点在图中位置;否则返回-1。 intLocateVex(MGraphG,VertexTypeu) { inti; for(i=0;i if(strcmp(u,G.vexs[i])==0) returni; return-1; } //代价保存为文件 //代价存入文件 voidwenjian() { //system("cls"); FILE*fp; chars[50],ch; strcpy(s,"D: \\record.txt"); if((fp=fopen(s,"ab+"))==NULL) { printf("无法打开此文件\n"); exit(0); } else { //printf("请向磁盘中输入原点总数和边的总数: \n"); //printf("请输入顶点数边数\n"); //scanf("%d%d",&G.vexnum,&G.arcnum); //printf("请输入各居民点: "); //for(inti=1;i<=N;i++) //{ //scanf("%c",&G.vexs[i]); //}in //fput(G.vexs[i],fp); //} //printf("请向磁盘中输入各原点和边的总数同时记录原点,目的点,及相应的权值: (输入#键表示结束)\n"); printf("请向磁盘中输入各原点和边的总数: (输入$键表示结束)\n"); ch=getchar(); while(ch! ='$') { fputc(ch,fp); ch=getchar(); } printf("请向磁盘中输入原点,目的点,及相应的权值: (输入#键表示结束)\n"); ch=getchar(); while(ch! ='#') { fputc(ch,fp); ch=getchar(); } } fclose(fp); system("pause"); } //从文件中得到信息构成图 voidxianshi() { //system("cls"); FILE*fp; chars[50],ch; strcpy(s,"D: \\record.txt"); if((fp=fopen(s,"r"))==NULL) { printf("无法打开此文件\n"); exit(0); } else { while(! feof(fp)) { ch=fgetc(fp); putchar(ch); } } putchar(10); fclose(fp); system("pause"); } //算法7.2P162 //采用数组(邻接矩阵)表示法,构造无向网G。 intCreateAN(MGraph*G) { //system("cls"); inti,j,k,w; //chars[MAX_INFO],*info; //char*info; VertexTypeva,vb; printf("请输入无向网G的顶点数,边数,(空格区分)"); scanf("%d%d",&(*G).vexnum,&(*G).arcnum); printf("请输入%d个顶点的值: \n",(*G).vexnum); for(i=0;i<(*G).vexnum;++i)//构造顶点向量 scanf("%s",(*G).vexs[i]); for(i=0;i<(*G).vexnum;++i)//初始化邻接矩阵 for(j=0;j<(*G).vexnum;++j) { (*G).arcs[i][j].adj=INFINITY;//网初始化为无穷大 //(*G).arcs[i][j].info=NULL; } printf("请输入%d条边的顶点1顶点2权值(以空格作为间隔): \n",(*G).arcnum); for(k=0;k<(*G).arcnum;++k) { scanf("%s%s%d%*c",va,vb,&w);//%*c吃掉回车符 i=LocateVex(*G,va); j=LocateVex(*G,vb); (*G).arcs[i][j].adj=(*G).arcs[j][i].adj=w;//无向 //if(IncInfo) //{ //printf("请输入该边的相关信息(<%d个字符): ",MAX_INFO); //gets(s); //w=strlen(s); //if(w) //{ //info=(char*)malloc((w+1)*sizeof(char)); //strcpy(info,s); //(*G).arcs[i][j].info=(*G).arcs[j][i].info=info;//无向 //} //} } printf("输出临接矩阵: \n"); for(i=0;i<(*G).vexnum;++i) for(j=0;j<(*G).vexnum;++j) {if(j%3==0)printf("\n"); printf("%d",(*G).arcs[i][j].adj); } return1; system("pause"); } //求closedge.lowcost的最小正值 intminimum(minsideSZ,MGraphG) { inti=0,j,k,min; while(! SZ[i].lowcost) i++; min=SZ[i].lowcost;//第一个不为0的值 k=i; for(j=i+1;j if(SZ[j].lowcost>0) if(min>SZ[j].lowcost) { min=SZ[j].lowcost; k=j; } returnk; } //算法7.9P175 //用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边 voidMiniSpanTree_PRIM(MGraphG,VertexTypeu) {//system("cls"); inti,j,k; minsideclosedge; k=LocateVex(G,u); for(j=0;j { if(j! =k) { strcpy(closedge[j].adjvex,u); closedge[j].lowcost=G.arcs[k][j].adj; } } closedge[k].lowcost=0;//初始,U={u} printf("最小代价生成树的各条边为: \n"); for(i=1;i {//选择其余G.vexnum-1个顶点 k=minimum(closedge,G);//求出T的下一个结点: 第K顶点 printf("(%s-%s)\n",closedge[k].adjvex,G.vexs[k]);//输出生成树的边 closedge[k].lowcost=0;//第K顶点并入U集 for(j=0;j if(G.arcs[k][j].adj { //新顶点并入U集后重新选择最小边 strcpy(closedge[j].adjvex,G.vexs[k]); closedge[j].lowcost=G.arcs[k][j].adj; } } system("pause"); } voidmain() {//system("cls"); MGraphG; intxz; while (1) { //system("cls"); printf("\n"); printf("*******************************管道铺设最佳方案选择*******************\n"); printf("0记录保存为文件\n"); printf("1从文件中读记录\n"); printf("2构造无向网\n"); printf("3求出最小生成树\n"); printf("4退出\n"); printf("**********************************************************************\n"); printf("请输入操作序号(0-4): \n"); scanf("%d",&xz); switch(xz) { case0: wenjian();break; case1: xianshi();break; case2: CreateAN(&G);break; case3: MiniSpanTree_PRIM(G,G.vexs[0]);break; case4: exit(0); default: printf("输入无效指令! 按任意键继续! "); system("pause"); } } //system("pause"); } 六.测试结果 七.设计体会 通过数据结构的课程设计使我们对所学知识有了更好的理解,也增强了大家的动手能力。 同时也发现了自己的很多不足之处,对知识的应用能力很是欠缺,应用软件的能力及编程水平与课程要求更是存在很大的差距。 程序的运行结果与理论推导结果完全吻合,即该算法与程序设计满足课程设计要求。 该程序的主要优点是简单易懂,不存在理解上的障碍,也很自然地能想到这种解法。 主要缺点是程序的变动性比较差—初始化邻接矩阵后结果就固定了。 如果能加入图行和图的修改、插入、删除等操作,我想应该会好很多。 八、结束语 转眼,为期两周的《数据结构》课程设计即将结束了。 在这次课程设计中我的c语言知识和数据结构知识得到了很好学习。 编程能力也有了一定的提高。 同时也学回了解决问题的方法。 总结起来,自己主要有以下几点体会: 1.必须牢固掌握基础知识。 由于C语言是大一所学知识,没有好好的去体会掌握,同时也没有掌握好上学期学的《数据结构》这门课,所以在课程设计初期感到无从下手,但在后来的设计过程中自己通过看书和课外资料,并请教其他同学,慢慢地对C语言和数据结构知识有所了解和熟悉。 这时才逐渐有了思路。 所以,在这次课程设计以后,我下了决心: 以后一定要好好学习好专业知识。 2.必须培养严谨的科学态度。 我在编写程序时经常因为一些类似于少写了分号,大括号不匹配等造成的程序调试失败,不够认真仔细,给自己带来了许多麻烦。 3.这次课程设计也让我充分的认识到《数据结构》这门课的重要性。 它给我们的一个思想和大纲,让我们再编程时更容易找到思路,不至于无章可循。 同时它也有更广泛的实际应用价值。 总之,在这次课程设计中,我的C语言以及数据结构知识得到了长足的进步,对编程有了更深层次的了解。 参考文献 1.谭浩强《C语言设计》第2版 2.严蔚敏《数据结构C语言版》
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 管道 铺设 课程设计 报告