模拟退火

 

 

 1 #include<cstdio> 
 2 #include<cstring>
 3 #include<cmath>
 4 #include<ctime>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<set>
 9 #define inf (0x7fffffff)
10 #define l(a) ((a)<<1)
11 #define r(a) ((a)<<1|1)
12 #define b(a) (1<<(a))
13 #define T_min (1e-8)
14 #define R (0.99999)
15 #define e (2.718281828459045)
16 #define pi (3.14159265358979323846)
17 #define rep(i,a,b) for(int i=a;i<=(b);i++)
18 #define clr(a) memset(a,0,sizeof(a))
19 typedef long long ll;
20 typedef unsigned long long ull;
21 using namespace std;
22 int readint(){
23     int t=0,f=1;char c=getchar();
24     while(!isdigit(c)){
25         if(c=='-') f=-1;
26         c=getchar();
27     }
28     while(isdigit(c)){
29         t=(t<<3)+(t<<1)+c-'0';
30         c=getchar();
31     }
32     return t*f;
33 }
34 const int maxn=200009;
35 int n,opt,tmp,pre,del,path[2][maxn];
36 double T=1e5,d[maxn];
37 struct node{
38     double x,y;
39     inline bool operator<(const node A)const{
40         return x<A.x||(x==A.x&&y<A.y);
41     }
42 }X[maxn];
43 int dis(int i,int j){
44      return int(sqrt((X[i].x-X[j].x)*(X[i].x-X[j].x)+(X[i].y-X[j].y)*(X[i].y-X[j].y))); 
45 }
46 int f(int t){
47     int s=0;
48     rep(i,2,n+1) s+=dis(path[t][i-1],path[t][i]);
49     return s;
50 }
51 void newway(){
52     int type=rand()%3,a=rand()%(n-1),b=rand()%(n-1);
53     while(a==b) a=rand()%(n-1);a+=2;b+=2;
54     if(a>b) swap(a,b);
55     if(type==0){
56         rep(i,1,n+1) path[opt^1][i]=path[opt][i];
57         swap(path[opt^1][a],path[opt^1][b]);
58     }else if(type==1){
59         rep(i,1,a-1) path[opt^1][i]=path[opt][i];
60         rep(i,a,b) path[opt^1][i]=path[opt][a-i+b];
61         rep(i,b+1,n+1) path[opt^1][i]=path[opt][i];
62     }else{
63         rep(i,1,a-1) path[opt^1][i]=path[opt][i];
64         path[opt^1][a]=path[opt][b];
65         rep(i,a+1,b) path[opt^1][i]=path[opt][i-1];
66         rep(i,b+1,n+1) path[opt^1][i]=path[opt][i];
67     }
68 }
69 void cal(){
70     int ans,cnt=0;
71     srand(time(NULL));
72     rep(i,1,n) path[opt][i]=i;path[opt][n+1]=1;ans=pre=f(opt);
73     while(T>T_min){
74         cnt++;if(cnt>1e6) break;
75         newway();
76         tmp=f(opt^1);del=tmp-pre;
77         ans=min(ans,tmp);
78         if(del<0){
79             opt^=1;pre=tmp;
80         }else if(rand()*rand()/32767.0/32767.0<pow(e,-del/T)){
81             opt^=1;pre=tmp;
82         }
83         T*=R;
84     }
85     cout<<cnt<<endl;
86     printf("%d\n",ans);
87 }
88 int main(){
89     freopen("#input.txt","r",stdin);
90     //freopen("#output.txt","w",stdout);
91     n=readint();
92     rep(i,1,n){
93         X[i].x=readint();X[i].y=readint();
94     }
95     cal();
96     fclose(stdin);
97     //fclose(stdout);
98     return 0;
99 }
TSP

 

posted @ 2017-11-24 23:53  ChenThree  阅读(194)  评论(0编辑  收藏  举报