zoukankan      html  css  js  c++  java
  • 模拟退火

    模拟退火

    模拟退火时有三个参数,分别是初始温度T0 、降温系数Δ (delta)终止温度 Tk 。

    其中,T0 是一个比较大的数,Δ 是一个略小于 1 的正数,Tk 是一个略大于 0 的正数。

    我们先让温度 T=T0 ,然后每次降温时T=TΔ ,直到 TTk 为止。

    我们探讨一下SA的玄学调参。

    Q:答案不是最优的怎么办?

    A:有以下几种方法:调大Δ (delta)、调大T0 、调小Tk ,以及多跑几遍SA。

    当您的程序跑的比较快时,可以选择多跑几遍SA,或者调大 Δ ,从而增大得到最优解的概率。

    调大T0 和调小Tk 也可以,而且时间并不会增大太多

    大致过程如下

    可以看出,随着温度的降低,解逐渐稳定下来,并逐渐集中在最优解附近。

    如何生成新解

    • 坐标系内:随机生成一个点,或者生成一个向量。
    • 序列问题: random\_shufflerandom_shuffle 或者随机交换两个数。
    • 网格问题:可以看做二维序列,每次交换两个格子即可。

    P1337 [JSOI2004]平衡点 / 吊打XXX

    模板代码:

     1 #include <bits/stdc++.h>
     2 #define delta 0.996 // 徐徐降温
     3 
     4 using namespace std;
     5 
     6 struct node {
     7     int x,y,w;
     8 }object[2005];// 存物体的坐标和重量
     9 int n;
    10 double ansx,ansy,answ; // 最终答案
    11 
    12 double energy( double x, double y ){//根据题意变化, 能量总和越小越稳定( 即越接近正确答案 )
    13     double r=0,dx,dy;
    14     for ( int i=1; i<=n; i++ ) {
    15         dx = x-object[i].x;
    16         dy = y-object[i].y;
    17         r += sqrt(dx*dx+dy*dy)*object[i].w;
    18     }
    19     return r;
    20 }
    21 
    22 void sa(){
    23     double t = 3000; // 温度足够高
    24     while ( t>1e-15 ) {
    25         double ex = ansx + (rand()*2-RAND_MAX)*t; // 随机产生新答案.
    26         double ey = ansy + (rand()*2-RAND_MAX)*t;
    27         double ew = energy(ex,ey);
    28         double de = ew - answ;
    29         if ( de<0 ) { // 新答案能量低,更稳定
    30             ansx = ex;
    31             ansy = ey;
    32             answ = ew;
    33         }
    34         else if ( exp(-de/t)*RAND_MAX>rand() ) { // 否则根据多项式概率接受
    35             ansx = ex;
    36             ansy = ey;
    37         }
    38         t *= delta;
    39     }
    40 }
    41 
    42 void solve() // 多跑几遍退火,增加得到最优解的概率
    43 {
    44     sa();sa();sa();sa();
    45 }
    46 
    47 int main()
    48 {
    49     cin >> n;
    50     for ( int i=1; i<=n; i++ ) {
    51         scanf("%d %d %d",&object[i].x,&object[i].y,&object[i].w);
    52         ansx += object[i].x;
    53         ansy += object[i].y;
    54     }
    55     ansx/=n; ansy/=n; // 以平均值作为初始答案
    56     answ = energy(ansx,ansy);
    57     solve();
    58     printf("%.3f %.3f
    ",ansx,ansy);
    59 
    60     return 0;
    61 }
  • 相关阅读:
    General part中方向选取的作用
    mount part中位置的作用
    关于zero pivot
    Revit二次开发示例:ModelessForm_ExternalEvent
    elasticsearch6.4 memory locking requested for elasticsearch process but memory is not locked
    百度网盘 http://pandownload.com/index.html
    MySQL 5.7主从复制从零开始设置及全面详解——实现多线程并行同步,解决主从复制延迟问题!
    linux 系统优化
    服务器cpu过高修复:操作系统内核bug导致
    Jvm中时区设置方式
  • 原文地址:https://www.cnblogs.com/wsy107316/p/12207573.html
Copyright © 2011-2022 走看看