【算法】模拟退火算法学习记录

        写这篇博客的原因是博主本人在看某篇文章的时候,发现自己只是知道SGD这个东西,但是到底是个啥不清楚,所以百度了一下,然后在通过博客学习的时候看到了退火两个字,想到了本科做数模比赛的时候涉猎过,就上bilibili搜索讲解视频学习了退火的算法,感觉看完之后收获还蛮大的,所以写下这篇博客作为记录。话不多说,上正文——

一、算法介绍

        模拟退火算法(Simulated Annealing, SA)是一种概率型优化算法,它受到物理学中固体物质退火过程的启发。退火过程是指将固体加热后再慢慢冷却,使其达到能量最低的稳定状态。模拟退火算法将这一过程应用于组合优化问题,通过模拟退火过程来寻找问题的全局最优解。

        举个栗子,逼近下图函数的最大值,利用退火的思想就是经过多次迭代(退火),逼近函数上的A点。

         因为模拟退火算法借鉴的是固体的退货原理,相信理科生都能很快get到,温度越高,固体内部的分子能量越高,均处于快速无序的运动,当温度慢慢降低时,分子的能量降低,慢慢地趋于有序,到最后达到常温的时候,能量达到最小,此时内部的分子最为稳定。从前面这段话我们可以解析出几个点——

  • 温度越高,分子越乱,放在退火算法里就是温度越高,x的跳变范围越大
  • 温度变化是缓慢的,特别特别慢那种
  • 温度不再变化之后,也就是趋于有序,放在退火算法里也就是达到了最优 

二、算法大框架

模拟退火算法本质上就是一个循环算法。(博主本人在练习代码的时候,感觉核心有点像暴力枚举,啊哈哈哈哈)

  1. 设定一个初始的温度T
  2. 每个循环就是退火一次
  3. 降低T(通过将T和一个降温系数相乘来达到慢慢降温的效果)
  4. T无限接近于0的时候退出循环

将上面的流程以伪代码的形式展示:

double T; //初始温度
double dt; //降温系数,小于1但是趋于1,类似0.99这种
const double eps = 1e-4; //用于判断T是否趋于0while(T > eps)
{//退火流程//……T = T * dt; //降温
}

三、退火算法详解

        这一部分主要是来详细介绍模拟退火算法的核心部分。首先需要现在定义域中随机取一个自变量x,这样根据函数又可以得到f(x)。下一步,自变量根据当前温度进行随机变化得到x0,又得到f(x0)。最后,根据我们的具体需要来决定是一定接受还是按概率接受。

        可能有的同学看完上面这段脑袋都大了,我们就拿上面的函数求最大值来举个栗子——

        图中的x就是随机选择的一个自变量,x0是根据当前温度随机跳变后的自变量。在俺们这个例子中,我们是想要找到函数的最大值,如果随机跳变后的自变量对应的函数值大于当前自变量的函数值是百分百接受的,也就是直接进行数据更新,也就是上图中从x跳变到x1的情况;但是如果跳变后的自变量对应的函数值小于当前自变量的函数值,这样的情况是按概率接受的(这种情况也很好理解,如果小于就直接拒绝,这样很容易就陷入到局部最优了)。

        那么这个按概率接受又是啥嘞?我们用一个公式来表示,具体的推导大家感兴趣可以自己找一下,俺在这里就不详细展开了。

e^{\tfrac{\Delta f}{KT}}

其中,\Delta f是函数值的变化量,K是一个物理学常数,T是当前温度。根据指数函数的性质,整个指数部分小于0时函数值是小于1的,才满足概率小于等于1的条件,所以同学们在判断接受的时候要尤其注意指数部分的形式。

所以总结一下就是:

  • 随机跳变后的函数值如果结果更好,我们一定接受它(即x=x0,f(x)=f(x0))
  • 随机跳变后的函数值如果结果更差,我们以​的概率e^{\tfrac{\Delta f}{KT}}接受它

 将模拟退火算法以伪代码形式展示:

//三板斧
double T = 2000; //初始温度
double dt = 0.993;  //退火率(温度下降率)
const double eps = 1e-14;  //用来判定T是否无限趋近于0//函数,传入自变量参数x,得到f(x)
double func(double x)
{return f(x);//函数内部的功能具体问题具体分析
}//退火算法的核心
void SA()
{//先随机生成一个x值,这里的x值不是说只能是一个参数,可以是一组参数,也是具体情况具体分析double x = rand();//得到随机数对应的f(x)double y = func(x);//退火算法开始while (T > eps){//先算出随机跳变后的自变量,可以是减小,也可以增大double dx = x + (2 * rand() - RAND_MAX) * T; //因为是与当前温度相关的跳变,所以要乘以Tdouble dy = func1(dx);//计算得到跳变后自变量对应的函数值//退火函数的关键!!if (满足百分百接受的条件) {y = dy;x = dx;}else if(exp((y-dy)/T) * RAND_MAX > rand())//否则按一定概率接受{y = dy;x = dx;}else{T = T * dt; //温度缓慢降低}}cout << x << endl; //打印结果
}

四、应用举例

        利用模拟退火算法来实现计算一个数的平方根,给出完整的c++代码,方便同学们学习调试。(因为博主也是从其他博主那里学习的,我感觉这块的代码还有蛮多可以改进的,因为c++很少使用全局变量,会破坏封装性,而且使得代码不好迁移)

#include<iostream>
using namespace std;double n;
//三板斧
double T = 2000; //初始温度
double dt = 0.993;  //退火率(温度下降率)
const double eps = 1e-14;  double func1(double x)
{return abs(x * x - n);
}void SA1()
{//先随机生成一个x值double x = rand();//得到随机数对应的f(x)double y = func1(x);while (T > eps){//先算出x的跳变数,可正可负double dx = x + (2 * rand() - RAND_MAX) * T;//保证dx为正数,因为只有正数才有平方根while (dx < 0){dx = x + (2 * rand() - RAND_MAX) * T;}double dy = func1(dx);//退火函数的关键!!//需要计算得到的func函数值足够小if (dy < y) //当得到的函数值小于原来的函数值时百分百接受 {y = dy;x = dx;}else if(exp((y-dy)/T) * RAND_MAX > rand())//否则按一定概率接受{y = dy;x = dx;}else{T = T * dt;}}cout << x << endl;
}void testSA1()
{cout << "请输入要计算的数:" << endl;cin >> n;SA1();
}int main()
{testSA1();return 0;
}

        整体的流程跟前两点讲的是完全吻合的,同学们可以结合着前面的理论内容、代码以及注释来理解学习,整个的学习脉络还是非常清楚的。

        模拟退火算法就先写到这,有任何问题欢迎同学们指出,大家一起学习进步嗷~

参考:

详解随机梯度下降法(Stochastic Gradient Descent,SGD)_随机梯度下降公式-CSDN博客

速通模拟退火 - 分享今天心情

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/500882.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MATLAB第111期】基于MATLAB的sobol全局敏感性分析方法二阶指数计算

【MATLAB第111期】基于MATLAB的sobol全局敏感性分析方法二阶指数计算 一、简介 在MATLAB中计算Sobol二阶效应指数通常涉及到全局敏感性分析&#xff08;Global Sensitivity Analysis, GSA&#xff09;&#xff0c;其中Sobol方法是一种流行的技术&#xff0c;用于评估模型输入…

android studio android sdk下载地址

android studio安装后&#xff0c;因为公司网络原因&#xff0c;一直无法安装android sdk 后经过手机网络&#xff0c;安装android sdk成功如下&#xff0c;也可以手动下载后指定android sdk本地目录 https://dl.google.com/android/repository/source-35_r01.zip https://dl…

“AI人工智能软件开发公司:创新技术,引领未来

大家好&#xff01;今天我们来聊聊一个充满未来感的话题——AI人工智能软件开发公司。这个公司&#xff0c;用大白话说&#xff0c;就是专门研究和开发人工智能软件的地方&#xff0c;它们用最新的技术帮我们解决问题&#xff0c;让生活和工作变得更智能、更便捷。听起来是不是…

ACL的注意事项

ACL只对数据进行抓取和匹配&#xff0c;ACl本身不对数据做拒绝和允许的操作&#xff0c;只有在接口方向上应用后才对数据进行拒绝或允许的操作。 ACl只在packetfilter包过滤时默认动作是允许&#xff0c;这个时候至少需要有一条deny规则&#xff0c;否则全都是允许的规则&…

gitlab 还原合并请求

事情是这样的&#xff1a; 菜鸡从 test 分支切了个名为 pref-art 的分支出来&#xff0c;发布后一机灵&#xff0c;发现错了&#xff0c;于是在本地用 git branch -d pref-art 将该分支删掉了。之后切到了 prod 分支&#xff0c;再切出了一个相同名称的 pref-art 分支出来&…

webserver的http实现

1、用了状态机&#xff0c;为什么要用状态机&#xff1f; 在逻辑处理模块中&#xff0c;响应的http请求采用主从状态机完成&#xff0c; 传统的控制流程都是按照顺序执行的&#xff0c;状态机能够处理任意顺序的事件&#xff0c;并能提供有意义的响应--即使这些事件发生的顺序和…

C语言面的向对象编程(OOP)

如果使用过C、C#、Java语言&#xff0c;一定知道面向对象编程&#xff0c;这些语言对面向对象编程的支持是语言级别的。C语言在语言级别不支持面向对象&#xff0c;那可以实现面向对象吗&#xff1f;其实面向对象是一种思想&#xff0c;而不是一种语言&#xff0c;很多初学者很…

Qt监控系统放大招/历经十几年迭代完善/多屏幕辅屏预览/多层级设备树/网络登录和回放

一、前言说明 近期对视频监控系统做了比较大的更新升级&#xff0c;主要就是三点&#xff0c;第一点就是增加了辅屏预览&#xff0c;这个也是好多个客户需要的功能&#xff0c;海康的iVMS-4200客户端就有这个功能&#xff0c;方便在多个屏幕打开不同的视频进行查看&#xff0c…

基于feapder爬虫与flask前后端框架的天气数据可视化大屏

# 最近又到期末了&#xff0c;有需要的同学可以借鉴。 一、feapder爬虫 feapder是国产开发的新型爬虫框架&#xff0c;具有轻量且数据库操作方便、异常提醒等优秀特性。本次设计看来利用feapder进行爬虫操作&#xff0c;可以加快爬虫的速率&#xff0c;并且简化数据入库等操作…

数据挖掘——模型的评价

数据挖掘——模型的评价 模型的评价混淆矩阵ROC曲线如何构建ROC曲线 模型过分拟合和拟合不足减少泛化误差 模型的评价 混淆矩阵 准确率 a d a b c d \frac{ad}{abcd} abcdad​ T P T N T P T N F P F N \frac{TPTN}{TPTNFPFN} TPTNFPFNTPTN​ 其他度量&#xff1a; …

庐山派K230学习日记1 从点灯到吃灰

1 简介​ 庐山派以K230为主控芯片&#xff0c;支持三路摄像头同时输入&#xff0c;典型网络下的推理能力可达K210的13.7倍&#xff08;算力约为6TOPS&#xff09;。支持CanMV&#xff0c;可作为AI与边缘计算平台 K230简介 K230芯片集成了两颗RISC-V处理器核心&#xff0c;双核…

活动预告 |【Part2】Microsoft 安全在线技术公开课:安全性、合规性和身份基础知识

课程介绍 通过参加“Microsoft 安全在线技术公开课&#xff1a;安全性、合规性和身份基础知识”活动提升你的技能。在本次免费的介绍性活动中&#xff0c;你将获得所需的安全技能和培训&#xff0c;以创造影响力并利用机会推动职业发展。你将了解安全性、合规性和身份的基础知…

【PCIe 总线及设备入门学习专栏 4.5 -- PCIe Message and PCIe MSI】

文章目录 PCIe Message 与 MSIPCIe Message 和 MSI 的作用与关系MSI 的配置与寄存器MSI 和 ARM GIC 的关系示例&#xff1a;MSI 在 ARM GIC 的实际应用总结 PCIe Message 与 MSI 本文将介绍 PCIe message 的作用以及message 与 MSI 的关系&#xff0c;再介绍 MSI 如何配置以及…

C++11右值与列表初始化

1.列表初始化 C98传统的{} C98中一般数组和结构体可以用{}进行初始化。 struct Point {int _x;int _y; }; int main() {int array1[] { 1, 2, 3, 4, 5 };int array2[5] { 0 };Point p { 1, 2 };return 0; } C11中的{} C11以后统一初始化方式&#xff0c;想要实现一切对…

设计模式 创建型 建造者模式(Builder Pattern)与 常见技术框架应用 解析

单例模式&#xff08;Singleton Pattern&#xff09;&#xff0c;又称生成器模式&#xff0c;是一种对象构建模式。它主要用于构建复杂对象&#xff0c;通过将复杂对象的构建过程与其表示分离&#xff0c;使得同样的构建过程可以创建出具有不同表示的对象。该模式的核心思想是将…

什么是Redis哨兵机制?

大家好&#xff0c;我是锋哥。今天分享关于【什么是Redis哨兵机制&#xff1f;】面试题。希望对大家有帮助&#xff1b; 什么是Redis哨兵机制&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Redis 哨兵&#xff08;Sentinel&#xff09;机制是 Redis 提…

全国计算机设计大赛大数据主题赛(和鲸赛道)经验分享

全国计算机设计大赛大数据主题赛&#xff08;和鲸赛道&#xff09;经验分享 这是“和鲸杯”辽宁省普通高等学校本科大学生计算机设计竞赛启动会汇报—大数据主题赛的文档总结。想要参加2025年此比赛的可以借鉴。 一、关于我 人工智能专业 计赛相关奖项&#xff1a; 2022年计…

STM32 + 移远EC800 4G通信模块数传

一、4G模块简述 EC800M-CN 是移远通信&#xff08;Quectel&#xff09;推出的一款高性能、超小尺寸的 LTE Cat 1 无线通信模块&#xff0c;专为 M2M&#xff08;机器对机器&#xff09;和 IoT&#xff08;物联网&#xff09;应用设计。它具有以下主要特点&#xff1a; 通信速率…

标准库以及HAL库——按键控制LED灯代码

按键控制LED本质还是控制GPIO,和点亮一个LED灯没什么区别 点亮一个LED灯&#xff1a;是直接控制输出引脚&#xff0c;GPIO初始化推挽输出即可 按键控制LED&#xff1a;是按键输入信号从而控制输出引脚&#xff0c;GPIO初始化推挽输出一个引脚以外还得加一个GPIO上拉输入 但是…

springboot525基于MVC框架自习室管理和预约系统设计与实现(论文+源码)_kaic

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装自习室管理和预约系统软件来发挥其高效地信息处理的作用&am…