zoukankan      html  css  js  c++  java
  • 模拟退火学习笔记

    本篇参考了一下Chhokmah小姐姐的博客

    概念:

    其实基于爬山,爬山是一个非常笨的贪心,爬山本质是按照一个方向找最高点,不过找到一个比两边都高的点就会停下,这显然是错的,结果却由此诞生了一个模拟退火。

    模拟退火((Simulate Anneal,SA))是一种通用概率演算法,用来在一个大的搜寻空间内找寻命题最优解,是解决(TSP)问题的有效方法之一。其出发点基于物理中固体物质的退火过程。模拟退火是一种通用的优化算法,其物理退火过程由加温过程、等温过程、冷却过程三部分组成。

    基本上就是选一个初解,然后简单变化得到新解,如果可以更新就更新,不能就按概率更新,然后持续操作,最后收敛到最优解。

    来自(Chhokmah)的解释:

    我们还是爬山算法,还是判断当前答案是不是更优,但是我们加的操作是:如果不是更优,那么我们就来一个继续迭代的概率,这个概率会随着整体的程序越变越小。
    
    做一个比喻:
    爬山算法是一个瞎的兔子,要跳到最高的山峰,他跳着跳着发现路开始向下了,他就不跳了。
    模拟退火是一个喝醉的兔子,要跳到最高的山峰,他一直在跳,越跳越清醒,最后调到了最高的地方。
    

    参数:

    • (T_0):冷却初始温度
    • (T):当前的温度
    • (T_k):冷却目标温度
    • (alpha):表示温度的降低后相对原温度的比值,一般是(0.95sim0.99),让物体慢慢降温
    • (x):当前解
    • (x'):当前的解
    • (Delta):表示答案的变化值

    每次比较差值随机出来的答案是不是在范围内,越到后面随机的答案就越小。

    陷入局部最优增大(T_0)(alpha),精度不够减小(T_k)。有的时候也会采取在(T)降至(T_k)以下时多次寻找新答案,感觉上会提高正确性,这一点感性理解一下,毕竟都是玄学。

    实现:

    • 由一个产生函数从当前解中产生一个位于解空间的新解,然后由当前解通过简单变换产生新解。

    伪代码:

    生成初解x
    while(T>Tk)
        随机生成新解x'
        delta=f(x')-f(x)
        if 答案更优
            更新最优答案
        else if exp(-delta/T)>rand(0,1)
            更新当前答案
        T=T*alpha
    

    例题:

    P1337 [JSOI2004]平衡点 / 吊打XXX

    正解是个物理题。不过模拟退火也能做,算一下势能,如果平衡的话势能会最小,如果没到最小那么向势能指向方向移动更优,然后模拟退火一波,不断调整即可。

    P3878 [TJOI2010]分金币

    两部分的话默认前一半是第一部分的,后面是第二部分,然后算一下两个的差,随机再修改交换,退火就完事了。虽说折半搜索好像也可以。

    P2503 [HAOI2006]均分数据

    这个题似乎用退火最容易过,随机拿出来一个放到其他地方,开始可以找最低的位置放,其次可以随机调整其他的,复杂度很低,一发就过了。

  • 相关阅读:
    MFC之界面提示(CToolTipCtrl类)
    Windows的三种坐标系:屏幕坐标系,非客户区坐标系,客户区坐标系
    【数据库】insert语句
    【js】v-for 的一些用法 :class {{index}}
    jQuery查找选中的checkbox个数
    limit offset
    http状态码
    Whitelabel Error Page
    【Mybatis】Mybatis generator的使用
    【CSS】Bootstrap 图标
  • 原文地址:https://www.cnblogs.com/--BLUESKY007/p/10677025.html
Copyright © 2011-2022 走看看