tsp问题 模拟退火算法

#include<iostream>
#include<cmath>
#include<stdlib.h>  
#include<stdio.h>
#include<time.h>
using namespace std;

int Length(int **d,int *node,int n);

int main(){
	int v=0.9;  //衰减函数 α(t)=0.9 * t0
    int t0=100; //初始温度
    int L=20000;//Mapkob链路径长度 
    int s=0;//停止准则为连续两个Mapkob链路径无变化
    int length=0;
    int bChange=0;
    double m;//保存e的指数
	double l;//保存随机浮点数
	int n;//n个城市
	cout<<"输入城市个数:"<<endl;
	cin>>n;
	//创建二维数组 
	int **d=new int *[n];
	for(int i=0;i<n;i++)
		d[i]=new int[n];
		cout<<"输入距离:"<<endl;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			cin>>*(d[i]+j);
  //初始化最短路径 
	int *road=new int[n];
	
	for(int i=0;i<n;i++)
		road[i]=i+1;
		
    int *minroad=new int[n];
	
  	for(int i=0;i<n;i++)
		minroad[i]=i+1;
	
	//	for(int i=0;i<n;i++){
	//	for(int j=0;j<n;j++)
	//		cout<<*(d[i]+j)<<" ";
	//	cout<<endl;
//	}	
	//0 9 2 1 9 0 1 2 2 1 0 8 1 2 8 0
		while(s!=2){
			//采用2变换法产生新的路径
			bChange=0;
			int temp=0;
			//srand(time(0));
			int r1=rand()%n;
			int r2=rand()%n;
			//cout<<r1<<"+"<<r2<<endl;
				while(r1==r2)
				r2=rand()%n;
		    if(r1>r2){
				temp=r1;
				r1=r2;
				r2=temp;
			}
			//将u和v及其之间的顺序逆转
		temp=0;
     	while(r1<r2){
		temp=*(road+r1);
		*(road+r1)=*(road+r2);
		*(road+r2)=temp;
		r1++;
		r2--;
     	}
     	
     	// 计算 df = f(j)-f(i) 的值
			length=Length(d,road,n)-Length(d,minroad,n);
			//根据Metropolis准则判断是否接受新的路径
				if(length<0){
				for(int i=0;i<n;i++)  //保存最短路径
					*(minroad+i)=*(road+i);
				bChange=1;
			}
			else{ 
				m=(double)(-length)/t0;
				l=(double)(rand()/(double)RAND_MAX);
				if(exp(m)>l){
					for(int i=0;i<n;i++)  //保存最短路径
						*(minroad+i)=*(road+i);
					bChange=1;
				}
			}
			t0=t0*v;// 衰减函数 α(t)=0.9 * t 
		if(bChange==0)
			s += 1;
		else s=0;	
			
		}
		for(int i=0;i<n;i++)
		cout<<*(minroad+i)<<"->";
		cout<<*(minroad)<<endl;
		cout<<"最短长度为:"<<Length(d,minroad,n)<<endl;
	
		return 0;
		
	
}
//计算路径长度函数
int Length(int **d,int *node,int n){
	int p=0;  //路径结点从1开始
	int i=0,j=0; //两结点间的路径在二维数组里的位置
	int s=0; //遍历节点
	int length=0; //路径长度
	for(s=0;s<n-1;s++){
		i=*(node+s)-1;
		j=*(node+s+1)-1;
		length += *(d[i]+j);
	}
	i=*(node+n-1)-1;
	j=*(node)-1;
	length += *(d[i]+j);
	return length;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值