1、1)个顶点的完全连通无向图中,任意选择一个顶点Vi作为起始点,在与顶点Vi相关联的n-1条边中,选择一条权值最小的边ei,此边可连接Vi及图中另一个顶点Vj,然后在与Vi或Vj相关联除ei以外的所有边中,选择权值最小的边ej,ej又可连接另外一个顶点(边的选则还要保证树中没有环的产生)。依此求顶点的方法,依次求出所有的可连接n个顶点的n-1条边,因为在此生成树中的每一条边均为不会生成环的,且权值最小的连接顶点的边,因此这棵生成树为此含有n(n1)个顶点的完全连通无向图的最小生成树。搜索算法中应包括:输入设计(城市数目;城市坐标;一个存储完全图的二维数组arry1maxmax(邻接矩阵,其中,m
2、ax表示城市的数目,arry1ij表示第i和第j个城市间的距离,例如下面的矩阵所示)。);路径查找设计(一个用于判断某个顶点是否已被选过的一维标志位数组arry2max;一个用来存储查找的最短路径以及路径长度的二维数组arry3maxmax+2(array3i1和array3imax用来存储从第i个顶点出发的这条路径的起始点和始点array3imax+1中存储的是这条闭合回路的路径长度。)V1 V2 V3 V4 V5 V6V1 0 6 1 5 0 0V2 6 0 5 0 3 0V3 1 5 0 5 6 4V4 5 0 5 0 0 2V5 0 3 6 0 0 6V6 0 0 4 2 6 0 四、
3、结 果(运行时间均只需几秒)1、10个随机城市的TSP。2、12个随机城市的TSP3、30个随机城市的TSP(先将Max改为31).五、程 序# includemath.hstdio.hstdlib.h# define Max 21 int cn,tt,start; / 要经过的城市个数,起点double arry1MaxMax; / 邻接矩阵,存放两两城市间的距离double fn=0,gn=0,hn=0; / 启发函数double f1=0,g1=0,h1=0;int arry3Max; / 存放已历经的城市名int arry4Max; / 标志位数组,cn个城市中已历经的置,未历经的置/
4、 定义顶点数据类型struct Vertex int x; int y;CityMax;/ 主函数void main() void RandNum(int); void CityCoordinate(); double CityCost(int,int); void TSP(); double MaxLengh(); int i,j; CityCoordinate(); / 随机生成并显示个城市及其坐标 printf(n); for(i=1; iMax; i+) / 随机生成并显示表示两城市间距离的邻接矩阵 tt=0; for(j=i; j j+,tt+) if(i=j) arry1ij=0;
5、 else arry1ij=CityCost(i,j); TSP(); / 用最小生成树查找最短路径n从%d出发的最佳路径为:%d,start,start); for(i=2;i=cn;i+) printf(,arry3i);%dn,arry3cn+1);总路径长度为:%fn,fn);/ 随机数产生器int RandNum(int max) int m; m=rand()%(max-1)+1; / 产生一个20的随机数 return m;/ 生成并显示城市坐标void CityCoordinate() int i,j,hh=0; srand(unsigned)time(NULL); / 使用当
6、前时间作为种子 City1.x=RandNum(Max); / 生成并显示第个城市的坐标 City1.y=RandNum(Max);City1的坐标: (%d,%d); , City1.x, City1.y);i+) / 生成第20个城市的坐标 Cityi.x=RandNum(Max); Cityi.y=RandNum(Max); for(j=1;ji;j+) / 检查重合坐标,有重合时重新生成 if(Cityi.x= Cityj.x& Cityi.y= Cityj.y) i=i-1; hh+; / 换行 if(0!=i%2) hh=0; if(0=hh) printf(City%d的坐标:,
7、 i, Cityi.x, Cityi.y);/ 显示第i个城市的坐标/ 计算并显示城市间的欧式距离double CityCost(int i,int j) int x1,x2,y1,y2,hh=0; double Distance,t; x1= Cityi.x; x2= Cityj.x; y1= Cityi.y; y2= Cityj.y; t=(x1-x2)* (x1-x2)+(y1-y2)* (y1-y2); Distance=sqrt(t); arry1ij=Distance;=tt%2) hh=0; / 换行 %d与%d的距离:%3.2f , i, j, Distance); retur
8、n arry1ij;/ 用启发式的MST查找最短路径/void TSP() int Mnode; / 起点,当前搜索层的父节点 int h,i,k,l,m,n,nn; int x,y=0; int arry2Max=0,0, 0,0, 0, 0,0, 0,0, 0, 0,0, 0,0, 0, 0,0, 0,0, 0,0; / 标志位数组,已历经的置0,未历经的置1 double temp1=100,temp2=100; double layer1Max; / 初始化当前搜索层节点 double layer2Max; / 初始化后继搜索层节点n请输入要经过的城市个数: scanf_s(%d,&c
9、n);请输入要历经的城市: for(h=1;hh+) / 输入历经节点x); if(0=arry2x) arry2x=1; / 避免重复 else if(1=arry2x) h=h-1;i+) / 显示历经节点 if(1=arry2i) %d ,i);请输入出发城市: / 输入出发点start); arry2start=0; / 初始化 arry31=start; arry3cn+1=start; Mnode=arry31; / 搜索路径for(n=2;nn+) / 找出城市cn for(nn=1;nnnn+) / 初始化layer1和layer2 layer1nn=0; layer2nn=0
10、; for(k=1;kk+) / 搜索Mnode所有后继节点 if(1=arry2k) gn=g1+arry1Mnodek; hn=arry1kstart; fn=gn+hn; layer1k=fn; for(l=1;ll+) / 找出第一个后继节点y,并初始化y=layer1l) y=l; break; for(m=y+1;mlayer2l) temp1=layer2l;nn+) layer2nn=0; / 初始化layer2 Mnode=m; / 再以m为父节点 arry2y=1; arry2m=0;k+) / 搜索m的所有后继节点l+) / 找出m的代价最小的后继节点temp2layer2l) temp2=layer2l; arry2m=1; / 消除假设条件下对arry2值的改变 if (temp1temp2) y=m; else if(0!=layer1m&layer1ylayer1m) y=m; /。 g1=g1+arry1Mnodey; arry3n=y;fn=g1+arry1ystart;/ 搜索路径
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1