模拟退火求解TSP问题报告.doc
文本预览下载声明
模拟退火求解TSP问题实验报告
实验要求:
旅行商问题(Travelling Salesman Problem, 简记TSP,亦称货郎担问题):设有n个城市和距离矩阵D=[dij],其中dij表示城市i到城市j的距离,i,j=1,2 … n,则问题是要找出遍访每个城市恰好一次的一条回路并使其路径长度为最短。
实验思路:
1)指标函数:访问所有城市的路径的长度
2)新解的产生: 选择两个城市间的位置交换方式得到一个可能解的邻域,在随机选择一个解
3)新解的接受准则:exp(-(fj-fi)/t)
4)初始温度的确定:产生一组解,使其平均接受概率为0.9
5)内循环次数:n
6)温度的衰减系数:0.95
7)算法的停止准则:温度低于.01获没有新解产生
实验代码:
/*
指标函数:访问所有城市的路径的长度
新解的产生: 选择两个城市间的位置交换方式得到一个可能解的邻域,在随机选择一个解
新解的接受准则:exp(-(fj-fi)/t)
初始温度的确定:产生一组解,使其平均接受概率为.9
内循环次数:n
温度的衰减系数:.95
算法的停止准则:温度低于.01获没有新解产生
*/
#includestdlib.h
#includestdio.h
#includemath.h
#includetime.h
const long MAX=100;
struct
double x,y;
} city[MAX];
//函数:读入数据--返回城市数目
long initial()
{
long i,n;
//读入城市的数目、x坐标、y坐标
scanf(%d,n);
for(i=0;in;i++)
scanf(%lf%lf,city[i].x,city[i].y);
return n;
}
//函数:计算指标函数f(i)的值
double cal_f(long *path,long n)
{
long pre,i;
double len;
len=0.0;
pre=path[0];
for(i=1;in;i++){
len+=sqrt((city[path[i]].x-city[pre].x)*(city[path[i]].x-city[pre].x)
+(city[path[i]].y-city[pre].y)*(city[path[i]].y-city[pre].y));
pre=path[i];
}
len+=sqrt((city[path[0]].x-city[pre].x)*(city[path[0]].x-city[pre].x)
+(city[path[0]].y-city[pre].y)*(city[path[0]].y-city[pre].y));
return len;
}
void generate_path(long *path,long n);
//函数:计算初始温度
double cal_temperature(long num)
{
long j,n;
double t,sum,fi,fj;
long path[MAX];
t=1.0;
n=20*num;
while(1){
sum=0.0;
generate_path(path,num);
fi=cal_f(path,num);
for(j=0;jn;j++){
generate_path(path,num);
fj=cal_f(path,num);
sum+=fi-fj;
fi=fj;
}
if(exp(-(sum/n)/t)=0.9)
break;
t*=1.05;
};
return t;
}
//函数:生成一个序列作为解
void generate_path(long *path,long n)
{
long i,cnt,temp;
long mark[MAX];
for(i=0;in;i++)
mark[i]=0;
cnt=0;
//srand(time(NULL)); //pay attention to随机数的生成??
while(cntn){
temp=rand()%n;
if(mark[temp]==0){
mark[temp]=1;
path[cnt]=temp;
cnt++;
}
}
}
long main()
{
freopen(10.txt,r,stdin);
clock_t start,finish;
struct Neighbour{
long path[MAX];
bool flag;//true--未选择;false--已选择
} nei
显示全部