模拟退火

模拟退火

 

 

基本思路(Main Thoughts):

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

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

  形象的比喻如下:

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

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

 

实现步骤(Implementation Steps):

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

    a) 优 直接取代

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

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

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

模板(Code):

  //by 苍梧

   模拟退火_第1张图片

时间&空间复杂度(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\n",ANS);
58     }
59     return 0;
60 }
View Code

 

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

 

你可能感兴趣的:(模拟退火)