模拟退火算法超详细教程,请收好!
预计读完 5 分钟
今天,小编将带大家学习一个经典算法——模拟退火算法。
以下为本文框架:
一、什么是模拟退火算法?
模拟退火算法(simulated annealing,SA)来源于固体退火原理,是一种基于概率的算法。
算法思想为:先从一个较高的初始温度出发,逐渐降低温度,直到温度降低到满足热平衡条件为止。在每个温度下,进行n轮搜索,每轮搜索时对旧解添加随机扰动生成新解,并按一定规则接受新解。
打个比方:
有一只兔子在山上,要去山脚下,但它喝醉了。于是它就胡乱瞎蹦跶,有可能直接蹦跶到山脚下,有可能蹦跶到更高的另一座山,也可能跳到某个山谷里。等它醒酒后,它就慢慢地往低处走。这就是模拟退火。
为更好理解模拟退火算法的具体步骤,我们来举个栗子。
假设初始温度为1000℃,温度衰减系数α = 0.98,热平衡条件为温度小于T℃。
模拟退火算法本质是双层循环,外层循环(上图左侧彩色模块)控制温度由高向低变化,温度计算公式 , 为取值在[0, 1]上的温度衰减系数,如0.95;内层循环(上图右侧黑色模块)中,温度固定,对旧解添加随机扰动得到新解,并按一定规则接受新解。内层循环的迭代次数称为马尔科夫链长度,如上图中的马尔科夫链的长度为1000.
二、模拟退火算法有什么优点?
模拟退火算法的优点在于:不管函数形式多复杂,模拟退火算法更有可能找到全局最优解。
举个栗子:寻找目标函数f = x + 10 sin(3x) + cos(x) 在[0, 9]范围内的最小值。
从函数图像可以看到,该函数在[0, 9]范围内有多个“坑”,也就是局部最小值,全局最小值位于[1, 2]范围上的“坑”内。如果用梯度下降法来求解全局最小值,若学习率设置得不合理很容易掉进某个坑内出不来,比如这样↓
而模拟退火算法相对来说不会那么容易陷入局部最优解。
我们把模拟退火算法求出的解看成是一个红色的小球,可以看到,随着温度的下降,这个小球一直反复横跳;直到温度较低时,这个小球才在最小值附近稳定下来。
那模拟退火算法是怎么跳出局部最优值的呢?
关键点在于模拟退火算法对较差的旧解的处理上。
在任一温度时,对初始解添加随机扰动产生新解,若新解的目标函数值优于旧解,则接受新解;若新解差于旧解,则按一定概率接受旧解,从而有一定概率跳出局部最优解,找到全局最优解。
而这个“一定概率”也不是瞎取的,这个概率的计算公式为: 。其中, , 为新解的目标函数值,为旧解的目标函数值,T为当前的温度,k为玻尔兹曼常数。温度越高,算法接受新解的概率越高。这个根据一定概率选择是否接受差解的方法叫做Metropolos准则。
三、模拟退火算法有什么缺陷?
模拟算法虽好,但也存在一些缺点。
1. 初始温度和马尔科夫链长度的设置问题
从理论上来说,初始温度越高,且马尔科夫链越长,算法搜索越充分,得到全局最优解的可能性越大,但这也意味着需要耗费更多的计算时间。接下来我们采取控制变量法做个实验来验证一下这个结论。
从图中可以看到,随着迭代次数的增加,温度逐渐降低,马尔科夫链长度1000的模拟退火算法在迭代100多次之后搜索到了全局最小值,而马尔科夫链长度100的模拟退火算法则无法搜索到全剧最小,困在局部最小的坑里出不去了。这说明,马尔科夫链长度越长,模拟退火算法搜索越充分,更容易搜索到全局最优解,但相应的搜索时间会更长。
再来看一下初始温度T0对结果的影响。
可以看到,初始温度100和初始温度1000的两个模拟退火算法都能搜索到全局最小值,初始温度1000的搜索到全剧最小的速度稍快一点。
2. 退火速度问题
温度衰减系数越小,温度下降越快,对应的迭代次数也就越少,算法搜索的次数也就越少,因此导致了上图中温度衰减系数0.9的模拟退火算法没有搜索到最优解。
另外,越到后期,温度衰减得越慢,但是我们可以将温度衰减系数设置为动态的,即随着温度下降,温度衰减系数也随之变小,如 ,以加快后期温度下降,加速算法收敛。
总结一下,关键参数是马尔科夫链长度和温度衰减系数,马尔科夫链越长,且温度衰减系数越接近于1,模拟退火算法搜索越充分,越有可能找到全局最优解,但相应地也会增加算法搜索时间。当解空间的维度较高时,模拟退火算法要想搜索到全局最优解需要耗费大量时间,这是模拟退火算法的一个主要缺点。
四、应用推广
模拟退火算法在优化类问题的应用非常广泛,可以对上文的代码进行修改以应用到其他问题。但是具体问题具体分析,除了必要的数据更改之外,特别要注意以下3点:
例如,将问题升级到2维,寻找目标函数f = sin(x) + cos(y) 在[0, 6]×[0, 6]范围内的最小值。
可以看到,随着迭代次数的增加,模拟退火算法慢慢逼近目标函数的全局最小值,并最终找到了目标函数在[0, 6]×[0, 6]范围内的全局最小值-2,最小值点位于(4.7162, 3.1358)。