模拟退火——模板

题目背景为TSP。

 

View Code
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<ctime>
  7 
  8 using namespace std;
  9 
 10 const int maxn=100;
 11 const double max_t=10000.0;
 12 const double ratio=0.98;
 13 const double eps=1e-6;
 14 const int per_t=25;
 15 const int tT=1;
 16 
 17 int n;
 18 
 19 int ans;
 20 
 21 bool use[maxn];
 22 
 23 int map[maxn][maxn];
 24 
 25 int z[maxn],y[maxn];
 26 
 27 void calc()
 28 {
 29     for (int T=1;T<=tT;T++)
 30     {
 31         memset(use,false,sizeof(use));
 32         use[0]=true;
 33         long long nowans=0;
 34         use[1]=true;
 35         z[1]=1;
 36         for (int a=2;a<=n;a++)
 37         {
 38             int wx=0;
 39             while (use[wx])
 40                 wx=rand()%n+1;
 41             z[a]=wx;
 42             use[wx]=true;
 43             nowans+=map[z[a-1]][z[a]];
 44         }
 45         nowans+=map[z[n]][z[1]];
 46         for (double nowt=max_t;nowt>=eps;nowt*=ratio)
 47         {
 48             for (int hehe=1;hehe<=per_t;hehe++)
 49             {
 50                 int nowp1=rand()%(n-1);
 51                 int nowp2=rand()%(n-1);
 52                 while (nowp1==nowp2)
 53                 {
 54                     nowp1=rand()%(n-1);
 55                     nowp2=rand()%(n-1);
 56                 }
 57                 nowp1+=2;nowp2+=2;
 58                 if (nowp1>nowp2) swap(nowp1,nowp2);
 59                 long long newans=0;
 60                 swap(z[nowp1],z[nowp2]);
 61                 for (int a=1;a<n;a++)
 62                     newans+=map[z[a]][z[a+1]];
 63                 newans+=map[z[n]][z[1]];
 64                 long long delta=nowans-newans;
 65                 if (newans<nowans || exp((double)delta/nowt)>rand()/RAND_MAX)
 66                 {
 67                     nowans=newans;
 68                 }
 69                 else swap(z[nowp1],z[nowp2]);
 70                 if (ans>nowans)
 71                 {
 72                     for (int a=1;a<=n;a++)
 73                         y[a]=z[a];
 74                     ans=nowans;
 75                 }
 76             }
 77         }
 78     }
 79 }
 80 
 81 int main()
 82 {
 83     scanf("%d",&n);
 84     if (n==1)
 85     {
 86         printf("0\n");
 87         return 0;
 88     }
 89     for (int a=1;a<=n;a++)
 90         for (int b=1;b<=n;b++)
 91             scanf("%d",&map[a][b]);
 92     ans=123456789;
 93     srand(time(0));
 94     calc();
 95     printf("%d\n",ans);
 96     for (int a=1;a<=n;a++)
 97     {
 98         printf("%d",y[a]-1);
 99         if (a==n) printf("\n");
100         else printf(" ");
101     }
102 
103     return 0;
104 }

 

 

原文地址:https://www.cnblogs.com/zhonghaoxi/p/2584347.html