music算法_“要热爱 请深爱”系列(5)浅谈模拟退火算法
黄乐天
浅谈模拟退火算法
背景
在实际生活中, 数学问题中,我们常常会遇到(一定范围内)函数求最值的问题。一般可以用数学方式解答,但如果遇到如下恶心的函数:
它的函数图像是这样的:
我们只好用计算机科学 (说白了就是编程) 来计算了。
对于这种单峰函数,可以使用“爬山算法”来得出结果,即每次在当前最优解附近找一个解,若比当前最优解更优则接受它。
但它的缺点十分明显,就是容易陷入局部最优解,如果遇到下面的
多峰函数:
(我也不知道这g(r)是咋来的)
我们可以使用一种玄学算法——模拟退火
模拟退火是啥?
模拟退火算法(Simulated Annealing,SA)最早的思想是由N. Metropolis等人于1953年提出。1983 年,S. Kirkpatrick 等成功地将退火思想引入到组合优化领域。它是基于Monte-Carlo迭代求解策略的一种随机寻优算法,其出发点是基于物理中固体物质的退火过程与一般组合优化问题之间的相似性。模拟退火算法从某一较高初温出发,伴随温度参数的不断下降,结合概率突跳特性在解空间中随机寻找目标函数的全局最优解,即在局部最优解能概率性地跳出并最终趋于全局最优。模拟退火算法是一种通用的优化算法,理论上算法具有概率的全局优化性能,目前已在工程中得到了广泛应用,诸如VLSI、生产调度、控制工程、机器学习、神经网络、信号处理等领域。
——百度百科
实际上,SA广泛运用于信息学竞赛(Olympiad in Informatics,OI),在OIers(即信竞生)想不出某道数据范围较小的题的正解时用来骗分。
看看它的原理:
模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。根据Metropolis准则,粒子在温度T时趋于平衡的概率为e(-ΔE/(kT)),其中E为温度T时的内能,ΔE为其改变量,k为Boltzmann常数。用固体退火模拟组合优化问题,将内能E模拟为目标函数值f,温度T演化成控制参数t,即得到解组合优化问题的模拟退火算法:由初始解i和控制参数初值t开始,对当前解重复“产生新解→计算目标函数差→接受或舍弃”的迭代,并逐步衰减t值,算法终止时的当前解即为所得近似最优解,这是基于蒙特卡罗迭代求解法的一种启发式随机搜索过程。退火过程由冷却进度表(Cooling Schedule)控制,包括控制参数的初值t及其衰减因子Δt、每个t值时的迭代次数L和停止条件S。
——百度百科
物理?...感觉这段话只有小唐能看懂
用人话来说,这是一种求多峰函数最值的算法。原理是模拟固体降温的过程,并在此过程中产生新解。随着温度的降低,产生新解的变化越来越小,越来越集中在最优解附近。直到温度低至一定的最低温,即“结晶”,则停止此过程,当前的最优解基本上就是全局最优解了。
还不理解?上图!
过程也应该很好理解,直接上动图吧
我们用几个变量来理性理解此过程(以求多峰函数最小值为例)
:常量,模拟退火的初始温度,一般设在
模拟退火的当前温度
常量,模拟退火的目标温度,一般设为
常量,模拟退火的温度变动量,一般比小一点点,乘上得到下一个温度
当前得到的最优解结果(当前求到的函数最小值)
新得到的解
上一个被接受的解
解的变化量,即的结果
那么模拟退火的具体过程就是,由初温开始,每次乘以得到当前温度,若$t
在这个过程中,我们在上一被接受的解的基础上随机浮动产生新解。但是注意,每次的浮动大小与当前温度有关,若小则浮动相对也更小。我们通过一系列随机数的操作再乘来得出浮动大小,最后加上得出新解。
接着我们计算由所得的结果(求函数值),减去得到解的变动量。若,则我们遇到了一个更小的结果,即更优的解,那么当然要接受它——更新变为新解的结果,变为。如果,则这是个更劣的解,我们当然不要更新,那是否接受这个解(更新)呢?我们使用Metropolis接受准则,对于接受这个解,它的概率是,再判断这个概率是否大于一个大于、小于等于的随机数来接受即可。
对于这个概率的理解,我们引用一位神犇的思想:对于,如果它较大,就说明我们遇到了一个非常劣的解,则接受它的概率极小,因为很小;反之接受的概率较大,因为相对较大。对于,随时间增加而减小,所以用来除以。而且,对于整个式子,较大的时候我们会接受大部分解,较小时只会接受较小的解。
例题/C++代码实现
如果看不懂代码,可以在菜鸟教程学习基础语法就绝对能看懂了,当然我自己也会加上详细注释。
例题:UVA10228 A Star not a Tree?
原题面是英文的,我写一下中文题面吧...
题目描述
给定一个边形所有顶点坐标,求其费马点到所有顶点距离和
费马点是指到多边形所有顶点距离和最小的点
输入格式
第一行一个正整数,其后行,每行两个整数。
输出格式
一行,即费马点到所有顶点距离和,精确到整数。
题目分析
我们可以通过模拟退火来找出其费马点,只用改变每个解(坐标)对结果的计算即可。
原来我们举的例子是计算函数,把解直接代入即可。而在这题中,计算结果的方式变为计算此坐标到每个顶点的距离之和。计算距离的方式应该不用我多说,就是利用勾股定理求欧几里得距离,则到的距离为。
核心代码如下:
//头文件等不展示了//...和/*...*/均为注释//定义变量int n;//int为整型变量,储存一个[-2^32,2^31-1]的整数,这里表示定义一个整型变量n,即多边形边的数量double ans=1e18;//double是“双精度浮点数”,即较为精确的小数,储存范围很大//这里把ans的初始值定为10^18,因为取最小值,后面直接比较就好double px[105],py[105];//double类型数组,一个数组(如px)可储存105个double类型的数,因为n最大为100//如需访问第i个点的x轴上的值,为px[i]const double eps=1e-15;//定义常量eps,const为常量关键字double calc(double x,double y)//计算此坐标到所有顶点的距离和{//这是一个“double”的函数,返回值则也为double类型 double res=0;//储存结果的变量 for(int i=1;i<=n;i++)//i从1到n循环 s+=sqrt((x-px[i])*(x-px[i])+(y-py[i])*(y-py[i]));//计算距离,sqrt是开方函数 return res;//返回结果}void SA()//模拟退火的核心{//这是个"void"的函数,没有像calc一样的返回值return res //rand()是随机函数,一个区间[0,32767]的整数 //=是赋值操作,a=b表示把b赋值给a double x=rand()%10000,y=rand()%10000;//最初始的解随机得出 //%是取余 double t=3000;//模拟退火的温度 while(t>eps)//温度大于末温就一直循环 {//while(condition){...}表示只要满足condition就执行"..." //RAND_MAX是rand()能达到的最大值,即32767 double xx=x+(rand()*2-RAND_MAX)*t,yy=y+(rand()*2-RAND_MAX)*t;//随机操作再乘t //↑计算新解e double now=calc(xx,yy);//计算结果 double dt=now-ans;//计算e_k if(dt<0)x=xx,y=yy,ans=now;//找到更优的解,则接受它 else if(exp(-dt/t)>rand()/(RAND_MAX*1.0)/*rand()/RAND_MAX一定>0且<=1*/)//Metropolis准则 x=xx,y=yy;//接受这个解,但不要更新ans,因为它不是最优解 t*=0.996;//t乘上Δ }//+=,*=都也是赋值操作,如a+=b表示把a+b赋值给a}//输入和输出变量都在下面的主函数main()里,每个C/C++程序都要有一个main函数,所有操作都在里面//包括上面的SA()也会在main()被调用//int main(){...}//这里只展示核心代码(模拟退火部分),主函数就不写在这里了//完整代码可以找我要
后记
写这篇文章只是为了让你们了解模拟退火的原理及过程,真正在实际生活应用可能还得等到大学或者工作的研究。当然,在别人问你求函数峰值的数学问题时,也可以拿出电脑跑一遍模拟退火来炫技[斜眼笑]...
如果有任何不理解的地方可以来问我,挂几个联系方式:
QQ:3038564494
邮箱:adayhlt526@gmail.com
参考资料
浅谈玄学算法——模拟退火 by M_sea(https://www.luogu.com.cn/blog/m-sea/qian-tan-SA)
模拟退火-维基百科(https://zh.wikipedia.org/wiki/模拟退火) (如果wiki上不去可以找我要图片)
模拟退火算法-百度百科(https://baike.baidu.com/item/模拟退火算法)
END
“要热爱 请深爱”系列往期精彩回顾
(1)2025——Music!嗨起来!
(2)几道你第一眼肯定做错的题
(3)那些英语“白大象”
(4)世界之大,远不及他心中碧海苍梧
扫码关注更多精彩
策划、审定:班主任赵老师编辑:黄乐天、黄乐天妈妈、肖刘畅妈妈
music算法_“要热爱 请深爱”系列(5)浅谈模拟退火算法相关推荐
- 叫你一声老公 请深爱你的宝贝
题记:小爱:"Rain,你算我的男朋友吗?" Rain:"不算,我算你老公!" 小爱: (可是你还没有表白呢...) 老公,不知道什么时候开始,我开始对你用这么 ...
- 异地恋,如果爱,请深爱
如果你们在一个班,一起自习,一起上课下课,一起泡茶一起记笔记,离开一秒也无所谓,还有下一秒;如果你们在一个学校,可以一起去图书馆,一起去露天电影场,一起进食堂一起看星星看月亮,一起跑八百一起手牵手进小 ...
- 浅谈PPO算法-玩转月球登陆
浅谈PPO算法-玩转月球登陆 前言 github 什么是Actor-Critic? Actor-Critic代码 ppo算法 实现 前言 总感觉强化学习公式真难学,也难表达心中所想,我还是白话强化学习 ...
- 《MATLAB智能算法30个案例》:第20章 基于遗传模拟退火算法的聚类算法
<MATLAB智能算法30个案例>:第20章 基于遗传模拟退火算法的聚类算法 1. 前言 2. MATLAB 仿真示例 3. 小结 1. 前言 <MATLAB智能算法30个案例分析& ...
- std中稳定排序算法_敏哥:深挖亚马逊A9算法中的广告搜索排序
大家好,我是敏哥.最近国外疫情肆虐,牵动着所有跨境电商人的心.今天美国的确诊人数已经突破了33万人,每天以3万左右的确诊数量在增加,就连老虎也未能幸免. 国外疫情肆虐,对于跨境电商人而言并不是一个很好 ...
- java python算法_用Python,Java和C ++示例解释的排序算法
java python算法 什么是排序算法? (What is a Sorting Algorithm?) Sorting algorithms are a set of instructions t ...
- 木桶排序算法_【生信常识】二代测序的比对算法浅析
前言 本来我只打算将孟大哥的视频内容做一个文字版的概述,然后孟大哥说,不如再加一个算法推导吧,然后我就开始看多一些东西,然后就想着把孟大哥视频里面大概提及然后没有仔细讲的部分做一些补充,完善整个体系的 ...
- 快速排序 c++_算法浅谈——分治算法与归并、快速排序(附代码和动图演示)
本文始发于个人公众号:TechFlow 在之前的文章当中,我们通过海盗分金币问题详细讲解了递归方法. 我们可以认为在递归的过程当中,我们通过函数自己调用自己,将大问题转化成了小问题,因此简化了编码以及 ...
- sha256算法_腾讯云提供免费证书已支持使用ECC算法 大幅度节省证书流量
目前大多数网站使用的都是基于RSA非对称加密算法签发的数字证书,而在部署加密协议后服务器开销亦会增加. 对大型网站而言如果有能够降低服务器开销的方法那自然也得用上,所以现在很多网站也开始使用ECC数字 ...
最新文章
- 三星a5009Android6.0,三星A5009原版系统刷机包_三星A5009最新升级包线刷包和root
- 经典重温:卡尔曼滤波器介绍与理论分析
- C# 3.0入门系列(二)
- 【计算机组成原理】定点除法运算
- mapreduce之partition分区
- 独家 | 蚂蚁金服TRaaS技术风险防控平台解密
- SocketAsyncEventArgs
- 蓝奏云数值验证码识别,python调用虹鱼图灵识别插件,超高正确率
- VS2005+SQL2005 Reporting Service动态绑定报表(Web)
- java压缩单个文件
- 如何将百度文库中不能复制的文字复制下来
- 用友OA/NC/NCCloud漏洞集合
- 大班音乐机器人反思_大班音乐活动lbrack;机器人rsqb;
- MATLAB 设置纵轴显示范围、科学记数法
- 端口映射和端口转发区别是什么
- Android中一个app启动另一个app|从浏览器打开app
- mybatis-plus clickhouse支持分页
- Excel中数据透视表数据源更新的三种方式
- 二级日语语法总汇(2)
- centOS7重启网卡失败
热门文章
- 数据结构基础概念及算法概念
- python idle在哪_python安装包里idle在哪
- matlab factor函数,matlab中因子分析的函数factoran如何使用??
- 很多工程师问ESP32彩屏能不能在arduino上面来玩,这个是没有问题的
- 轮询没有收到的可能性_轮询(Polling)是什么?
- ad16怎么画弧线_如何告别“千人一面”?手把手教你抠细节,画不一样人脸
- 全球首个知识增强千亿大模型鹏城-百度·文心发布
- Palo Doris不会用?(基础指南)
- win7系统备份还原软件_收藏备用!操作系统的快速备份与还原技巧
- 逆向-002-iOS重签名