模拟退火,Simulated Annealing,SA

模拟退火算法名字的由来是其参考了金属冶炼的退火过程

 

 

模拟退火可以解决TSP旅行商问题

 

引入

当我们遇到一个爬山问题的时候

模拟退火算法 python源代码 模拟退火算法实例_搜索

首先肯定是最简单的贪心法,但是贪心会陷入局部最优解,不一定能搜索出全局最优解

如图,假设C点为当前位置,贪心搜索到A点这个局部最优解就会停止搜索,因为在A点无论向那个方向小幅度移动都不能得到更优的解。

 

模拟退火算法

模拟退火其实也是一种贪心算法,但是它的搜索过程引入了随机因素。

模拟退火算法以一定的概率来接受一个比当前解要差的解,因此有可能会跳出这个局部的最优解,达到全局的最优解。

以图中为例,模拟退火算法在搜索到局部最优解A后,会以一定的概率接受到E的移动。也许经过几次这样的不是局部最优的移动后会到达D点,于是就跳出了局部最大值A。

 

这里的“一定的概率”的计算参考了金属冶炼的退火过程,这也是模拟退火算法名称的由来。

模拟退火算法 python源代码 模拟退火算法实例_模拟退火算法_02

 

实战演示

假设现在我们有一个函数,形式为

模拟退火算法 python源代码 模拟退火算法实例_最优解_03

其函数图像为

模拟退火算法 python源代码 模拟退火算法实例_最优解_04

通过求导我们也能发现,在x=10处该函数取到最小值,有全局最优解。

 

接下来我们通过拟退火算法实现整个寻优过程。

①解空间

解空间就是我们所要求的定义域的空间范围,在这里我们定为[0, 100]

②目标函数

目标函数就是我们要求的函数,这里即为y=3x2-60x+9

③新解的产生

通过当前的解产生一个新解的方法有很多,在这里我们直接通过加上一个微小的偏差bias来微调这个值。

x_new = x + np.random.uniform(-1, 1)

增加一个[-1,1]之间的实数。

④代价函数差

代价函数差就是前后两次函数值的差值:E(j)-E(i)

⑤接受准则

接受准则就是算法最核心的地方:

模拟退火算法 python源代码 模拟退火算法实例_搜索_05

如果E(j) <E(i),就接受新的值;否则,以一定的概率接受新的值,即概率大于0-1之间的随机数则接受。在实际使用当中,我们可以把K看作1处理,甚至温度T都可以是任意尺度的值。比如初始T=1

⑥降温

利用选定的降温系数a进行降温处理,T=a*T,从而得到一个新的温度。比如a=0.999

⑦结束条件

可以选定一个结束的温度,当温度T不断衰减到某个值时,算法结束,输出当前状态。比如std=0.0000001

import numpy as np
import matplotlib.pyplot as plt

def x_function(x):
    return 3*x**2 - 60*x + 9
 
 
x = [i for i in np.linspace(0, 100)]
y = map(x_function, x)
plt.plot(x, list(y))
plt.show()


T = 1 # 初始温度
x = np.random.uniform(0, 100)
std = 0.00000001 # 终止温度
a = 0.999 # 衰减率

while T > std:
    y = x_function(x)
    # 新值通过扰动产生
    x_new = x + np.random.uniform(-1, 1)
    if 0 <= x_new <= 100:
        y_new = x_function(x_new)
        if y_new < y:
            x = x_new
        else:
            p = np.exp((y - y_new) / T)
            r = np.random.uniform(0, 1)
            if p > r:
                x = x_new
                # print(x)
    T = T * a
    
print(x, x_function(x))


模拟退火算法 python源代码 模拟退火算法实例_最优解_06

 

可见,我们通过模拟退火的算法寻找到了全局最优的最小值x=10

 

总结

      怎么来理解这个过程?事实上就是在解空间中先随机的选择一个解x,计算它的函数值,然后以一定的方式(可以是增减一个扰动)得到一个新的解x1,比较这两个函数值,取最小值。即使后者的函数值比前者大,也可以以一定的概率保留,只是说这个概率定义成了玻尔兹曼分布中的概率形式。和其他的启发式算法(遗传算法)一样,它们都是以概率为导向的迭代算法,说白了这个世界就是这么奇妙,冥冥之中自有概率在安排。