模拟退火学习笔记

本篇参考了一下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]均分数据

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

原文地址:https://www.cnblogs.com/--BLUESKY007/p/10677025.html