模拟退火入门

什么是模拟退火?

以下是来自百度百科的解释:

模拟退火算法(Simulate Anneal,SA)是一种通用概率演算法,用来在一个大的搜寻空间内找寻命题的最优解。模拟退火是由S.Kirkpatrick, C.D.Gelatt和M.P.Vecchi在1983年所发明的。V.Černý在1985年也独立发明此演算法。模拟退火算法是解决TSP问题的有效方法之一。
模拟退火的出发点是基于物理中固体物质的退火过程与一般组合优化问题之间的相似性。模拟退火算法是一种通用的优化算法,其物理退火过程由加温过程、等温过程、冷却过程这三部分组成。

博主自己的理解:

首先要说明,这是一个建立在随机基础上的,不一定正确的算法。但是模拟退火在OI中是一种在最优化问题中骗分的好方法,对于一些奇奇怪怪的多元函数也可以用这个方法来求解。
模拟退火,顾名思义就是模拟退火的过程,也就是模拟所有高温杂乱的原子到低温稳定的原子的过程,通常是先让目标随机大幅度移动,在此过程中不断更新答案,最后慢慢到达稳定的答案。通过多次重复的此过程,到达最优解。

根据热力学规律并结合计算机对离散数据的处理, 我们定义: 如果当前温度为 T , 当前状态与新状态之间的能量差为 ΔE
, 则发生状态转移的概率为:
P(ΔE)=eΔEkT
显然如果 ΔE为正的话转移是一定会成功的, 但是对于 ΔE<0
我们则以上式中计算得到的概率接受这个新解.
然后我们维护温度 T即可. 这里我们有三个参数: 初温 T0 , 降温系数 d , 终温 Tk一般 T0是个比较大的数, d 是个接近 1 但是小于 1 的值, Tk 是个接近 0的正值.首先让温度 T=T0然后进行一次转移尝试, 然后让 T=dT当 T<Tk
时模拟退火过程结束, 当前解作为最优解.

看起来好像很难理解?

请看例题

解释一下此例题中一些细节:

1.安利一个模拟退火的模板:

void fire()//模拟退火
{
    先定义一个温度t(看心情咯)。
    while(t>1e-14)(视题目而定)
    {
        t*=delta//降温(delta的值看心情,一般是0.99左右的数)
        x=rand()*t(随机出新的解用,t控制变动的范围)
        newans=getans(x)(得到新解的ans)
        if(判断是否更新)  then 更新答案
        else    if(随机判断是否更新) then 更新目标
        (有一定概率更新以确保不会卡在区域最优解里面)
    }
}

2.T在程序中的作用:


1.可以说T是整个函数的核心部分,T的处理通常决定了退火的成功与否。

2.首先T一个类似cnt的数,表示温度是否降到0(答案是否趋于稳定)

3.在随机新解时T决定了新解的波动范围,温度越低波动越小,这样可以更大的概率更精确地命中最优解(形象来说就是在温度越低时原子波动越小)。

4.T还影响了是否更新一个不是优于当前解的目标,例如刚刚的题目中:
if(exp(-DE/t)*RAND_MAX>rand())

注意事项:


1.关于t和delta值的确定,如果太大会导致降温太快而错过最优解,但太小又会导致时间超时,所以建议用极限数据测试一下时间。希望大家多做几个类似题目感受,才能更好把握。

2.是否更新不是最更解的目标,需要通过热力学公式P(ΔE)=eΔEkT来灵活运用。

总结

其实在上面的例子中也可以体现出来, 这个算法的要点在于新解的选取以及参数的调整...实际上利用退火过程的性质大胆随机再配合调参经验一般效果拔群OwO,用熟了之后绝对是骗分利器,但是作为一个随机化算法并不一定能找到最优解。

推荐题目


POJ 2069 最小包含球问题求解

洛谷 2503 均分数据

洛谷 3936 Coloring

猜你喜欢

转载自www.cnblogs.com/Le-mon/p/9072859.html