本帖最后由 薛定谔了么 于 2025-1-21 15:27 编辑

模拟退火算法(Simulated Annealing,简称SA) 是一种基于物理退火过程的优化算法。它灵感来源于金属退火过程中的分子运动——在高温下,金属分子的自由度很高,随着温度的逐渐降低,分子排列逐渐有序,最终达到最低能量状态。退火算法通过模拟这一过程,解决复杂的优化问题。
在现实生活中,我们经常会遇到寻找最优解的问题,无论是优化路线、调度任务还是调整模型参数。
模拟退火算法(Simulated Annealing,简称SA)是解决这类问题的一个经典优化算法。今天,我们通过一个有趣的生活场景——“醉酒的人下山”,来形象地理解模拟退火算法的工作原理,并且提供一个简单的实现案例和Python代码。
什么是模拟退火算法?
模拟退火是一种启发式算法,灵感来源于金属退火的物理过程。在金属加热到高温后,逐渐冷却,金属分子会从不规则的结构调整为更稳定、更低能量的状态。模拟退火算法通过模拟这一过程来寻找问题的全局最优解。该算法在搜索空间中进行随机搜索,通过“接受”不太好的解来避免陷入局部最优解,最终朝着全局最优解逼近。
案例:醉酒的人下山
想象一个醉酒的人在山上迷失方向,目标是尽快到达山谷(即最低点)。这个醉酒的人步伐不稳定,他可能因为醉酒而随意走动,但他总是倾向于向低处走,以便尽快找到山谷。此时,模拟退火算法的过程就像这个醉酒的人下山。
当前状态: 醉酒的人站在山上的某个点,周围的地形起伏不平。
目标: 醉酒的人希望找到最低的山谷,也就是最低的能量状态(全局最优解)。
移动规则: 醉酒的人每次可以选择朝着四个方向走一步,每次走的距离是随机的,步伐可能向上、向下或平地走。
接受不好的解: 如果他走到的地方比现在的位置高(即走到了一个局部的“山峰”),他可能仍然会决定停留在这个地方,毕竟他可能找到了比当前状态稍好一点的位置(这就是模拟退火中的“接受劣解”)。
逐渐冷却: 随着醉酒的人下山,他的判断能力会变得更为理智(模拟退火中的温度逐渐降低),不再随意接受一些较差的解,而开始越来越倾向于选择更接近山谷的地方。
模拟退火的原理公式
模拟退火的核心是通过接受不太好的解来避免局部最优解的困境,并通过控制“温度”逐步使搜索趋向全局最优解。算法的基本步骤如下:
初始状态: 选择一个初始解,设置初始温度。
迭代过程: 在当前解附近随机生成一个新解。如果新解比当前解好,则接受新解;如果新解不好,则以一定的概率接受新解,这个概率由温度决定。
温度下降: 随着温度逐渐降低,接受劣解的概率逐渐减小,直到温度降至某个预设的最低值,算法结束。
数学上,接受新解的概率可以表示为:

其中:
Δ E 是新解和当前解之间的能量差(或目标函数值差)。
𝑇 是当前的温度。
随着温度的逐渐下降,接受较差解的概率逐渐降低,最终趋向全局最优解。
降温过程(Cooling Schedule):随着算法的进行,温度逐渐下降,通常采用以下冷却方式

其中,0 < α < 1 是冷却系数。
终止条件:当温度下降到一个设定的阈值,或者经过足够的迭代后,算法终止。
通过这种模拟退火的过程,退火算法能够跳出局部最优解,逐步逼近全局最优解。

应用场景
模拟退火算法被广泛应用于以下几个领域:
组合优化问题:如旅行商问题(TSP)、背包问题、排序问题等。
机器学习: 如神经网络的权重优化、超参数调优。
图像处理: 如图像恢复、图像分割等。
工程优化: 如路径规划、生产调度等。
实现模拟退火算法的案例:寻找函数的最小值
下面我们用模拟退火算法来寻找一个简单的数学函数的最小值。假设我们要优化的目标函数是:𝑓 ( 𝑥 ) = 𝑥 ⋅ sin ( 𝑥 )
我们的目标是找到这个函数的最小值。
Python代码实现
import math
import random
import matplotlib.pyplot as plt
# 定义目标函数
def objective_function(x):
return x * math.sin(x)
# 模拟退火算法
def simulated_annealing(start_x, T_max, T_min, alpha, max_iter):
x = start_x
T = T_max
best_x = x
best_fx = objective_function(x)
history = [(x, best_fx)] # 保存历史记录以便绘图
for i in range(max_iter):
# 在当前解附近随机选择一个新解
new_x = x + random.uniform(-1, 1)
# 计算当前解和新解的目标函数值
current_fx = objective_function(x)
new_fx = objective_function(new_x)
# 如果新解更优,接受新解
if new_fx < current_fx:
x = new_x
if new_fx < best_fx:
best_x = new_x
best_fx = new_fx
# 否则,按照一定的概率接受新解
else:
if random.uniform(0, 1) < math.exp((current_fx - new_fx) / T):
x = new_x
# 降温
T *= alpha
history.append((x, objective_function(x)))
# 如果温度低于最小温度,结束
if T < T_min:
break
return best_x, best_fx, history
# 设置参数
start_x = 5 # 初始解
T_max = 100 # 初始温度
T_min = 0.1 # 最小温度
alpha = 0.99 # 温度衰减率
max_iter = 1000 # 最大迭代次数
# 运行模拟退火算法
best_x, best_fx, history = simulated_annealing(start_x, T_max, T_min, alpha, max_iter)
# 打印最优解
print(f"最优解: x = {best_x}, f(x) = {best_fx}")
# 绘制搜索过程图
x_vals = [h[0] for h in history]
y_vals = [h[1] for h in history]
plt.plot(x_vals, y_vals, label='Search Path')
plt.scatter(best_x, best_fx, color='red', label='Best Solution')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Simulated Annealing Search Path')
plt.legend()
plt.show()
目标函数:objective_function(x) 定义了我们要优化的函数𝑓 ( 𝑥 ) = 𝑥 ⋅ sin ( 𝑥 )
模拟退火函数:simulated_annealing 实现了模拟退火算法的核心流程,包括生成新的候选解、接受新解的概率判断、以及逐步降低温度的过程。
绘图:为了直观展示退火过程,我们使用 matplotlib 来绘制模拟退火算法的搜索路径。

总结
模拟退火算法是一个强大的全局优化算法,广泛应用于各种实际问题中。通过模拟物理退火的过程,算法能够避免局部最优解的困境,最终找到全局最优解
在理解了模拟退火算法的基本原理后,我们通过生活中的“醉酒的人下山”的比喻,形象地展示了这一过程。希望通过本篇文章,你能够更好地理解模拟退火算法,并能将其应用于实际问题中。 ————————————————
本文转载自CSDN博主:搞技术的妹子
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/viviwiky/article/details/143840005 |