tspWord文档格式.docx
《tspWord文档格式.docx》由会员分享,可在线阅读,更多相关《tspWord文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
1)个顶点的完全连通无向图中,任意选择一个顶点Vi作为起始点,在与顶点Vi相关联的n-1条边中,选择一条权值最小的边ei,此边可连接Vi及图中另一个顶点Vj,然后在与Vi或Vj相关联除ei以外的所有边中,选择权值最小的边ej,ej又可连接另外一个顶点(边的选则还要保证树中没有环的产生)。
依此求顶点的方法,依次求出所有的可连接n个顶点的n-1条边,因为在此生成树中的每一条边均为不会生成环的,且权值最小的连接顶点的边,因此这棵生成树为此含有n(n>
1)个顶点的完全连通无向图的最小生成树。
搜索算法中应包括:
输入设计(城市数目;
城市坐标;
一个存储完全图的二维数组arry1[max][max](邻接矩阵,其中,max表示城市的数目,arry1[i][j]表示第i和第j个城市间的距离,例如下面的矩阵所示)。
);
路径查找设计(一个用于判断某个顶点是否已被选过的一维标志位数组arry2[max];
一个用来存储查找的最短路径以及路径长度的二维数组arry3[max][max+2](array3[i][1]和array3[i][max]用来存储从第i个顶点出发的这条路径的起始点和始点array3[i][max+1]中存储的是这条闭合回路的路径长度。
)
V1V2V3V4V5V6
V1061500
V2605030
V3150564
V4505002
V5036006
V6004260
四、结果(运行时间均只需几秒)
1、10个随机城市的TSP
。
2、12个随机城市的TSP
3、30个随机城市的TSP(先将Max改为31)
.......................................................................................
五、程序
#include<
time.h>
math.h>
stdio.h>
stdlib.h>
#defineMax21
intcn,tt,start;
//要经过的城市个数,,起点
doublearry1[Max][Max];
//邻接矩阵,存放两两城市间的距离
doublefn=0,gn=0,hn=0;
//启发函数
doublef1=0,g1=0,h1=0;
intarry3[Max];
//存放已历经的城市名
intarry4[Max];
//标志位数组,cn个城市中已历经的置,未历经的置
//定义顶点数据类型
structVertex
{
intx;
inty;
}City[Max];
///////////////////////////////////////////////////////////////////////////////////////////
//主函数
voidmain()
{
voidRandNum(int);
voidCityCoordinate();
doubleCityCost(int,int);
voidTSP();
doubleMaxLengh();
inti,j;
CityCoordinate();
//随机生成并显示个城市及其坐标
printf("
\n"
);
for(i=1;
i<
Max;
i++)//随机生成并显示表示两城市间距离的邻接矩阵
{
tt=0;
for(j=i;
j<
j++,tt++)
{
if(i==j)arry1[i][j]=0;
elsearry1[i][j]=CityCost(i,j);
}
TSP();
//用最小生成树查找最短路径
\n从%d出发的最佳路径为:
%d→"
start,start);
for(i=2;
i<
=cn;
i++)printf("
arry3[i]);
%d\n"
arry3[cn+1]);
总路径长度为:
%f\n"
fn);
}
//随机数产生器
intRandNum(intmax)
intm;
m=rand()%(max-1)+1;
//产生一个~20的随机数
returnm;
//生成并显示城市坐标
voidCityCoordinate()
inti,j,hh=0;
srand((unsigned)time(NULL));
//使用当前时间作为种子
City[1].x=RandNum(Max);
//生成并显示第个城市的坐标
City[1].y=RandNum(Max);
City[1]的坐标:
(%d,%d);
"
City[1].x,City[1].y);
i++)//生成第~20个城市的坐标
City[i].x=RandNum(Max);
City[i].y=RandNum(Max);
for(j=1;
j<
i;
j++)//检查重合坐标,有重合时重新生成
if(City[i].x==City[j].x&
&
City[i].y==City[j].y)
i=i-1;
hh++;
//换行
if(0!
=i%2)hh=0;
if(0==hh)printf("
City[%d]的坐标:
i,City[i].x,City[i].y);
//显示第i个城市的坐标
//计算并显示城市间的欧式距离
doubleCityCost(inti,intj)
intx1,x2,y1,y2,hh=0;
doubleDistance,t;
x1=City[i].x;
x2=City[j].x;
y1=City[i].y;
y2=City[j].y;
t=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
Distance=sqrt(t);
arry1[i][j]=Distance;
=tt%2)hh=0;
//换行
%d与%d的距离:
%3.2f"
i,j,Distance);
returnarry1[i][j];
//用启发式的MST查找最短路径/////////////////////////////////////////////////////////
voidTSP()
intMnode;
//起点,当前搜索层的父节点
inth,i,k,l,m,n,nn;
intx,y=0;
intarry2[Max]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//标志位数组,已历经的置0,未历经的置1
doubletemp1=100,temp2=100;
doublelayer1[Max];
//初始化当前搜索层节点
doublelayer2[Max];
//初始化后继搜索层节点
\n请输入要经过的城市个数:
"
scanf_s("
%d"
&
cn);
请输入要历经的城市:
for(h=1;
h<
h++)//输入历经节点
x);
if(0==arry2[x])arry2[x]=1;
//避免重复
elseif(1==arry2[x])h=h-1;
i++)//显示历经节点
if(1==arry2[i])
%d"
i);
请输入出发城市:
//输入出发点
start);
arry2[start]=0;
//初始化
arry3[1]=start;
arry3[cn+1]=start;
Mnode=arry3[1];
//////////////////////////////////////////////////////////////////////搜索路径
for(n=2;
n<
n++)//找出城市~cn
for(nn=1;
nn<
nn++)//初始化layer1[]和layer2[]
layer1[nn]=0;
layer2[nn]=0;
for(k=1;
k<
k++)//搜索Mnode所有后继节点
if(1==arry2[k])
gn=g1+arry1[Mnode][k];
hn=arry1[k][start];
fn=gn+hn;
layer1[k]=fn;
for(l=1;
l<
l++)//找出第一个后继节点y,并初始化y
=layer1[l])
y=l;
break;
}
for(m=y+1;
m<
m++)//。
比较并查找最佳后继
if(layer1[y]==layer1[m])////////////////如果出现两个后继代价相同,搜索它们的下一层节点
Mnode=y;
//////先以y为父节点
arry2[y]=0;
k++)//搜索y的所有后继节点
layer2[k]=fn;
l++)//找出y的代价最小的后继节点
=layer2[l]&
temp1>
layer2[l])temp1=layer2[l];
nn++)layer2[nn]=0;
//初始化layer2[]
Mnode=m;
//////再以m为父节点
arry2[y]=1;
arry2[m]=0;
k++)//搜索m的所有后继节点
l++)//找出m的代价最小的后继节点
temp2>
layer2[l])temp2=layer2[l];
arry2[m]=1;
//消除假设条件下对arry2[]值的改变
if(temp1>
temp2)y=m;
elseif(0!
=layer1[m]&
layer1[y]>
layer1[m])y=m;
}//。
g1=g1+arry1[Mnode][y];
arry3[n]=y;
fn=g1+arry1[y][start];
}/////////////////////////////////////////////////////////////搜索路径