这个https://www.cnblogs.com/tian-luo/p/9228570.html题目的模拟退火算法解法,mark一下写法。
#include<bits/stdc++.h> #define N 25 using namespace std; struct ss { int path[N]; }; int dis[N][N],n; int xiagao() { srand(time(0)); ss now; for(int i=1;i<=n;i++)now.path[i]=i; random_shuffle(now.path+2,now.path+n); int ans=0; for(int i=1;i<n;i++)ans+=dis[now.path[i]][now.path[i+1]]; double T=1,k=0.999,eps=1e-6; while(T>eps) { int l=rand()%(n-2)+2; int r=rand()%(n-2)+2; if(l>r)swap(l,r); int diss=dis[now.path[l-1]][now.path[r]]+dis[now.path[l]][now.path[r+1]]-(dis[now.path[l-1]][now.path[l]]+dis[now.path[r]][now.path[r+1]]); if(diss<0) { ans+=diss; int ls[N]; for(int i=r;i>=l;i--)ls[i]=now.path[l+r-i]; for(int i=l;i<=r;i++)now.path[i]=ls[i]; } else { double ran=double(rand()%10000); ran/=9999.0; if(ran<exp((double)diss*-1.0/T)) { ans+=diss; int ls[N]; for(int i=r;i>=l;i--)ls[i]=now.path[l+r-i]; for(int i=l;i<=r;i++)now.path[i]=ls[i]; } } T=k*T; } return ans; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)scanf("%d",&dis[i][j]); int upper=1000,ans=INT_MAX; while(upper--) { ans=min(ans,xiagao()); //printf("%d ",ans); } printf("%d ",ans); return 0; }