模拟退火算法(SAA,Simulated Annealing Algorithm)的灵感来源于工艺铸造流程中的退火处理,随着铸造温度升高,分子运动趋于无序,徐徐冷却后,分子运动趋于有序。这是一种基于概率突跳特性(取决于温度状态)的算法,在解空间中概率寻找(或趋近于)最优解。它是跳出局部最优解的一个常用解决办法。在超大规模集成电路(Very Large Scale Integration Circuit,VLSI)、神经网计算机、计算机视觉、TSP和Knapsack问题等有重要且广泛的应用。
模拟退火算法采用了串行结构。
模拟退火算法的三要素是解空间,目标函数和初始解。它的基本思想是:
模拟退火算法包含两个部分,即Metropolis和退火过程,分别对应着内循环和外循环。外循环将固体加热至较高的温度(初始温度T0),然后按照降温系数alpha使温度按照一定的比例下降,当达到终止温度Tf时,冷却结束,退火过程结束,对应上述的(1)过程。
Metropolis算法是内循环,即在每次更新的温度下迭代L次,并寻找该温度下能量的最小值(最优解)。对应的是上述的(2)过程。
用能量变化来解释模拟退火算法接受新解的情况:
Metropolis准则:
1953年提出。若在温度T时,由状态i转变为状态j,那么若EjMetropolis算法是退火算法的基础,同样是在局部最优中选取全局最优。
在“退火”过程中,铸件徐徐冷却,分子运动趋于有序,每个分子都趋于平衡态,最终温度下降到常温时,达到基态,内能减为最小,能量减小原子趋于稳定。
在一定的某温度 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=
退火过程由冷却温度表(Cooling Schedule)控制,包括控制参数的初值t及其衰减因子Δt、每个t值时的迭代次数L和停止条件Tf。
接受状态的三条原则:
(1)在固定温度下,接受使目标函数下降的候选解的概率 > > >使目标函数上升的候选解概率;
(2)随着温度的下降,接受使目标函数上升的解的概率要逐渐减小;
(3)当温度趋于零时,只能接受目标函数下降的解。
可见参数的选择控制构成了模拟退火算法的重点和创新点。
模拟退火算法的缺点:
目前,已有一些高效的改进方案,比如并行模拟退火算法、快速模拟退火算法等。
改进的可行方案 :
采用并行搜索结构,并改进状态产生函数,改进退火历程,增加新的环节,例如增加升温/重升温过程,增加补充搜索过程,增加多次搜索策略等。
用模拟退火算法求解 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}")