学习笔记--模拟退火
**模拟退火(Simulated Annealing)**是一种随机搜索算法,用于求解优化问题,特别是组合优化问题。它的名字和灵感来源于物理学中的退火过程,即将物质加热到高温,然后逐渐冷却,以达到低能量状态。
模拟退火算法的工作原理如下:
-
初始化:选择一个初始解和一个较高的初始“温度”。
-
迭代搜索:在每次迭代中,根据一定规则生成一个新的解。
-
接受准则:比较新解和当前解的优劣。如果新解更优,那么通常会接受它。如果新解较差,根据一个概率准则(通常基于Metropolis准则)决定是否接受。这个概率与当前的“温度”和解的优劣差有关。
-
降温:随着迭代的进行,逐渐降低“温度”,这导致接受较差解的概率下降。
-
终止:当“温度”降到一个设定的阈值以下,或者达到预定的迭代次数时,算法终止。
模拟退火算法的关键在于它允许在搜索过程中暂时接受较差的解,这有助于跳出局部最优,从而有可能找到全局最优解。同时,通过逐渐降低“温度”,算法逐渐聚焦于搜索空间中的高质量区域。
###在模拟退火中,Metropolis准则如下:
-
如果新生成的解比当前解更好(即,目标函数值更低),那么总是接受这个新解。
-
如果新生成的解比当前解更差,那么以一定的概率接受这个新解。这个概率是基于目标函数值的差异和当前的“温度”计算的,具体为 exp(-(新解的目标函数值 - 当前解的目标函数值) / 当前温度)。
接受更差的解的能力是模拟退火算法的一个关键特性,它允许算法有可能跳出局部最优解,并在搜索空间中更广泛地搜索。然而,随着“温度”的降低,接受更差解的概率也逐渐降低,使算法更加倾向于在潜在的最优区域内进行搜索。
还是那个例题。
假设我们要优化函数 f(x) = x^2,在范围 [-10, 10] 内找到使得函数取得最小值的 x。
import math
import random
# 目标函数
def f(x):
return x**2
# 模拟退火算法
def simulated_annealing():
# 参数设置
x = random.uniform(-10, 10) # 初始解
T = 1000 # 初始温度
T_min = 0.01 # 最小温度
alpha = 0.95 # 降温系数
# 主循环
while T > T_min:
# 生成新的解
x_new = x + random.uniform(-1, 1)
# 确保新解在 [-10, 10] 范围内
x_new = max(-10, min(10, x_new))
# 计算目标函数值的差
delta_f = f(x_new) - f(x)
# Metropolis 准则
if delta_f < 0 or random.random() < math.exp(-delta_f / T):
x = x_new
# 降温
T = T * alpha
# 返回找到的解
return x
# 执行模拟退火算法
result = simulated_annealing()
print(f"找到的解: x = {result}, f(x) = {f(result)}")
多跑几次我们会发现,使用模拟退火算法求出的解可能在不同的运行中是变化的。这是因为模拟退火是一种随机算法,它包含随机性在内。算法的随机成分包括初始解的选择、新解的生成以及根据Metropolis准则以一定的概率接受较差的解。
由于这些随机因素,每次运行模拟退火算法时,搜索路径和找到的解可能是不同的。这也是模拟退火算法的一个优点,因为它能够通过多次运行来探索解空间的不同区域。
为了提高找到好解的概率,可以采取以下措施:
-
多次运行:多次运行算法并记录每次运行的结果。从这些结果中选择最好的解。
-
参数调整:调整模拟退火算法的参数,如初始温度、降温率等,以找到适合问题的设置。
-
更好的邻域搜索策略:优化生成新解的方法,可能更加有效地搜索解空间。
请注意,由于模拟退火是一种近似算法,它不能保证找到全局最优解,但通常可以找到一个相当不错的解。另外,这个例子是为了学习算法的工作原理,模拟退火对这种简单问题可能是不必要的。在实际应用中,模拟退火通常用于解决更复杂的优化问题。