模拟退火

没时间复习这个了,暂时用来当模板,以后再来写下自己的模板

 1 #include <iostream>  
 2 #include <algorithm>  
 3 #include <cstdlib>  
 4 #include <cmath>  
 5 #include <ctime>  
 6 #include <cstdio>  
 7 using namespace std;  
 8 struct Point  
 9 {  
10     double x,y;  
11 }a[105];  
12 int n;  
13 double dis(double x,double y,Point a)  
14 {  
15     return sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y));  
16 }  
17 double Getans(double x,double y)  
18 {  
19     double ans=0.0;  
20     for (int i=1;i<=n;i++)  
21         ans+=dis(x,y,a[i]);  
22     return ans;  
23 }  
24 int main()  
25 {  
26     //srand((unsigned)time(0));  
27     while (scanf("%d",&n)!=EOF)  
28     {  
29         double x=0,y=0,t=1e5,ans=1e20;  
30         for (int i=1;i<=n;i++)  
31         {  
32             scanf("%lf%lf",&a[i].x,&a[i].y);  
33             x+=a[i].x,y+=a[i].y;  
34         }  
35         x/=n,y/=n;  
36         ans=Getans(x,y);  
37         while (t>0.02)  
38         {  
39             double tx,ty;  
40             tx=0,ty=0;  
41             for (int i=1;i<=n;i++)  
42             {  
43                 tx+=(a[i].x-x)/dis(x,y,a[i]);  
44                 ty+=(a[i].y-y)/dis(x,y,a[i]);  
45             }  
46             double tmp=Getans(x+tx*t,y+ty*t);  
47             if (tmp<ans)  
48                 ans=tmp,x+=tx*t,y+=ty*t;  
49             else if (t>(double)(rand()%100000))  
50                 ans=tmp,x+=tx*t,y+=ty*t;  
51             t*=0.9;  
52         }  
53         printf("%.0f\n",ans);  
54     }  
55     return 0;  
56 } 

 

posted @ 2017-10-15 19:53  weeping  阅读(171)  评论(0编辑  收藏  举报