exp(-ΔE / T) 是接受概率公式,降温由温度更新策略控制;初温据ΔE_max设为≈ΔE_max/ln(2),终温取1e-6~1e-4;健康接受率应为40%~80%,需监控并调整初温与alpha。

降温函数选 exp(-ΔE / T) 还是线性衰减?
实际用下来,exp(-ΔE / T) 是接受概率的核心公式,它本身不决定“怎么降温”,而是决定“当前温度下是否接受更差解”。真正控制降温节奏的是温度更新策略——也就是你每次迭代后怎么改 T。
常见做法是乘一个衰减系数:T = T * alpha,其中 alpha 通常取 0.95~0.999。太接近 1(比如 0.999)会导致前期退火太慢,容易卡在局部;太小(如 0.8)则温度掉得太快,后期几乎不接受劣解,退化成贪心。
线性衰减(T = T - delta)理论上可行,但实践中很难预估总迭代次数,容易中途温度归零,导致算法提前冻结。
initial_T 和 final_T 怎么设才不瞎试?
initial_T 要足够高,让初始阶段能大范围探索:一般先跑几轮随机采样,算出目标函数值的典型波动范围 ΔE_max,然后设 initial_T ≈ ΔE_max / ln(2),这样初始接受劣解的概率约 50%。
立即学习“C++免费学习笔记(深入)”;
final_T 不必精确到 0.001,只要低到使 exp(-ΔE / T) 在常见劣解下趋近于 0 即可。经验上设为 1e-6~1e-4 就够用;更稳妥的做法是用迭代次数或连续拒绝次数做终止条件,而非硬写 final_T。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
容易踩的坑:
- 直接把
initial_T设成 1000 或 1e6 —— 完全脱离问题尺度,前期全是随机跳,收敛极慢 - 用
final_T == 0做 while 条件 —— 浮点精度问题会导致死循环 - 没监控实际接受率,无法判断温度是否偏高/偏低
怎么判断当前参数是不是调好了?
核心指标不是“最终结果多好”,而是“接受率是否健康”:理想情况下,前 30% 迭代的平均接受率应在 40%~80% 区间。低于 20% 说明温度掉太快或初温太低;高于 90% 说明初温太高或衰减太慢。
实操建议:
- 每 100 次迭代打印一次当前
T、接受次数、接受率 - 用固定随机种子复现,避免把运气当效果
- 对同一组参数,多跑几次看结果方差——如果标准差远大于均值,说明退火不稳定,大概率是温度策略或初温有问题
- 不要只调
alpha:它和initial_T强耦合;改了初温,往往得同步微调alpha
C++ 实现里哪些细节会悄悄破坏退火效果?
最容易被忽略的是随机数生成器的状态和分布:
- 别用
rand()—— 周期短、低位随机性差,std::mt19937才靠谱 - 接受判断必须用
std::uniform_real_distribution<double>(0.0, 1.0)</double>,不能手写(double)rand()/RAND_MAX - 温度更新要放在每次迭代末尾,且确保所有分支(无论是否接受新解)都执行降温,否则逻辑错乱
- 浮点比较慎用
==判断温度是否归零,改用T
还有个隐形陷阱:目标函数若存在大量平坦区域(即 ΔE ≈ 0),exp(-ΔE / T) 几乎恒为 1,退火会退成随机游走——这时得考虑加扰动或换邻域结构,光调温度没用。

















