问题:模拟退火算法 解决小规模TSP问题 (旅行商问题)
关键词:模拟退火算法;TSP问题;C语言
更多代码见:https://github.com/yxp123456/Algroithm_C
@源代码中基于模拟退火算法,实现了对于小规模TSP问题的求解;
@参数解释
Node_num //点的数目
T_start //初始温度
T_end //截至温度
k //退火系数
COUNTER //一个温度下的迭代次数
(更多解释见源代码)
@算法分析:
模拟退火算法的收敛性并不是很好,容易出现没有收敛到较优解的情况;
@运行结果:
/*******************
18->9->0->25->11->23->5->16->29->1->19->10->4->24->
8->20->7->12->6->28->30->3->14->13->21->22->15->26->2->27->17
>>总路程长度为81523.075436
>>测试次数1471000
>>概率下降次数6051
>>其中频率为0.004114
>>程序用时1.556000
*******************/
/****此处为main.c文件*****/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include"City_data.h"
/*模拟退火算法 求最优短路径 TSP问题
(无约束条件)
author:YXP
e-mail:yxp189@protonmail.com*/
int main(int argc, char *argv[]) {
time_t start,finish;
start = clock();
init ();
srand ((unsigned)time(NULL));
double T = T_start;
int* Route_test;
Route_test = (int*)malloc(sizeof(int)*Node_num);
copy_route (City_route,Route_test);
int i,counter=0,cp=0;
double r,R_len_CR,R_len_Rt,deta;
while (T>T_end){
for (i=0;i<COUNTER;i++){
recombine_route (Route_test);
R_len_CR=route_len(City_route);
R_len_Rt=route_len(Route_test);
deta = R_len_CR-R_len_Rt;
if (deta>0){
copy_route(Route_test,City_route);
}else{
if (exp(deta/T)>((double)rand()/(RAND_MAX+1.0))){
copy_route(Route_test,City_route);
cp++;
}
}
counter ++;
}
T=T*k;
}
for (i=0;i<Node_num;i++){
printf ("%d->",City_route[i]);
}
printf ("\n>>总路程长度为%lf\n",route_len(City_route));
double rate = (1.0*cp)/counter;
printf (">>测试次数%d\n>>概率下降次数%d\n>>其中频率为%lf\n",counter,cp,rate);
finish = clock();
double duration = ((double)(finish-start) )/CLOCKS_PER_SEC;
printf (">>程序用时%lf\n",duration);
return 0;
}
int copy_route (int* from_arr,int* to_arr)
{
int change_counter=0,i;
for (i=0;i<Node_num;i++){
if(from_arr[i]!=to_arr[i]){
to_arr[i] = from_arr[i];
change_counter++;
}
}
return change_counter;
}
double route_len (int *Route)
{
double len;
int i;
for (i=0;i<Node_num-1;i++){
len += Distance(Route[i],Route[i+1]);
}
return len;
}
int recombine_route (int *Route)
{
double p1=((double)rand()/(RAND_MAX+1.0));//Posibility_1
double p2=((double)rand()/(RAND_MAX+1.0)) ;
int Node_1 = p1*Node_num;
int Node_2 = p2*Node_num;
int temp = Route [Node_1];
Route [Node_1] = Route [Node_2];
Route [Node_2] = temp;
return Node_1*100+Node_2;
}
void init (void)
{
int i;
for (i=0;i<Node_num;i++){
City_route[i] = i;
}
}
double Distance (int From_node,int To_node)
{
double distance;
distance = sqrt((city_node[From_node][0]-city_node[To_node][0])*(city_node[From_node][0]-city_node[To_node][0])
+(city_node[From_node][1]-city_node[To_node][1])*(city_node[From_node][1]-city_node[To_node][1]));
return distance;
}
/****此处为City_data.h文件****/
#define Node_num 31//点的数目
#define T_start 50000.0//初始温度
#define T_end (1e-8)//截至温度
#define k 0.98//退火系数
#define COUNTER 1000//一个温度下的迭代次数
double Distance (int From_node,int To_node);
void init (void);
int recombine_route (int *Route);
double route_len (int *);
int copy_route (int* from_arr,int* to_arr);
int City_route [Node_num] ={0};
double city_node[Node_num][2] =
{
{1304,2312},{3639,1315},{4177,2244},
{3712,1399},{3488,1535},{3326,1556},
{3238,1229},{4196,1004},{4312,790},
{4386,570},{3007,1970},{2562,1756},
{2788,1491},{2381,1676},{1332,695},
{3715,1678},{3918,2179},{40661,2370},
{3780,2212},{3676,2578},{4029,2838},
{4263,2931},{3429,1908},{3507,2367},
{3394,2643},{3439,3201},{2935,3240},
{3140,3550},{2545,2357},{2778,2826},
{2370,2975}
};