一开始接触到 模拟退火算法,根本不知其为何物。然后根据一道我胡乱做错的题目(RQNOJ No.31),竟然牵扯到了这个算法,最后竟然高速AC了,所以看来这个算法还是很厉害的。
首先,模拟退火算法 顾名思义,一定是与 模拟退火 有关的。这个算法利用了热力学中金属退火的概率计算公式:P(Δ E) = exp(Δ E / (k * T)),其中 k 是常数,T 是递减的。这个公式在算法中的应用,是计算接受非最优解的概率。
在搜索中,我们从当前状态可以转到很多状态。其中如果所转到的状态较当前状态更优,那么必须转到;但是如果所转到的状态并不如当前状态优,则我们需要考虑接不接受它,因为从 非最优状态 是有可能转到 更优状态 的。
于是我们可以利用 模拟退火 的计算公式:
设置参数 t, r, k, 分别表示 初始温度,每次降温的比率 和 每次所得温度的迭代次数。
在每次所得的温度下,我们所进行的每一次迭代都会得到一个新解,而这个新解有可能较上一次更优,也有可能相反。对于更优的解,我们一概接受之;而在相反的情况下,我们利用P(Δ E) = exp(Δ E / T),其中Δ E 为前后两次 状态评估函数的差值(为负)。显然有 P 是属于 (0, 1) 的。利用该概率判断是否接受该新解。因为温度在下降,显然有该概率也会随着温度下降。这样所得的解将一定程度上收敛。事实证明(其实我也只做了一道题),这个算法的效率和效果很好。
下面上 RQNOJ No.31 的代码: