模拟退火算法(SAA)简介
模拟退火算法(SAA,Simulated Annealing Algorithm)的灵感来源于工艺铸造流程中的退火处理,随着铸造温度升高,分子运动趋于无序,徐徐冷却后,分子运动趋于有序。这是一种基于概率突跳特性(取决于温度状态)的算法,在解空间中概率寻找(或趋近于)最优解。它是跳出局部最优解的一个常用解决办法。在超大规模集成电路(Very Large Scale Integration Circuit,VLSI)、神经网计算机、计算机视觉、TSP和Knapsack问题等有重要且广泛的应用。
模拟退火算法采用了串行结构。
SAA步骤
模拟退火算法的三要素是解空间,目标函数和初始解。它的基本思想是:
- 初始化
首先确定一个初始温度T,初始解状态S,每个T值的迭代次数L。 - 迭代
在1-L次数中做这些操作:(2)
产生新解S’。
计算温度增量△t’=C(S’)-C(S)。(C(S)为评估函数)
若Δt′<0则接受S′作为新的当前解,否则以概率exp(-Δt′/(KT))接受S′作为新的当前解(k为波尔兹曼常数)
如果终止条件已经满足,则接受当前解作为最优解,并停止迭代计算。如果不是,则继续。
T逐渐减少,且t趋近于0,则转到2.迭代。(1)
SAA原理
模拟退火算法包含两个部分,即Metropolis和退火过程,分别对应着内循环和外循环。外循环将固体加热至较高的温度(初始温度T0),然后按照降温系数alpha使温度按照一定的比例下降,当达到终止温度Tf时,冷却结束,退火过程结束,对应上述的(1)过程。
Metropolis算法是内循环,即在每次更新的温度下迭代L次,并寻找该温度下能量的最小值(最优解)。对应的是上述的(2)过程。
用能量变化来解释模拟退火算法接受新解的情况:
Metropolis准则:
1953年提出。若在温度T时,由状态i转变为状态j,那么若Ej<Ei,则接受j状态为新状态。否则,进入新一轮判断:若概率P=exp(-(Ej-Ei)/KT)大于[0,1]区间的随机数,则接受j为新状态;若不成立,则保留i为新状态。
Metropolis算法是退火算法的基础,同样是在局部最优中选取全局最优。
在“退火”过程中,铸件徐徐冷却,分子运动趋于有序,每个分子都趋于平衡态,最终温度下降到常温时,达到基态,内能减为最小,能量减小原子趋于稳定。
在一定的某温度 T 0 T_0 T0下,存在状态变换(由一个波谷变化至下一个波谷),那么如果下一个波谷能量 E ( n + 1 ) E(n+1) E(n+1)大于原先的 E ( n ) E(n) E(n),就接受它成为新解,否则进入判断,设置一个概率P:
P = { 1 E ( n + 1 ) < E ( n ) e − ( E ( n + 1 ) − E ( n ) ) / T E(n+1)≥E(n) P= \begin{cases} \displaystyle1 & E(n+1)<E(n)\\e^{-(E(n+1)-E(n))/T} & \text{E(n+1)≥E(n)} \end{cases} P={1e−(E(n+1)−E(n))/TE(n+1)<E(n)E(n+1)≥E(n)
退火过程由冷却温度表(Cooling Schedule)控制,包括控制参数的初值t及其衰减因子Δt、每个t值时的迭代次数L和停止条件Tf。
接受状态的三条原则:
(1)在固定温度下,接受使目标函数下降的候选解的概率 > > >使目标函数上升的候选解概率;
(2)随着温度的下降,接受使目标函数上升的解的概率要逐渐减小;
(3)当温度趋于零时,只能接受目标函数下降的解。
可见参数的选择控制构成了模拟退火算法的重点和创新点。
SAA的参数选择控制
- 选择足够高的初始温度 T 0 T_0 T0意味着有更多的选择可以被触及,也就更接近全局最优解。
- 指数式下降的温度下降方式尤为便捷,而且收敛速度较慢。
- 终止温度的选取。
SAA的改进方向
模拟退火算法的缺点:
- 收敛速度慢
- 优化解和运行时间存在一定矛盾
- 难以判断是否达到最终平衡态
目前,已有一些高效的改进方案,比如并行模拟退火算法、快速模拟退火算法等。
改进的可行方案 :
采用并行搜索结构,并改进状态产生函数,改进退火历程,增加新的环节,例如增加升温/重升温过程,增加补充搜索过程,增加多次搜索策略等。
SAA简单应用实例
用模拟退火算法求解 f ( x ) = x 2 f(x)=x^2 f(x)=x2的最小值:
import math
import random
def simulated_annealing():
# 初始化
x = 20*(random.random()-0.5) # 初始解
T = 1000 # 初始温度
T_min = 1e-3 # 温度下限,当T小于此值时,停止迭代
alpha = 0.99 # 温度衰减系数
y = x**2 # 初始解的质量
while T > T_min:
# 在当前解附近随机选择一个新解
delta_x = (random.random()-0.5)
new_x = x + delta_x
new_y = new_x**2
# Metropolis准则:若新解比旧解好,或者根据概率接受不良解,以避免陷入局部最小值
if new_y < y:
x = new_x
y = new_y
else:
p = math.exp((y - new_y) / T)
if random.random() < p:
x = new_x
y = new_y
# 降温
T *= alpha
return x, y
if __name__ == "__main__":
x, y = simulated_annealing()
print(f"最优解: x = {x}, y = {y}")