scikit-opt 模拟退火(SA)深入:Fast / Boltzmann / Cauchy 三种降温策略的原理、参数与实战
2026/9/17 12:08:15 网站建设 项目流程

scikit-opt 模拟退火(SA)深入:Fast / Boltzmann / Cauchy 三种降温策略的原理、参数与实战

【免费下载链接】scikit-optGenetic Algorithm, Particle Swarm Optimization, Simulated Annealing, Ant Colony Optimization Algorithm,Immune Algorithm, Artificial Fish Swarm Algorithm, Differential Evolution and TSP(Traveling salesman)项目地址: https://gitcode.com/GitHub_Trending/sci/scikit-opt

本篇文章以 scikit-opt 仓库中的 docs/en/more_sa.md 为主体,系统讲解模拟退火(Simulated Annealing,SA)在 scikit-opt 中的三种具体实现:快速模拟退火(Fast)、玻尔兹曼模拟退火(Boltzmann)与柯西模拟退火(Cauchy)。你将学会三种策略各自的状态更新公式与降温曲线,掌握SAFastSABoltzmannSACauchy的完整调用方式(含边界约束版本),并结合 sko/SA.py 的源码理解 Metropolis 准则、链长与停止条件等底层机制,最终能在 examples/demo_sa.py 的基础上快速完成自己的优化任务。

一、模拟退火三策略的数学模型:三种"降温 + 抽样"方案

scikit-opt 的模拟退火实现把"生成新解"(抽样)与"温度更新"(降温)两件事绑定在一起,形成三种风格迥异的策略。文档 docs/en/more_sa.md 给出了三种策略的数学定义,它们分别对应源码中SAFastSACauchySABoltzmann三个类(sko/SA.py)。

1.1 Fast(快速退火)策略

u ~ Uniform(0, 1, size = d) y = sgn(u - 0.5) * T * ((1 + 1/T)**abs(2*u - 1) - 1.0) xc = y * (upper - lower) x_new = x_old + xc c = n * exp(-n * quench) T_new = T0 * exp(-c * k**quench)

该策略基于"快速退火"(Fast Simulated Annealing)思想:扰动幅度由温度T与均匀分布随机数u共同决定,扰动呈近似柯西分布的重尾特性,有利于在大范围内跳变;降温速度呈指数级衰减,收敛速度较快。对照源码,SAFast.get_new_x将公式中的upper - lower实现为可配置的hop步长(sko/SA.py),cool_down则按T_new = T_max * exp(-c * k**quench)降温(sko/SA.py),其中c = m * exp(-n * quench)(sko/SA.py)。

1.2 Cauchy(柯西)策略

u ~ Uniform(-pi/2, pi/2, size=d) xc = learn_rate * T * tan(u) x_new = x_old + xc T_new = T0 / (1 + k)

柯西策略的扰动服从柯西分布(通过tan(u)生成),同样具有重尾特性,允许偶尔产生大步长跳跃;温度随迭代次数k线性反比下降(T0 / (1 + k))。源码实现中,扰动幅度为learn_rate * T * tan(u),其中learn_rate默认取0.5(sko/SA.py),降温逻辑见 sko/SA.py。

1.3 Boltzmann(玻尔兹曼)策略

std = minimum(sqrt(T) * ones(d), (upper - lower) / (3*learn_rate)) y ~ Normal(0, std, size = d) x_new = x_old + learn_rate * y T_new = T0 / log(1 + k)

玻尔兹曼策略的扰动服从高斯分布:标准差取sqrt(T)与边界约束折算值两者中的较小者,使扰动范围受边界约束钳制;温度按对数函数T0 / log(1 + k)缓慢下降,属于三类中降温最慢、搜索最细致的方案。源码中std = min(sqrt(T), hop / (3 * learn_rate))的钳制逻辑在 sko/SA.py 实现,降温逻辑见 sko/SA.py。

三种策略核心差异可总结如下:

策略生成新解降温公式特点
Fast重尾扰动,xc = y * hopT_new = T0 * exp(-c * k**quench)降温快,适合快速粗寻优
Cauchy柯西分布扰动,xc = learn_rate * T * tan(u)T_new = T0 / (1 + k)允许大步长跳跃
Boltzmann高斯扰动,标准差受边界钳制T_new = T0 / log(1 + k)降温最慢,搜索细致

二、三种策略的统一骨架:SimulatedAnnealingBase 与 Metropolis 准则

无论选择哪种策略,它们都继承自SimulatedAnnealingBase(sko/SA.py),共享同一套核心流程:

  1. 初始化:以x0作为初始解,计算初始函数值作为best_y,温度初始化为T_max(sko/SA.py);
  2. 内层循环(链):在每一温度下迭代L次,通过get_new_x生成新解,并依据Metropolis 准则决定是否接受:
# Metropolis df = y_new - y_current if df < 0 or np.exp(-df / self.T) > np.random.rand(): x_current, y_current = x_new, y_new if y_new < self.best_y: self.best_x, self.best_y = x_new, y_new

(见 sko/SA.py)其含义是:新解更优(df < 0)必然接受;新解更差时,以概率exp(-df / T)接受,温度越高越容易"容忍"坏解,从而跳出局部最优;

  1. 外层循环:每完成一轮链,调用cool_down()降温,并记录generation_best_Ygeneration_best_X历史(sko/SA.py);
  2. 停止条件:温度降至T_min以下,或连续max_stay_counter轮最优值未改善(sko/SA.py)。

需要注意的是,run()返回(best_x, best_y),同时结果也保存在对象的best_xbest_ybest_x_historybest_y_history属性中,便于后续绘图分析(examples/demo_sa.py)。基类还提供了fit = run的兼容别名(sko/base.py),不过官方更推荐使用run()

三、Fast 模拟退火:基础用法与边界约束

3.1 基础用法

SAFast的类名定义为SA = SAFast(sko/SA.py),因此from sko.SA import SA拿到的就是 Fast 策略。文档及示例代码 examples/demo_sa.py 中的基础用法如下:

from sko.SA import SAFast demo_func = lambda x: x[0] ** 2 + (x[1] - 0.05) ** 2 + x[2] ** 2 sa_fast = SAFast(func=demo_func, x0=[1, 1, 1], T_max=1, T_min=1e-9, q=0.99, L=300, max_stay_counter=150) sa_fast.run() print('Fast Simulated Annealing: best_x is ', sa_fast.best_x, 'best_y is ', sa_fast.best_y)

其中demo_func是一个三维连续函数,理论最优点接近(0, 0.05, 0)。运行后best_x会收敛到该点附近,best_y接近 0。

3.2 带边界约束的用法

当决策变量存在取值范围时,可传入lb(下界)与ub(上界),两者必须同时给出,否则抛错(sko/SA.py)。边界约束版本会在每次生成新解后用np.clip将解限制在界内(sko/SA.py):

from sko.SA import SAFast sa_fast = SAFast(func=demo_func, x0=[1, 1, 1], T_max=1, T_min=1e-9, q=0.99, L=300, max_stay_counter=150, lb=[-1, 1, -1], ub=[2, 3, 4]) sa_fast.run() print('Fast Simulated Annealing with bounds: best_x is ', sa_fast.best_x, 'best_y is ', sa_fast.best_y)

源码提示:从 sko/SA.py 的实现看,SAFast实际从kwargs中读取的调温参数是m(默认 1)、n(默认 1)、quench(默认 1),以及影响扰动范围的hop(有边界时默认ub - lb,无边界时默认 10,见 sko/SA.py)。文档示例中传入的q=0.99会被**kwargs静默吸收而不生效,若要调节降温速度,应改用quench等参数。

四、Boltzmann 模拟退火:基础用法与边界约束

SABoltzmann使用高斯扰动与对数降温(sko/SA.py)。文档示例(对应 examples/demo_sa.py):

from sko.SA import SABoltzmann sa_boltzmann = SABoltzmann(func=demo_func, x0=[1, 1, 1], T_max=1, T_min=1e-9, q=0.99, L=300, max_stay_counter=150) sa_boltzmann.run() print('Boltzmann Simulated Annealing: best_x is ', sa_boltzmann.best_x, 'best_y is ', sa_boltzmann.best_y)

带边界约束版本(examples/demo_sa.py),注意示例中lb传的是标量-1ub传的是列表[2, 3, 4],源码会用np.ones(n_dim)自动广播成与维度匹配的数组(sko/SA.py):

from sko.SA import SABoltzmann sa_boltzmann = SABoltzmann(func=demo_func, x0=[1, 1, 1], T_max=1, T_min=1e-9, q=0.99, L=300, max_stay_counter=150, lb=-1, ub=[2, 3, 4]) sa_boltzmann.run() print('Boltzmann Simulated Annealing with bounds: best_x is ', sa_boltzmann.best_x, 'best_y is ', sa_boltzmann.best_y)

SABoltzmann还接受learn_rate参数(默认 0.5),它同时参与扰动标准差钳制与解更新的缩放(sko/SA.py),可视为该策略的核心灵敏度旋钮。

五、Cauchy 模拟退火:基础用法与边界约束

SACauchy使用柯西分布扰动与线性反比降温(sko/SA.py)。文档示例(对应 examples/demo_sa.py):

from sko.SA import SACauchy sa_cauchy = SACauchy(func=demo_func, x0=[1, 1, 1], T_max=1, T_min=1e-9, q=0.99, L=300, max_stay_counter=150) sa_cauchy.run() print('Cauchy Simulated Annealing: best_x is ', sa_cauchy.best_x, 'best_y is ', sa_cauchy.best_y)

带边界约束版本(examples/demo_sa.py):

from sko.SA import SACauchy sa_cauchy = SACauchy(func=demo_func, x0=[1, 1, 1], T_max=1, T_min=1e-9, q=0.99, L=300, max_stay_counter=150, lb=[-1, 1, -1], ub=[2, 3, 4]) sa_cauchy.run() print('Cauchy Simulated Annealing with bounds: best_x is ', sa_cauchy.best_x, 'best_y is ', sa_cauchy.best_y)

同样地,SACauchy的有效调节参数是learn_rate(默认 0.5)与hopq不参与计算。

六、参数一览表:如何为三种策略调参

综合 docs/en/more_sa.md 与 sko/SA.py 源码,三类模拟退火共享以下构造参数:

参数默认值作用
func必填目标函数,输入一维数组,输出标量
x0必填初始解,一维数组,其长度决定n_dim
T_max100初始温度,须满足T_max > T_min > 0(sko/SA.py)
T_min1e-7终止温度
L300每个温度下的迭代次数(链长,Long of Chain,sko/SA.py)
max_stay_counter150最优值连续未改善的轮数上限,用于提前停止(冷却计数,sko/SA.py)
lb/ub决策变量上下界,需同时传入,可传标量或数组;不传则无边界
hop有界时ub-lb,无界时 10Fast 策略的扰动缩放步长,也参与 Boltzmann 的标准差钳制

策略专属参数:

策略专属参数默认值作用
SAFastmnquench1、1、1控制指数降温速度,c = m * exp(-n * quench)
SABoltzmannlearn_rate0.5扰动标准差与解更新缩放
SACauchylearn_rate0.5柯西扰动幅度缩放

一般调参思路:T_max应覆盖目标函数可能的函数值落差(决定初始"容忍坏解"程度);L决定每个温度下的精细度,越大越接近精确搜索但耗时更长;max_stay_counter用于提前终止,避免在低收益阶段空转。文档示例统一采用T_max=1, T_min=1e-9, L=300, max_stay_counter=150,对 demo 函数已足够收敛。

七、结果验证与收敛曲线绘制

run()结束后,可从对象属性中取出历史收敛数据并绘制曲线(examples/demo_sa.py):

import matplotlib.pyplot as plt import pandas as pd plt.plot(pd.DataFrame(sa.best_y_history).cummin(axis=0)) plt.show()

其中best_y_history记录了每个降温周期(外层循环)的最优函数值,cummin取累计最小值后绘图,可以直观看到三种策略各自的收敛速度与最终精度,便于横向对比 Fast / Boltzmann / Cauchy 在具体问题上的表现。

八、延伸:SA 用于 TSP 组合优化

虽然 docs/en/more_sa.md 只介绍连续函数上的三种策略,但仓库将同一套 SA 骨架扩展到了组合优化——SA_TSP(sko/SA.py)。它以路径序列为解,每轮以等概率从三种变异算子中选择一种生成新路径:

  • swap:交换两个城市的访问顺序(sko/operators/mutation.py);
  • reverse:反转一段子路径,即 2-Opt 思想(sko/operators/mutation.py);
  • transpose:将一段子路径整体搬移到另一位置(sko/operators/mutation.py)。

用法示例(完整代码见 examples/demo_sa_tsp.py):

from sko.SA import SA_TSP sa_tsp = SA_TSP(func=cal_total_distance, x0=range(num_points), T_max=100, T_min=1, L=10 * num_points) best_points, best_distance = sa_tsp.run()

其降温曲线为T_new = T_max / (1 + log(1 + k))(sko/SA.py),可借助best_x_history制作寻优过程动画。这也印证了"更换get_new_xcool_down即可定制新的 SA 策略"的设计思路——三种连续策略与 TSP 版本本质上复用同一个SimulatedAnnealingBase骨架。

小结

  • 三种策略选型:Fast 降温最快、适合快速粗寻优;Cauchy 重尾扰动、兼顾大范围跳变;Boltzmann 对数降温最慢、搜索最细致。三者均支持lb/ub边界约束,解会被clip在界内;
  • 统一机制:Metropolis 准则、链长L、温度区间[T_min, T_max]max_stay_counter提前停止,构成三类算法的公共骨架(sko/SA.py);
  • 调参要点:Fast 调节m/n/quench,Boltzmann 与 Cauchy 调节learn_rate;文档示例中的q参数在当前源码中不生效;
  • 实战入口:直接运行 examples/demo_sa.py 即可复现三策略全部示例,再结合best_y_history绘制收敛曲线对比效果。

【免费下载链接】scikit-optGenetic Algorithm, Particle Swarm Optimization, Simulated Annealing, Ant Colony Optimization Algorithm,Immune Algorithm, Artificial Fish Swarm Algorithm, Differential Evolution and TSP(Traveling salesman)项目地址: https://gitcode.com/GitHub_Trending/sci/scikit-opt

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询