模拟退火法(Simulated Annealing, SA)是一种用于优化问题的算法,灵感来自于金属退火过程。以下是模拟退火法的浅显易懂解释:
模拟退火法的原理
-
退火过程的模拟
在金属退火过程中,金属被加热到高温,然后缓慢冷却。这一过程允许金属原子的重新排列,使其达到最低能量状态,形成稳定的晶体结构。模拟退火法借用了这一过程来解决优化问题:
加热:
开始时,系统处于高温状态,能量较高,允许较大的随机性和波动。
冷却:
随着温度的逐渐降低,系统的随机性减少,波动减小,逐步趋向稳定状态。 -
优化问题的解决
在优化问题中,我们希望找到一个全局最优解,而不是局部最优解。模拟退火法通过以下步骤来实现这一目标:
初始解:
从一个随机或给定的初始解开始。
邻域搜索:
在当前解的邻域中随机选择一个新解,称为候选解。
能量差计算:
计算新解和当前解的“能量差”,能量通常与目标函数的值相关联。例如,能量差可以是目标函数值的变化量。
接受新解的概率:
如果新解比当前解更优(能量更低),直接接受新解。
如果新解不如当前解,以一定概率接受新解。这一概率由当前温度和能量差决定,通常使用以下公式:
温度下降:
按照预定的冷却计划逐步降低温度。常见的冷却计划是指数冷却:
终止条件:
当温度降到某个阈值或者达到最大迭代次数时,停止算法。
示例
假设你想找到一个数,使得它的平方值最小。我们可以用模拟退火法来找到这个最优解(显然是0,但我们用这个简单例子来说明原理)。
import numpy as np
import matplotlib.pyplot as plt
# 目标函数
def objective_function(x):
return x**2
# 模拟退火算法
def simulated_annealing(initial_solution, initial_temp, cooling_rate, max_iter):
current_solution = initial_solution
current_temp = initial_temp
history = [current_solution]
for _ in range(max_iter):
# 生成邻域中的新解
new_solution = current_solution + np.random.uniform(-1, 1)
# 计算能量差
delta_energy = objective_function(new_solution) - objective_function(current_solution)
# 根据能量差和当前温度决定是否接受新解
if delta_energy < 0 or np.exp(-delta_energy / current_temp) > np.random.rand():
current_solution = new_solution
# 记录历史解
history.append(current_solution)
# 降低温度
current_temp *= cooling_rate
return current_solution, history
# 初始参数
initial_solution = 10
initial_temp = 100
cooling_rate = 0.95
max_iter = 100
# 执行模拟退火
final_solution, history = simulated_annealing(initial_solution, initial_temp, cooling_rate, max_iter)
# 打印最终结果
print(f"Final Solution: {final_solution}")
# 绘制历史解
plt.plot(history)
plt.xlabel('Iteration')
plt.ylabel('Solution')
plt.title('Simulated Annealing Optimization')
plt.show()