启发式算法之模拟退火算法 旅行商问题TSP C++实现

文章给出旅行商问题的模拟退火算法的C++实现:
环境:win7 vc6.0

头文件:

#include 
#include 
#include 
#include 
#include 
using namespace std;

全局变量的定义:
通过修改退火速度,初始温度可以得到不同程度的解

const int nCities = 99;   //城市数量
const double SPEED = 0.98;   //退火速度
const int INITIAL_TEMP = 1000;   //初始温度
const int L = 100 * nCities;   //Markov链的长度
double length_table[nCities][nCities]; // 城市距离

解得结构:
length 旅行商最终的路径长度
path 数组旅行商依次经过的城市


struct unit{
	double length; //路径长度
	int path[nCities]; //路径
}; 

下面是用到的函数:

初始化距离矩阵:
这里使用rand()函数随机生成数据,这样会使图的入度和出度不一致,可自己优化

//初始化距离矩阵
void init_dis(){
	for(int i = 0; i < nCities; i++)
		for(int j = 0; j < nCities; j++)
			length_table[i][j] = rand() % 100; //随机生成城市距离
}

生成函数,随机产生一个初始解,这里随机选了一个开始点,然后依次构造path

//随机产生一个初始解,随机选一个初始点顺序构造path
void generate(unit &temp){
	int j = 0;
	int i = rand() % nCities;
	while(j < nCities){
		temp.path[j] = i;
		j++;
		i = (i + 1) % nCities;
	}

}

交换法生成邻居

//交换法生成邻居

void getNewSolution(unit &p){

	int i = rand() % nCities;
	int j = rand() % nCities;
	int temp = p.path[i];
	p.path[i] = p.path[j];
	p.path[j] = temp;
}

计算路径长度


//计算路径长度

void CalCulate_length(unit &p){

	int j = 0;
	p.length = 0;
	for(j = 1; j < nCities; j++){
	
		p.length += length_table[p.path[j - 1]][p.path[j]];
	}
	p.length += length_table[p.path[nCities - 1]][p.path[0]]; //最后一城市到起点

}

接受新解得规则,根据模拟退火算法有两种情况

//接受新解规则 两个情况
bool Accept(unit &bestone, unit &temp, double t){

	if(bestone.length > temp.length)
		return true;
	else{
		if((int)(exp((bestone.length - temp.length) / t) * 100) > (rand() % 101))
			return true;
	}
	return false;
}

打印解

//打印解数组
void printp(unit p){
	cout<<"旅行商的距离为:"<<p.length<<endl;
	cout<<"经过的城市依次为:"<<endl;
	for(int i = 0; i < nCities; i++)
	{
		cout<<p.path[i]<<"  ";
		if((i+1) % 10 == 0)
			cout<<endl;
	}
	cout<<endl;
	cout<<endl;
}

核心算法,TSP模拟退火的过程

//TSP模拟退火算法
void SA_TSP(){

	srand(time(0));
	int i =0;
	double r = SPEED;
	double t = INITIAL_TEMP;
	const double t_min = 0.001;
	unit temp;
	unit bestone;
	generate(temp);
	CalCulate_length(temp);
	memcpy(&bestone, &temp, sizeof(temp));
	//打印初始解
	printp(bestone);
	while(t > t_min){
	
		for(i = 0; i < L; i++){
			getNewSolution(temp);
			CalCulate_length(temp);
			if(Accept(bestone, temp, t))
				memcpy(&bestone, &temp, sizeof(unit));
			else
				memcpy(&temp, &bestone, sizeof(unit));
		}
		t *=r;//退火

	}
	//打印最终解
	printp(bestone);
	return;
}

最后是主函数

int main(){
	init_dis();//初始化距离矩阵
	SA_TSP();//打印解在函数中
	return 0;
}

程序运行结果:
启发式算法之模拟退火算法 旅行商问题TSP C++实现_第1张图片

你可能感兴趣的:(启发式算法之模拟退火算法 旅行商问题TSP C++实现)