• 模拟退火


    模拟退火

    概述:求解最优化问题,example:TSP,函数max/min

    一、理论:

    算法认识:基于爬山算法(每次朝着当前上升最快的方向爬,但是初始化不同可能会得到不同的局部最优值,模拟退火可能跳出局部最优值)

    流程:初始高温-->温度降低-->终止在低温

    本质:贪心+随机化

    二、算法描述:

    [egin{cases} ext{if f[x+1] > f[x] 移动后更优,那么总是移动} \ ext{if f[x+1]< f[x]移动后更差,那么以一定的概率移动,并且这个概率随时移动} end{cases} ]

           $P(dE)=exp(frac{dE}{kT})$
    

    dE<0,说明:温度越高出出现的能量差为dE的降温概率越大,温度越低

    伪CODE:

    /*
    F(h[x]) 为估价函数
    h[x] 为当前的状态
    delta 控制降温的快慢
    T 系统的温度,初始温度比较高
    T_min 温度的下限,若温度达到T_min,停止搜索
    */
     while(T>T_min){
      y=x+rand()*t;
      dE=F(h[y])-F(h[x]);
      if(dE>=0)
         h[y]=h[x];//转移更优,那么转移
      else {
         //dE的越大,那么次语句的条件成立概率越大,T越小exp(dE/T)越小
       if(exp(dE/T)>random(0,1)){//exp(dE/T)表示以e(自然常数)为底的(dE/T)次方
            h[y]=h[x];
       }
      }
      T*=delta//delta 一般取0.98/0.99
     }
    

    三·、经典例题:

    1.[JSOI2004]吊打XXX

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<ctime>
    #include<cstdlib>
    using namespace std;
    const int MAXX=1010;
    int x[MAXX],y[MAXX],w[MAXX];
    double ansx,ansy;
    int sumx,sumy,n;
    inline double cal(double x0,double y0){
     double ans=0;
     for(int i=1;i<=n;++i){
      double xx=(double)x[i]-x0;
      double yy=(double)y[i]-y0;
      ans+=(double)sqrt(xx*xx+yy*yy)*w[i];
     }
     return ans;
    }
    inline void SA(){
     ansx=(double)sumx/n;
        ansy=(double)sumy/n;
     double t=1926;
     double t_min=1e-14;
     double delta=0.98;
     while(t>t_min){
      double randx=ansx+(rand()%20000-10000)*t;
      double randy=ansy+(rand()%20000-10000)*t;
      double dE=cal(randx,randy)-cal(ansx,ansy);
      if(dE<=0){
       ansx=randx;
       ansy=randy;
      }else {
       if(exp(-dE/t)*RAND_MAX>rand()){
        ansx=randx;
        ansy=randy;
       }
      }
      t*=delta;
     }
    }
    int main(){
     srand(time(NULL));
     scanf("%d",&n);
     for(int i=1;i<=n;++i){
      scanf("%d%d%d",&x[i],&y[i],&w[i]);
      sumx+=x[i];
      sumy+=y[i];
     }
        SA();SA();SA();
        printf("%.3lf %.3lf",ansx,ansy);
        return 0;
    }
    /*
    INPUT:
    3
    0 0 1
    0 2 1
    1 1 1
    OUTPUT:
    0.577 1.000
    */
    
  • 相关阅读:
    spring——依赖注入
    jsp课程笔记(一)
    spring入门程序(一)
    关于java项目导入到eclipse无法访问的问题
    lnmp一键下载及安装
    spring配置文件application.Context配置文件的约束信息快速获取
    Tomcat下载与安装
    Nginx配置java项目在Tomcat下访问
    webstrom快捷键合集
    Ubuntu 开启SSH服务以及有关设置:安装,指定端口号、免密登录、远程拷贝
  • 原文地址:https://www.cnblogs.com/ARTlover/p/9538408.html
Copyright © 2020-2023  润新知