摸你退火

模拟退火算法(Simulate Anneal,SA)

[pproptoleft| frac{1}{f[x_j]-f[x_i]} ight| ]

定义一个可接受的概率p,p(in[0,1])

(f(x_j)和f(x_i))越接近,p越大 新解和旧解函数越接近,越愿意接受新解

(y=e^{-x}(0le xle1)关于x单调递减) ge是大等于qwq le是小等于

所以我们可以假设(p propto e^{-left| f(x_j)-f(x_i) ight|})

因为有了负号所以不需要取导数

保证搜索前期范围尽量大,搜索后期范围尽量小

对式子(p_t propto e^{-left| f(x_j)-f(x_i) ight|})进行变形(p propto e^{-left| f(x_j)-f(x_i) ight|*C_i})

搜索前期t较小,我们希望搜索范围更大,更倾向于接受新解,对应的p就应该大,而(C_i)与p负相关,因此后期我们希望p较小,(C_i)就应该大一点,可以得到(C_i)关于t递增 所以时间越长t越大

假设求最大值:简单流程 || TSP

  1. 随机生成一个解A,计算A对应的f(A)

  2. 在A附近随机生成一个解B,计算B对应的f(B)

  3. if (f(B)>f(A)) 把B赋值给A //反复迭代

  4. if(f(B)(le)f(A)) 计算接受P的概率(p = e^{-left| f(x_j)-f(x_i) ight|*C_i}),然后生成一个[0,1]之间的随机数r,如果r<p,将解B赋值成A,然后重复上面步骤,否则反回第二步

    问题:如果优化问题有约束条件怎么办 怎样随机生成B?

    (C_i)如何设置 搜索过程什么时候结束

    定义初始温度,(T_0=100),温度下降公式(T_{t+1}=aT_t),a常取0.95,那么时刻t的温度

    (T_t=a^t * t_0=100*0.95^t)

    (p_t=e^{frac{f(B)-f(A)}{T_t}}=e^{frac{left|f(B)-f(A) ight|}{100*0.95^t}})

    取倒数是为了保证(C_i)关于t递增

    温度一定,(Delta f)越小,概率阅读,目标函数接受相差越小的可能性越大

    (Delta f)一定,温度越高,概率越大(但需要的计算越多),搜索前期温度越高越可能接受新解

t的实现通过迭代(循环)为保证搜索彻底,我们进行多次搜索,然后降温,再多次搜索

搜索停止时间:1.达到指定迭代次数 2.达到指定温度 3找到连续最优解M次都没变化(自己定M)
dalao的一张图
一遍SA往往无法跑出最优解,所以可以多跑几遍。

可以用一个全局变量记录所有跑过的SA的最优解,每次从那个最优解开始继续SA,可以减小误差。

如何生成新解

坐标系内:随机生成一个点,或者生成一个向量。
序列问题: $random_shuffle$或者随机交换两个数。
网格问题:可以看做二维序列,每次交换两个格子即可。

时间复杂度 (O( ext{玄学}))

一般降温系数 (Delta) 与 1 的差减少一个数量级, 耗时大约多 10 倍; (T_0)​ 和(T_k)​ 变化一个数量级, 耗时不会变化很大。
大神勃客https://www.luogu.com.cn/blog/m-sea/qian-tan-SA
https://www.luogu.com.cn/problem/solution/P2538

原文地址:https://www.cnblogs.com/shikeyu/p/13263098.html