学习笔记:模拟退火
模拟退火
引入
模拟退火是一种随机化算法。当一个问题的方案数量极大(甚至是无穷的)而且不是一个单峰函数时,我们常使用模拟退火求解。
解释
根据爬山算法的过程,我们发现:对于一个当前最优解附近的非最优解,爬山算法直接舍去了这个解。而很多情况下,我们需要去接受这个非最优解从而跳出这个局部最优解,即为模拟退火算法。
退火是一种金属热处理工艺,指的是将金属缓慢加热到一定温度,保持足够时间,然后以适宜速度冷却。目的是降低硬度,改善切削加工性;消除残余应力,稳定尺寸,减少变形与裂纹倾向;细化晶粒,调整组织,消除组织缺陷。准确的说,退火是一种对材料的热处理工艺,包括金属材料、非金属材料。而且新材料的退火目的也与传统金属退火存在异同。
由于退火的规律引入了更多随机因素,那么我们得到最优解的概率会大大增加。于是我们可以去模拟这个过程,将目标函数作为能量函数。
过程
如果新状态的解更优则修改答案,否则以一定概率接受新状态。
令当前温度为 ,新状态 与已知状态 (新状态由已知状态通过随机的方式得到)之间的能量(值)差为 (),则发生状态转移(修改最优解)的概率为
注意:我们有时为了使得到的解更有质量,会在模拟退火结束后,以当前温度在得到的解附近多次随机状态,尝试得到更优的解(其过程与模拟退火相似)。
模拟退火时我们有三个参数:初始温度 ,降温系数 ,终止温度 。其中 是一个比较大的数, 是一个非常接近 但是小于 的数, 是一个接近 的正数。
首先让温度 ,然后按照上述步骤进行一次转移尝试,再让 。当 时模拟退火过程结束,当前最优解即为最终的最优解。
注意为了使得解更为精确,我们通常不直接取当前解作为答案,而是在退火过程中维护遇到的所有解的最优值。
随着温度的降低,跳跃越来越不随机,最优解也越来越稳定。
一些技巧
分块模拟退火
有时函数的峰很多,模拟退火难以跑出最优解。
此时可以把整个值域分成几段,每段跑一遍模拟退火,然后再取最优解。
卡时
有一个 clock()
函数,返回程序运行时间。
可以把主程序中的 simulateAnneal();
换成 while ((double)clock()/CLOCKS_PER_SEC < MAX_TIME) simulateAnneal();
。这样子就会一直跑模拟退火,直到用时即将超过时间限制。
这里的 MAX_TIME
是一个自定义的略小于时限的数(单位:秒)。
重复
有些时候对于答案没有把握的话,可以考虑多跑几次模拟退火。这样的话可以增大找到正解的概率。
注意:有些时候模拟退火并不一定能够保证得出正解。类似于模拟退火、爬山算法这一类的随机化算法其实更适用于当一道题实在想不出高分做法时可以考虑暴力和退火相结合以尽量得到高分。并且,使用随机化算法的代码 CCF 是不会受理申诉的。传送门
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效