• 随机搜索与模拟退火


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

    开坑.

     

    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

     

  • 相关阅读:
    【Java学习笔记】<集合框架>Iterator的子接口ListIterator
    【Java学习笔记】<集合框架>List特有的取出方式之一
    【Java学习笔记】集合框架Ⅱ
    【Java学习笔记】集合框架Ⅰ
    【PS】Ⅱ图像合成与渐变工具笔记
    【PS】Ⅰ基础及选框工具笔记
    [PS]简单的智能电视制作案例
    Spring中线程池的使用
    SpringBoot 多线程
    solr DIH 设置定时索引
  • 原文地址:https://www.cnblogs.com/DragoonKiller/p/4411833.html
Copyright © 2020-2023  润新知