本篇参考了一下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
例题:
正解是个物理题。不过模拟退火也能做,算一下势能,如果平衡的话势能会最小,如果没到最小那么向势能指向方向移动更优,然后模拟退火一波,不断调整即可。
两部分的话默认前一半是第一部分的,后面是第二部分,然后算一下两个的差,随机再修改交换,退火就完事了。虽说折半搜索好像也可以。
这个题似乎用退火最容易过,随机拿出来一个放到其他地方,开始可以找最低的位置放,其次可以随机调整其他的,复杂度很低,一发就过了。