模拟退火算法 解决 TSP问题 (旅行商问题)(C语言)

8 篇文章 0 订阅
1 篇文章 0 订阅

问题:模拟退火算法 解决小规模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}
};

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值