• 模拟退火


    模拟退火


     

     

    基本思路(Main Thoughts):

      模拟退火是一种比爬山算法更加优(乱)秀(搞)的贪心法

      它基于爬山算法点的有点就是可以下降 不过越后几率越低,这样就能找到更高的山峰.

      形象的比喻如下:

        爬山算法:兔子爬最高的山峰.

        模拟退火:兔子喝醉了,乱爬,在爬的过程中逐渐清醒,最后爬到高峰.  

     

    实现步骤(Implementation Steps):

    1. 设定初始温度 温度最小值 起始位置,转移法
    2. 随机转移 然后判断该步后的决策与之前决策的优劣

        a) 优 直接取代

        b) 劣 则以一定概率移动 不过这个概率还会慢慢减少

      3.至于那个一定概率 大概就是用现在与原来的差值用log(差的绝对值/温度)或者exp(差的绝对值的相反数/温度)函数与一个rand 的值比较.

      4.概率慢慢减少就是温度慢慢下降 

    模板(Code):

      //by 苍梧

       

    时间&空间复杂度(Time & Memory Complexity):

      空间:O(?)

      时间:O(?)

    主要用途&优缺点(Main Applications & Advantages & Disadvantages):

      主要用途:乱搞

      优点:比爬山算法更靠谱?

      缺点:有时比爬山算法还不靠谱?

    推荐题目&数据(Recommendatory Problems & Data) :

      POJ 2420 做一道感受一下气氛吧。。

      

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<ctime>
     6 
     7 using namespace std;
     8 
     9 #define maxn 101
    10 
    11 #define eps 1e-4
    12 
    13 int n;
    14 
    15 struct poi{
    16     int x,y;
    17 }p[maxn];
    18 
    19 double sqr(double x){return x*x;}
    20 
    21 double dis(double X,double Y,poi P){return sqrt(sqr(X-P.x)+sqr(Y-P.y));}
    22 
    23 double sumdis(double xx,double yy)
    24 {
    25     double sum=0;
    26     for(int i=1;i<=n;i++)
    27     sum+=dis(xx,yy,p[i]);
    28     return sum;
    29 }
    30 
    31 int main()
    32 {
    33     freopen("t.in","r",stdin);
    34     while(scanf("%d",&n)!=EOF)
    35     {
    36     srand(n);
    37     double xx=0,yy=0;
    38     for(int i=1;i<=n;i++)
    39         scanf("%d%d",&p[i].x,&p[i].y),xx+=p[i].x,yy+=p[i].y;
    40     xx/=n,yy/=n;
    41     double T=100000,ANS=sumdis(xx,yy);
    42     while(T>0.02)
    43     {
    44         double sum=0,x,y,t=(rand()%10000)/10000.0;
    45         for(int i=-1;i<=1;i++)
    46         for(int j=-1;j<=1;j++)
    47         {
    48             x=xx+T*i;             
    49             y=yy+T*j;
    50             double D=sumdis(x,y);
    51             if(D+eps<ANS)ANS=D,xx=x,yy=y;
    52             else if(log((D-ANS)/T)>t+eps)ANS=D,xx=x,yy=y;
    53             
    54         }
    55         T*=t;
    56     }
    57     printf("%.0lf
    ",ANS);
    58     }
    59     return 0;
    60 }
    View Code

      貌似还和计算几何有关?以后再看吧。。

     

  • 相关阅读:
    C嵌入汇编
    App 运营 推广相关
    POJ 3904 Sky Code
    数组的复制与动态扩展算法
    另类病毒的自删除方法
    oracle触发器中增删改查本表
    POJ 2773 Happy 2006 数学题
    Android手机便携式wifi的使用及无线数据传输(主要针对XP系统)
    Find the minimum线段树成段更新
    使用visual c++ 2005编译64位可执行文件
  • 原文地址:https://www.cnblogs.com/tuigou/p/5052299.html
Copyright © 2020-2023  润新知