简介

模拟退火算法(Simulate Anneal,SA)是一种通用概率演算法,用来在一个大的搜寻空间内找寻命题的最优解。其思想借鉴于固体的退火原理,当固体的温度很高的时候,内能比较大,固体的内部粒子处于快速无序运动,当温度慢慢降低的过程中,固体的内能减小,粒子的慢慢趋于有序,最终,当固体处于常温时,内能达到最小,此时,粒子最为稳定。模拟退火算法便是基于这样的原理设计而成。

套用知乎上的形象描述:

一个锅底凹凸不平有很多坑的大锅,晃动这个锅使得一个小球使其达到全局最低点。一开始晃得比较厉害,小球的变化也就比较大,在趋于全局最低的时候慢慢减小晃锅的幅度,直到最后不晃锅,小球达到全局最低。


爬山算法

介绍模拟退火,一般会提到爬山算法。爬山算法是一种简单的贪心搜索算法,该算法每次从当前解的临近解空间中选择一个最优解作为当前解,直到达到一个局部最优解。

如上图所示,如果是简单的爬山算法,那么从出发点开始,遇到A就不会再爬了(肯定不会往D移动),因为A是其附近的一个比较高的点,再往两边走都会下降。这就是陷入了局部最优解。爬山算法可以说是完全“贪心”的,鼠目寸光,丝毫不知道后面还有C等着它。


模拟退火思想

事实上,与爬山算法相似,模拟退火也是一种贪心算法,但它到达A之后,有一定概率往D移动,并且随着时间推移(温度逐渐下降),这个概率会逐渐降低(这样最终才能稳定)。这个过程很像金属退火的那个过程,故退火算法因此得名。那么这个一定概率怎么表达呢,根据热力学原理,在温度为T时,出现能量差降温的概率为:

p(ΔE)=e−ΔEkTp(ΔE)=e−ΔEkT

p(\Delta E)=e^{-\frac {\Delta E}{kT}}
上面的公式是金属冶金的,这个公式翻译成模拟退火算法就是:假设现在位于某个位置 x0x0x_0,现在随机发生了一个位移到达 x0+Δxx0+Δxx_0+\Delta x,当发生位移后因变量 y|x=x0+Δxy|x=x0+Δxy|_{x=x_0+\Delta x}小于原来的 y|x=x0y|x=x0y|_{x=x_0},那么我接受这个位移的概率为:

p(Δx)=e−ΔxT(ify|x=x0+Δx<y|x=x0)p(Δx)=e−ΔxT(ify|x=x0+Δx<y|x=x0)

p(\Delta x)=e^{-\frac {\Delta x}{T}} \;\;(if\;y|_{x=x_0+\Delta x}
其中这里的T是模拟退火中设置的一个参数。当然,如果 y|x=x0+Δx>y|x=x0y|x=x0+Δx>y|x=x0y|_{x=x_0+\Delta x}>y|_{x=x_0},那么那个位移肯定会被接受,这个 p(Δx)=1p(Δx)=1p(\Delta x)=1。


有趣的比喻

爬山算法:兔子朝着比现在高的地方跳去。它找到了不远处的最高山峰。但是这座山不一定是珠穆朗玛峰。这就是爬山算法,它不能保证局部最优值就是全局最优值。(非常懒,一开始看到比现在高的就接受)

模拟退火:兔子喝醉了。它随机地跳了很长时间。这期间,它可能走向高处,也可能踏入平地。但是,它渐渐清醒了并朝最高方向跳去。这就是模拟退火。(一开始很激动,到处试探,变化大。后面心累了,逐渐减缓了步伐,朝向此时此刻的最高点爬去)


算法实现

这里用SA来求解y=10×sin(5x)+7×cos(4x)y=10×sin(5x)+7×cos(4x)y=10\times sin(5x)+7\times cos(4x)在的x=0和10x=0和10x=0和10之间的最大值

算法步骤:
1.初始化温度TTT、降温系数α" role="presentation">αα\alpha、最小温度TmimTmimT_{mim}以及一个随机的可行解(x,y)(x,y)(x,y)
2.当T>TmimT>TmimT>T_{mim},进行下面步骤,否则返回结果
3.随机发生扰动ΔxΔx\Delta x
4.计算发生扰动后的Δy值Δy值\Delta y值,大于0就接受这个扰动,小于0就以p(Δx)=e−ΔxTp(Δx)=e−ΔxTp(\Delta x)=e^{-\frac {\Delta x}{T}}概率接受。
5.更新最佳(x,y)(x,y)(x,y)
5.循环步骤3到4 n次(自己设定的参数)。
6.T=αTT=αTT = \alpha T
7.返回步骤2


代码

import matplotlib.pyplot as plt
import math
import random"""
函数里面所有以plot开头的函数都可以注释掉,没有影响
求解的目标表达式为:
y = 10 * math.sin(5 * x) + 7 * math.cos(4 * x)  x belongs to (0,10)
"""def main():plot_obj_func()T_init = 100  # 初始最大温度alpha = 0.90  # 降温系数T_min = 1e-3  # 最小温度,即退出循环条件T = T_initx = random.random() * 10  # 初始化x,在0和10之间y = 10 * math.sin(5 * x) + 7 * math.cos(4 * x)results = []  # 存x,ywhile T > T_min:x_best = x# y_best = float('-inf')  # 设置成这个有可能会陷入局部最优,不一定全局最优y_best = y  # 设置成这个收敛太快了,令人智熄flag = 0  # 用来标识该温度下是否有新值被接受# 每个温度迭代50次,找最优解for i in range(50):delta_x = random.random() - 0.5  # 自变量进行波动# 自变量变化后仍要求在[0,10]之间if 0 < (x + delta_x) < 10:x_new = x + delta_xelse:x_new = x - delta_xy_new = 10 * math.sin(5 * x_new) + 7 * math.cos(4 * x_new)# 要接受这个y_new为当前温度下的理想值,要满足# 1y_new>y_old# 2math.exp(-(y_old-y_new)/T)>random.random()# 以上为找最大值,要找最小值就把>号变成<if (y_new > y or math.exp(-(y - y_new) / T) > random.random()):flag = 1  # 有新值被接受x = x_newy = y_newif y > y_best:x_best = xy_best = yif flag:x = x_besty = y_bestresults.append((x, y))T *= alphaprint('最优解 x:%f,y:%f' % results[-1])plot_final_result(results)plot_iter_curve(results)# 看看我们要处理的目标函数
def plot_obj_func():"""y = 10 * math.sin(5 * x) + 7 * math.cos(4 * x)"""X1 = [i / float(10) for i in range(0, 100, 1)]Y1 = [10 * math.sin(5 * x) + 7 * math.cos(4 * x) for x in X1]plt.plot(X1, Y1)plt.show()# 看看最终的迭代变化曲线
def plot_iter_curve(results):X = [i for i in range(len(results))]Y = [results[i][1] for i in range(len(results))]plt.plot(X, Y)plt.show()def plot_final_result(results):X1 = [i / float(10) for i in range(0, 100, 1)]Y1 = [10 * math.sin(5 * x) + 7 * math.cos(4 * x) for x in X1]plt.plot(X1, Y1)plt.scatter(results[-1][0], results[-1][1], c='r', s=10)plt.show()if __name__ == '__main__':# for i in range(100):main()

运行结果

初始温度T=100T=100T=100
降温系数α=0.90α=0.90\alpha =0.90
每个T里面再循环505050次取当前温度最佳
得到全局最优的概率大概有100%100%100\%
运行得到的最优解:

收敛之快令人发指:


后话

这里不知道改了什么,同样一个目标函数,用遗传算法和模拟退火效率截然不同。大概是弄错了吧2333,毕竟水平有限。这么一对比,似乎退火在解决这种弱智问题上还好用点。不过其实仔细想下,两个算法各自的优缺点还是比较明显的。

遗传算法:优点是能很好的处理约束,能很好的跳出局部最优,最终得到全局最优解,全局搜索能力强;缺点是收敛较慢,局部搜索能力较弱,运行时间长,且容易受参数的影响。(一次放了一堆兔子,品种不好的就把人家丢掉)

模拟退火:优点是局部搜索能力强,运行时间较短;缺点是全局搜索能力差,容易受参数的影响。(一次只放一只喝醉酒的兔子,酒醒之时即是远方)

模拟退火算法(SA)简单介绍,附用python3求解最大值案例相关推荐

  1. java寻优算法_模拟退火算法SA原理及python、java、php、c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径...

    模拟退火算法SA原理及python.java.php.c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径 模拟退火算法(Simulated Annealing,SA)最早的思 ...

  2. 教学优化算法的简单介绍

    目录 摘要 背景 算法 学生初始化 教学阶段 学习阶段 流程总结 优缺点 优点 缺点 一些改进 总结 参考文献 摘要 教学优化算法(Teaching-learning-based optimizati ...

  3. ML与Optimality:最优化理论(GD随机梯度下降/QN拟牛顿法/CG共轭梯度法/L-BFGS/TR置信域/GA遗传算法/SA模拟退火算法)在机器学习中的简介、常用方法、案例应用之详细攻略

    ML与Optimality:最优化理论(GD随机梯度下降/QN拟牛顿法/CG共轭梯度法/L-BFGS/TR置信域/GA遗传算法/SA模拟退火算法)在机器学习中的简介.常用方法.案例应用之详细攻略 目录 ...

  4. 【matlab】模拟退火算法代码分析(附sj.txt文件)

    简介 模拟退火算法得益于材料的统计力学的研究成果.统计力学表明材料中粒子的不 同结构对应于粒子的不同能量水平.在高温条件下,粒子的能量较高,可以自由运动和 重新排列.在低温条件下,粒子能量较低.如果从 ...

  5. 模拟退火算法SA求解连续函数极值

    目录 一.模拟退火算法原理 二.模拟退火算法思想 三.模拟退火算法流程 四.关键参数说明 五.例题 一.模拟退火算法原理 模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却.加温时,固 ...

  6. 模拟退火算法SA参数设置实验记录

    模拟退火算法有4个参数 N:每个温度迭代次数 T:重复降温次数 a:降温系数 t0:初始温度 本文用一个50个城市的TSP问题数据集,用交叉对比的方法调参.一组参数运行200次取平均. 首先调初始温度 ...

  7. 一文搞懂什么是模拟退火算法SImulated Annealing【附应用举例】

    本文参考了很多张军老师<计算智能>的第十章知识. 本文来源:https://blog.csdn.net/qq_44186838/article/details/109181453 模拟退火 ...

  8. 机器学习十大算法的简单介绍

    1.线性回归 (Linear Regression) 2.逻辑回归 (Logistic Regression) 3.决策树 (Decision Tree) 4.支持向量机(SVM) 5.朴素贝叶斯 ( ...

  9. JAVA数据结构与算法【简单介绍】

    前几天去面一个大厂,面试官特别好,面试官说到,我们的学习不能本末倒置,数据结构和算法是程序的基础,如果数据结构你没有学好,你真正意义上不算会写代码.你的代码是各处粘贴,杂乱无章的. 由于现在大多用JA ...

最新文章

  1. 谁干的mysql无密码登录?
  2. 生活中的实验 —— 磁铁的使用
  3. Codeforces Round #740 (Div. 2) F. Top-Notch Insertions 线段树 / 平衡树 + 组合数学
  4. linux不编译设备树,petalinux 编译时报设备树语义错误
  5. OpenStack 认证服务 KeyStone部署(三)
  6. 凯撒密码加密算法python_想偷WiFi?万能钥匙不行?试试用python一键破解!
  7. 平行束滤波fbp_CT平行束和扇形束算法的转换.pptx
  8. 补码1位乘法和补码2位乘法(Booth算法)(三栏式)详解学习
  9. 通过Fildder下载百度音乐里的收费歌曲
  10. 知识图到文本的生成(十一)
  11. 桌面运维常见问题解决办法③
  12. android 打开短信应用,通过短信打开手机应用
  13. vue2.0分页插件官方_Vue 2的最佳和完整分页插件
  14. python种颜色循环_使用matplotlib颜色图进行颜色循环 - python
  15. 啥是jQuery(什么是jQuery)
  16. 储能系统下垂控制,输出电流按虚拟电阻比例分配,并补偿有下垂系数带来的母线压降
  17. 如何应对互联网大数据时代的挑战
  18. 集成阿里云OSS编写AliyunOSSUtil
  19. 客流统计分析系统增强售楼处、4S店飞单管理能力
  20. 由于缺少调试目标“……”,Visual Studio无法开始调试。请生成项目并重试,或者相应地设置OutputPath和AssemblyName属性,使其指向目标程序集的正确位置...

热门文章

  1. 鸡兔同笼,共有头48个,脚132只,求鸡和兔各有多少只?
  2. 推荐几本提高Java代码规范、可读性、健壮性和可维护性的基本经典图
  3. ERP中自定义报表制作流程
  4. 手机游戏地图绘制软件
  5. 杜洋STM32100步回顾总结
  6. BACnet基础入门
  7. 重装WIN7系统后连不上网络怎么办
  8. miRTarBase 数据库简介
  9. JS获取客户端信息(屏幕分辨率、浏览器版本、操作系统版本)
  10. 华为鸿蒙os和小米ov,华为鸿蒙OS和HMS已经备好!就差OV和小米一起吹东风了