#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;
}
tsp问题 模拟退火算法
最新推荐文章于 2023-11-29 14:29:00 发布