1、管道铺设施工的最佳方案问题可编辑一问题描述:1.实验题目:需要在某个城市n个居民小区之间铺设煤气管道,则在这n个居民小区之间只需要铺设n-1条管道即可.假设任意两个小区之间都可以铺设管道,但由于地理环境不同,所需要的费用也不尽相同.选择最优的方案能使总投资尽可能小,这个问题即为求无向网的最小生成树.2.基本要求:在可能假设的m条管道中,选取n-1条管道,使得既能连通n个小区,又能使总投资最小。每条管道的费用以网中该边的权值形式给出,网的存储采用邻接表的结构。3.测试数据:使用下图给出的无线网数据作为程序的输入,求出最佳铺设方案.右侧是给出的参考解。4.简述每一部分的对象、目的和要求:。主函数部
2、分:对象:图G;目的:为图G分配空间,以作为后续调用函数的参数;要求:无。Create_ALGraph()函数部分:对象:顶点,边及其权值;目的:将顶点,边存放在一起,构成图;要求:构造顶点表,各顶点的邻接表以构造图。.Create_WLGraph()函数部分:对象:图G;目的:将图中的权值只存放一次,存放到w指向的结构体中;要求:权值只存放一次,再分别存放该边的左右顶点.select_info()函数部分:对象:w指向的结构体;目的:将该结构体中的各权值以升序排列;要求:采用简单选择法进行排序.Create_TLGraph()函数部分:对象:排序后的w指向的结构体;目的:找到构成最小生成树的
3、边;要求:依权值升序排列,判断各边是否构成回路来取舍各边。二需求分析1.程序所能达到的基本可能:在n个小区m条管道中,选取n-1条管道,实现连通这n个小区,同时权值之和为最小.2.输入输出形式及输入值范围:程序运行后,用户可根据提示信息:”Please input the vertices and the edges:”输入顶点数和边数,再根据提示信息:”Please input the information of the verticesv:”输入顶点信息,然后进入循环,创建各个顶点的邻接表,即根据提示信息”Please input the information of edgesp,q:
4、”和Please input the information of weight:依次输入各顶点与其他顶点本身以及两者之间的权值,创建图完毕。用户输入完毕后,程序自动输出运行结果。输入值必须为字母和浮点数,可以不必区分大小写.3.测试数据要求:用户输入字母时,输入大写或小写,都可以被该程序识别,正常运行。但必须根据提示信息后面给出的参考形式,有针对性地输入逗号。三概要设计为了实现上述功能,该程序以邻接表来存储图,因此需要图这个抽象数据类型。1.图抽象数据类型定义:ADT ALGraph 数据对象:D=,i=1,2,3。.,n,n 数据关系:R=; 基本操作:Create_ALGraph(G);
5、/创建图Create_WLGraph(G); /将图G中各顶点以及权值存放到新图中,权值只存放一次select_info(W, G);/将新图W中的权值按升序排列Create_TLGraph(w, G);/将最小生成树以顶点对 (i, j)的形式输出ADT ALGraph2.本程序保护模块:主函数模块图模块调用关系:3。主要算法流程图:Create_ALGraph( )算法流程图: Create_WLGraph()算法流程图:Create_TLGraph()算法流程图:四详细设计1.相关头文件的调用说明:includedefine MaxVerNum 1002。元素类型、结点类型和结点指针类型
6、:static void forcefloat(float p)float f = *p;forcefloat(f);typedef struct node int adjvex; float info; struct node next;EdgeNode;typedef struct vnode char vertex; EdgeNode *firstedge;VertexNode;typedef VertexNode AdjListMaxVerNum;struct bianint z,y; float info;;typedef structchar vMaxVerNum; struct
7、bian eMaxVerNum;WGraph;struct visitvisitedMaxVerNum; positionMaxVerNum; vvppMaxVerNumMaxVerNum;3.邻接表类型:typedef structAdjList adjlist; int n,e;ALGraph;/部分基本操作的伪码实现Create_ALGraph(ALGraph *G)int i,j; char p,q; int k; / int x=0; */ EdgeNode s; char a,b; printf(Please input the vertices and the edgesn),&
8、(Ge); printf(”Please input the information of the verticesv:n”); getchar(); for(i=0;i(Gn);i+) scanf(%c”,(Gadjlisti.vertex); G-adjlisti。firstedge=NULL; /*if(G-adjlisti。vertex!= &Gadjlisti。vertex!=nG-adjlisti.vertex!=) x+;/ for(k=0;k2(Ge);k+) printf(Please input the information of edgesp,q:n”); getcha
9、r(); scanf(%c,%c,p,&q); s=(EdgeNode *)malloc(sizeof(EdgeNode); s-adjvex=q-64; i=p64; getchar(); printf(Please input the information of weight:n”); scanf(%f,&(sinfo); s-next=G-adjlisti-1。firstedge; Gadjlisti1.firstedge=s; / printf(”Please output the information:n); printf(”%d,%dn”,Gn,Ge); printf(”x=%
10、dn”,x); for(i=0;iGn;i+) printf(%cn”,G-adjlisti。vertex); s=G-adjlisti.firstedge; while(s!=NULL) printf(”the linbian is %d,the info is %.1fn,sadjvex,sinfo); s=s-next; */int Panduan_Vertex(int k,int i,WGraph *w,EdgeNode s)int t; for(t=0;tk;t+) if((w-et)。y=i+1&(wet)。z=s-adjvex) return 1; return 0;void s
11、elect_info(WGraph W,ALGraph *G) int i,j,p,k; float t; for(i=0;ie);i+) p=i; for(j=i+1;j(Ge);j+) if(W-ej.infoWep。info) p=j; if(p!=i) t=W-ep。info; Wep.info=Wei.info; Wei.info=t; k=W-ep。z; Wep。z=Wei.z; W-ei。z=k; k=Wep。y; W-ep。y=Wei。y; Wei。y=k; / for (i=0;i(G-e);i+) printf(%.1f ,W-ei.info); printf(n);/ i
12、nt judge_vertex(WGraph w,int i,struct visit *vp) if(vpvisitedwei。z-1=1&vp-visitedwei。y-1=1)return 1;else if(vpvisitedw-ei。z1=-1&vp-visitedwei。y-1=1)return 2;else if(vpvisitedw-ei.y-1=-1&vpvisitedw-ei。z1=1)return 3;else if(vpvisitedwei。z-1=1&vp-visitedwei.y-1=1)return 4; void Create_TLGraph(WGraph *w
13、,ALGraph G)WGraph T; int i,j,t,h,k=2; int m=1; int abc,bcd; struct visit vp; vp=(struct visit *)malloc(sizeof(struct visit)); for(i=0;i(Gn);i+) vp-visitedi=1; vppositioni=-1; vpvvppi0=i+1; for(j=1;jG-n;j+) vpvvppij=0; T。v0=w-vwe0。z1; T.v1=wvwe0。y-1; vp-visitedw-e0.z-1=1; vppositionwe0。z1=w-e0。z; for
14、(j=0;jvvppw-e0。z1j=0) vpvvppwe0.z1j=we0。y; break; vpvisitedw-e0.y1=1;vppositionw-e0.y1=w-e0.z; T。e0。info=w-e0.info; T。e0。z=we0。z; T。e0.y=w-e0。y; for(i=1;ie);i+) t=judge_vertex(w,i,vp); if(t=4) if(vp-positionwei.z1=vppositionw-ei。y1) continue; else abc=0; bcd=0; for(j=0;jn;j+) if(vp-vvppvppositionw-e
15、i。y-1-1j!=0) abc+;for(j=0;jn;j+)if(vpvvppvp-positionwei.z11j!=0)bcd+;for(j=bcd,h=0;jpositionw-ei.z-1)1j=vpvvpp(vppositionwei。y-1)-1h; vp-vvppvppositionw-ei。y1-1h=0;for(h=bcd;habc+bcd;h+)vpposition(vp-vvppvppositionwei。z-1-1h)1=vp-positionwei。z-1;T。em.info=w-ei。info; T。em.z=wei。z; T.em.y=wei。y; m+; e
16、lse if(t=1) vpvisitedwei。z-1=1; vp-visitedwei。y-1=1; T.vk+=w-vw-ei.z-1; T.vk+=w-vw-ei。y1; T.em.info=wei。info; T。em。z=wei。z; T.em.y=w-ei。y; m+; vppositionw-ei.z-1=w-ei。z; vp-positionw-ei。y1=w-ei。z; vpvvppwei。z-11=wei.y; vpvvppw-ei.y-10=0; else if(t=2) vp-visitedwei.z-1=1; vp-positionwei。z-1=vp-positi
17、onwei。y1; for(j=0;jvvppvp-positionw-ei。y1-1j=wei.z; break; vp-vvppwei.z-10=0; T.vk+=w-vwei.z-1; T。em.info=wei。info; T。em.z=w-ei.z; T。em。y=w-ei。y; m+; else if(t=3) vpvisitedw-ei.y-1=1; vp-positionwei。y1=vp-positionwei。z1; for(j=0;j(Gn);j+) if(vp-vvppvppositionwei。z-11j=0) vpvvppvppositionw-ei。z-1-1j=
18、w-ei。y; break; vpvvppw-ei。y10=0; T。vk+=wvwei。y-1; T。em.info=wei.info; T.em。z=w-ei.z; T.em.y=w-ei.y; m+; printf(”Please output the information:n);for(i=0;iadjlist0。firstedge; while(s!=NULL) W-ek。z=1; W-ek.y=s-adjvex; Wek.info=sinfo; k+; s=s-next; for(i=1;i(G-n);i+) Wvi=Gadjlisti.vertex; s=G-adjlisti.
19、firstedge; while(s!=NULL) m=Panduan_Vertex(k,i,W,s); if(m=1) s=snext; continue; else Wek。z=i+1; Wek.y=sadjvex; Wek。info=sinfo; k+; s=snext; / printf(”Please output the information:n”); for(i=0;in;i+) printf(”%cn”,Wvi); for(i=0;iG-e;i+) printf(”d,%d,%.1fn”,Wei。z,Wei。y,Wei。info);*/ select_info(W,G); C
20、reate_TLGraph(W,G);4.主函数的伪码:main()ALGraph G; G=(ALGraph )malloc(sizeof(ALGraph); Create_ALGraph(G); Create_WLGraph(G);5.函数调用关系:五调试分析1.出现问题及解决方法:在刚开始写程序时,由于考虑不全面,在去除连通图闭合回路的算法中遇到很大困难,后来采用以下方法解决了这个问题:将每个顶点分别放在一个结构体中,结构体中的数组visitedi记录顶点Vi是否被访问过的情况,positioni记录顶点Vi的具体位置,二维数组vvppij记录已经将以该顶点为左顶点或右顶点的权值存入T中
21、后,该权值的右顶点或左顶点的编号。其具体思想是:只要将一个权值存入T中,就将相应的左右顶点放到同一个二维数组中,之后每欲将一个权值加入T中,先检验该权值的两顶点是否在同一个二维数组中.若不在,则将该权值存入T中;若在,将该权值舍去(因为再将该权值加入T中,就会出现回路)。2.方法优缺点分析:优点: 思想比较简单,容易令人理解;在写核心算法时,先将字母顶点用相应的数字代替,所以在将数字转化成字母回去时,利用数字与ASCII码值的固定差值,可以保证用户在输入时的大小写字母都可以被该程序识别。缺点:由于采用数字来代替字母,中间的转换关系比较复杂,尤其是将对应关系理清需要足够的耐心和细心。3主要算法的
22、时间和空间复杂度分析:(1)由于Create_ALGraph()算法中将读入顶点的操作执行了n次,读入边的操作执行了2m次,故其时间复杂度为O(n+2m);(2)由于Create_WLGraph()算法将读入权值及其左右顶点的操作执行了n次,故其时间复杂度为O(n);(3)由于Create_TLGraph()算法中根据判断是否构成回路来取舍边,因为有n条边,故要执行n次,所以时间复杂度是O(n);(4)由于select_info()函数采用简单选择法排序,时间复杂度是O();(5)所有算法的空间复杂度都是O(1)。六使用说明程序运行后,用户根据提示输入顶点数,边数,顶点信息,边的信息,权值,输
23、入完毕后程序会自动以顶点对(i, j)的形式输出最小生成树的边。七调试结果输入数据:“9,“15”,“ABCDEFGHI,“A,B”,“32。8,“A,C”,“44。6”,“A,H,“12。1”,“A,I,“18.2”,“B,A”,“32。8”,“B,C”,“5。9,“C,A,“44。6”,“C,B”,“5.9”,“C,D”,“21.3,“C,E”,“41.1,“C,G,“56.4,“D,C”,“21.3”,“D,E”,“67.3,“D,F,“98。7”,“E,C,“41。1”,“E,D”,“67。3”,“E,F”,“85.6”,“E,G”,“10.5”,“F,D”,“98。7,“F,E,“8
24、5。6,“F,I”,“79.2,“G,C”,“56。4”,“G,E”,“10。5”,“G,H,“52。5”,“H,A”,“12。1”,“H,G”,“52.5,“H,I,“8。7”,“I,A”,“18。2”,“I,F”,“79。2”,“I,H,“8。7”。(双引号不需输入)输出数据:(B,C),(H,I),(E,G),(A,H),(C,D),(A,B),(C,E),(F,I) 运行结果截屏: 八附录源程序清单:include /*调用的头文件库说明/includestdlib.h#define MaxVerNum 100static void forcefloat(float p)float f
25、 = *p; /*由于我的TC中不支持浮点数,故添加了这个程序段*/forcefloat(f);typedef struct node /*构造邻接表的结构体/ int adjvex; float info; /*存放权值*/ struct node *next; /*指向下一个邻接点的指针域*/EdgeNode;typedef struct vnode /构造顶点表的结构体/ char vertex; /顶点域*/ EdgeNode firstedge; /边表头指针/VertexNode;typedef VertexNode AdjListMaxVerNum;typedef struct /构造图的结构体/AdjList adjlist; /邻接表/ int n,e; /*顶点数和边数/ALGraph;struct bian /*存放权值及其左右顶点的结构体*/int z,y; float info;typedef struct /*用该结构体来只存放一次权值及其相应的顶点*/char vMaxVerNum; struct bian eMaxVerNum;WGraph;struct visit /*用该结构体来存放各结
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1