随机搜索与模拟退火

这是我见过的最神的乱搞!

开坑.

 

AC POJ 2420

  1 #include <cstdio>
  2 #include <fstream>
  3 #include <iostream>
  4  
  5 #include <cstdlib>
  6 #include <cstring>
  7 #include <algorithm>
  8 #include <cmath>
  9  
 10 #include <queue>
 11 #include <vector>
 12 #include <map>
 13 #include <set>
 14 #include <stack>
 15 #include <list>
 16  
 17 typedef unsigned int uint;
 18 typedef long long int ll;
 19 typedef unsigned long long int ull;
 20 typedef double db;
 21  
 22 using namespace std;
 23  
 24 inline int getint()
 25 {
 26     int res=0;
 27     char c=getchar();
 28     bool mi=false;
 29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
 30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
 31     return mi ? -res : res;
 32 }
 33 inline ll getll()
 34 {
 35     ll res=0;
 36     char c=getchar();
 37     bool mi=false;
 38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
 39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
 40     return mi ? -res : res;
 41 }
 42  
 43 db eps=1e-20;
 44 inline bool feq(db a,db b)
 45 { return fabs(a-b)<eps; }
 46 
 47 template<typename Type>
 48 inline Type avg(const Type a,const Type b)
 49 { return a+((b-a)/2); }
 50 
 51 
 52 //==============================================================================
 53 //==============================================================================
 54 //==============================================================================
 55 //==============================================================================
 56 
 57 
 58 
 59 int n;
 60 
 61 db x[105];
 62 db y[105];
 63 
 64 inline db dis2(db x1,db y1,db x2,db y2)
 65 { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); }
 66 
 67 inline db getdist(db X,db Y)
 68 {
 69     db l=0;
 70     for(int i=0;i<n;i++)
 71     l+=dis2(X,Y,x[i],y[i]);
 72     return l;
 73 }
 74 
 75 int _cnt=0;
 76 int rands=0;
 77 inline int getrand()
 78 {
 79     _cnt++;
 80     if(_cnt==32768*32768) srand(++rands);
 81     return rand()+32768*rand();
 82 }
 83 
 84 inline db dbrand()
 85 { return (db)(rand()+32768*rand())/(db)(32768*32768); }
 86 
 87 db res;
 88 
 89 
 90 int main()
 91 {
 92     srand(rands);
 93     
 94     while(scanf("%d",&n)>0)
 95     {
 96         for(int i=0;i<n;i++)
 97         {
 98             x[i]=getint();
 99             y[i]=getint();
100         }
101         
102         //Searching.
103         db cx=0,cy=0;
104         res=getdist(cx,cy);
105         
106         db T=1e5;
107         
108         while(T>=1e-2)
109         {
110             db rx=cx+(dbrand()-0.5)*T*2.0;
111             db ry=cy+(dbrand()-0.5)*T*2.0;
112             db dist=getdist(rx,ry);
113             db d=res-dist;
114             if(d>0)
115             {
116                 res=dist;
117                 cx=rx;
118                 cy=ry;
119             }
120             T*=0.98;
121         }
122         
123         printf("%.0f
",res);
124     }
125     
126     
127     return 0;
128 }
View Code

注意程序写的并不是完整的模拟退火....我们只接受最优参数,而完全不接受那些比较差的参数......

但是这里的搜索范围使用了类似的温度变量T....

db rx=cx+(dbrand()-0.5)*T*2.0;
db ry=cy+(dbrand()-0.5)*T*2.0;

这应该也算模拟退火吧(模拟分子的不规则运动)........反正能A掉这个题........

 

 

AC POJ 1379

  1 #include <cstdio>
  2 #include <fstream>
  3 #include <iostream>
  4  
  5 #include <cstdlib>
  6 #include <cstring>
  7 #include <algorithm>
  8 #include <cmath>
  9  
 10 #include <queue>
 11 #include <vector>
 12 #include <map>
 13 #include <set>
 14 #include <stack>
 15 #include <list>
 16  
 17 typedef unsigned int uint;
 18 typedef long long int ll;
 19 typedef unsigned long long int ull;
 20 typedef double db;
 21  
 22 using namespace std;
 23  
 24 inline int getint()
 25 {
 26     int res=0;
 27     char c=getchar();
 28     bool mi=false;
 29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
 30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
 31     return mi ? -res : res;
 32 }
 33 inline ll getll()
 34 {
 35     ll res=0;
 36     char c=getchar();
 37     bool mi=false;
 38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
 39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
 40     return mi ? -res : res;
 41 }
 42  
 43 db eps=1e-20;
 44 inline bool feq(db a,db b)
 45 { return fabs(a-b)<eps; }
 46 
 47 template<typename Type>
 48 inline Type avg(const Type a,const Type b)
 49 { return a+((b-a)/2); }
 50 
 51 
 52 //==============================================================================
 53 //==============================================================================
 54 //==============================================================================
 55 //==============================================================================
 56 
 57 int n;
 58 
 59 db xlim,ylim;
 60 
 61 db x[1050];
 62 db y[1050];
 63 
 64 inline db dis2(db x1,db y1,db x2,db y2)
 65 { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); }
 66 
 67 inline db getdist(db X,db Y)
 68 {
 69     db l=1e40;
 70     for(int i=0;i<n;i++)
 71     l=min(l,dis2(X,Y,x[i],y[i]));
 72     return l;
 73 }
 74 
 75 int _cnt=0;
 76 int rands=0;
 77 inline int getrand()
 78 {
 79     _cnt++;
 80     if(_cnt==32768*32768) srand(++rands);
 81     return rand()+32768*rand();
 82 }
 83 
 84 inline db dbrand()
 85 { return (db)(rand()+32768*rand())/(db)(32768*32768); }
 86 
 87 db res;
 88 
 89 int main()
 90 {
 91     srand(rands);
 92     
 93     int T=getint();
 94     while(T--)
 95     {
 96         scanf("%lf%lf%d",&xlim,&ylim,&n);
 97         for(int i=0;i<n;i++)
 98         scanf("%lf%lf",x+i,y+i);
 99         
100         //Searching.
101         db cx=0,cy=0;
102         res=getdist(cx,cy);
103         
104         db T=1e4;
105         while(T>=1e-4)
106         {
107             db rx=cx+(dbrand()-0.5)*2.0*T;
108             db ry=cy+(dbrand()-0.5)*2.0*T;
109             
110             rx=max(0.0,rx); rx=min(xlim,rx);
111             ry=max(0.0,ry); ry=min(ylim,ry);
112             
113             db dist=getdist(rx,ry);
114             if(dist>res)
115             {
116                 res=dist;
117                 cx=rx;
118                 cy=ry;
119             }
120             T*=0.999;
121         }
122         
123         printf("The safest point is (%.1f, %.1f).
",cx,cy);
124     }
125     
126     return 0;
127 }
View Code

跟上一题差不多,调一下参数加一点限制就交了.....然后就A了..... 313ms.....

依然是不带概率回退的参数搜索.......

T*0.999可以调整到T*0.998,这样以后总的运行时间是172ms...

 

AC BZOJ 3680

不带概率接受的模拟退火

  1 #include <cstdio>
  2 #include <fstream>
  3 #include <iostream>
  4  
  5 #include <cstdlib>
  6 #include <cstring>
  7 #include <algorithm>
  8 #include <cmath>
  9  
 10 #include <queue>
 11 #include <vector>
 12 #include <map>
 13 #include <set>
 14 #include <stack>
 15 #include <list>
 16  
 17 typedef unsigned int uint;
 18 typedef long long int ll;
 19 typedef unsigned long long int ull;
 20 typedef double db;
 21  
 22 using namespace std;
 23  
 24 inline int getint()
 25 {
 26     int res=0;
 27     char c=getchar();
 28     bool mi=false;
 29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
 30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
 31     return mi ? -res : res;
 32 }
 33 inline ll getll()
 34 {
 35     ll res=0;
 36     char c=getchar();
 37     bool mi=false;
 38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
 39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
 40     return mi ? -res : res;
 41 }
 42 
 43 //==============================================================================
 44 //==============================================================================
 45 //==============================================================================
 46 //==============================================================================
 47 
 48 
 49 db frand()
 50 { return db(rand()+rand()*32768)/(32768*32768-1); }
 51 
 52 struct point
 53 {
 54     db x,y;
 55     point(){ x=y=0; }
 56     point(db x,db y):x(x),y(y){ }
 57     
 58     point operator+(point f)
 59     { return point(x+f.x,y+f.y); }
 60     
 61     point operator-(point f)
 62     { return point(x-f.x,y-f.y); }
 63     
 64     point operator()(point f)
 65     { return f-*this; }
 66     
 67     point operator*(db k)
 68     { return point(k*x,k*y); }
 69     
 70     db len()
 71     { return sqrt(x*x+y*y); }
 72 };
 73 
 74 
 75 int n;
 76 
 77 point a[10050];
 78 db w[10050];
 79 
 80 db getdist(point x)
 81 {
 82     db res=0.0;
 83     for(int i=0;i<n;i++)
 84     res+=x(a[i]).len()*w[i];
 85     return res;
 86 }
 87 
 88 int main()
 89 {    
 90     srand(1782);
 91     
 92     n=getint();
 93     for(int i=0;i<n;i++)
 94     scanf("%lf%lf%lf",&a[i].x,&a[i].y,&w[i]);
 95     
 96     //simulate anneal
 97     db B=1e10;
 98     db T=B;
 99     db R=0.992;
100     point res(0,0);
101     db dist=getdist(res);
102     while(T>=1e-4)
103     {
104         point cur(res.x+(frand()*2.0-1.0)*T,res.y+(frand()*2.0-1.0)*T);
105         db cd=getdist(cur);
106         
107         if(cd<dist)
108         {
109             res=cur;
110             dist=cd;
111         }
112         
113         T*=R;
114     }
115     
116     printf("%.3f %.3f
",res.x,res.y);
117     
118     return 0;
119 }
View Code

加上了概率接受以后就再也没法A了TAT

而且好像T的初始值要设到非常非常大否则精度很难搞?

 

 

 


具体算法参考

http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

 

原文地址:https://www.cnblogs.com/DragoonKiller/p/4411833.html