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

        写这篇博客的原因是博主本人在看某篇文章的时候,发现自己只是知道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.mzph.cn/bicheng/65902.shtml

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

相关文章

【0x0037】HCI_Write_Link_Supervision_Timeout命令详解

目录 一、命令概述 二、命令格式及参数说明 2.1. HCI_Write_Link_Supervision_Timeout 命令格式 2.2. Handle 2.3. Link_Supervision_Timeout 三、生成事件及参数 3.1. HCI_Command_Complete 事件 3.2. Status 3.3. Handle 四、命令执行流程 4.1. 命令准备阶段 4.…

【杂谈】-DeepSeek如何以560万美元突破成本障碍

DeepSeek如何以560万美元突破成本障碍 文章目录 DeepSeek如何以560万美元突破成本障碍1、高效人工智能的经济学2、实现不可能的工程3、人工智能生态系统的连锁反应 传统的人工智能观点认为&#xff0c;构建大型语言模型 (LLM)需要大量资金——通常需要数十亿美元的投资。但中国…

Android 系统 Activity 系统层深度定制的方法、常见问题以及解决办法

Android 系统 Activity 系统层深度定制的方法、常见问题以及解决办法 目录 引言Activity 系统层概述Activity 系统架构图Activity 系统层深度定制的方法 4.1 自定义 Activity 生命周期4.2 自定义 Activity 启动流程4.3 自定义 Activity 转场动画4.4 自定义 Activity 窗口管理4…

TIOBE 指数 12 月排行榜公布,VB.Net排行第九

IT之家 12 月 10 日消息&#xff0c;TIOBE 编程社区指数是一个衡量编程语言受欢迎程度的指标&#xff0c;评判的依据来自世界范围内的工程师、课程、供应商及搜索引擎&#xff0c;今天 TIOBE 官网公布了 2024 年 12 月的编程语言排行榜&#xff0c;IT之家整理如下&#xff1a; …

vs2022编译opencv 4.10.0

参考&#xff1a;Windosw下Visual Studio2022编译OpenCV与参考区别在于&#xff0c;没有用cmake GUI&#xff0c;也没有创建build目录&#xff0c;直接用vs2022打开了C:\code\opencv目录&#xff0c;即CMakeLists.txt所在根目录。没有修改默认下载地址&#xff0c;采用手动下载…

未来教育:AI知识库如何重塑学习体验

在科技日新月异的今天&#xff0c;教育领域正经历着前所未有的变革。人工智能&#xff08;AI&#xff09;技术的快速发展&#xff0c;特别是AI知识库的广泛应用&#xff0c;正在重塑我们的学习体验&#xff0c;使之变得更加高效、个性化和智能化。本文将深入探讨AI知识库如何影…

c#实现繁体转简体的方法

在软件开发中&#xff0c;使用了Syncfusion第三方控件&#xff0c;Syncfusion通过资源库实现汉化&#xff0c;但Syncfusion提供的资源库SfResources.zh.resx为繁体的&#xff0c;通过研究发现了使用C#完成繁体到简体转换&#xff0c;在 C# 中&#xff0c;处理繁体转简体的任务可…

Android Camera压力测试工具

背景描述&#xff1a; 随着系统的复杂化和业务的积累&#xff0c;日常的功能性测试已不足以满足我们对Android Camera相机系统的测试需求。为了确保Android Camera系统在高负载和多任务情况下的稳定性和性能优化&#xff0c;需要对Android Camera应用进行全面的压测。 对于压…

大中厂面试经验分享:如何使用消息队列(MQ)解决系统问题

在大中型互联网公司中&#xff0c;消息队列&#xff08;MQ&#xff09;作为一种关键的分布式系统组件&#xff0c;广泛应用于解决系统中的高并发、异步处理、解耦等问题。 在面试中&#xff0c;尤其是针对后端工程师或系统架构师的职位&#xff0c;面试官常常会通过询问消息队列…

C# 设计模式(结构型模式):组合模式

C# 设计模式&#xff08;结构型模式&#xff09;&#xff1a;组合模式 在软件设计中&#xff0c;有时我们需要处理的是一组对象&#xff0c;而这些对象既可以是单独的元素&#xff0c;也可以是由多个子元素组成的复合体。这时&#xff0c;组合模式&#xff08;Composite Patte…

JDK8源码分析Jdk动态代理底层原理

本文侧重分析JDK8中jdk动态代理的源码&#xff0c;若是想看JDK17源码分析可以看我的这一篇文章 JDK17源码分析Jdk动态代理底层原理-CSDN博客 两者之间有着略微的差别&#xff0c;JDK17在JDK8上改进了不少 目录 源码分析 过程 生成的代理类大致结构 本文侧重分析JDK8中jdk…

Spire.PDF for .NET【页面设置】演示:向 PDF 添加平铺背景图像

平铺背景通常是指用一个或多个小图像重复填充的背景。在本文中&#xff0c;您将学习如何在 PDF 中平铺图像&#xff0c;并使用 C# 和 VB.NET 为您的 PDF 创建平铺背景。 Spire.PDF for .NET 是一款独立 PDF 控件&#xff0c;用于 .NET 程序中创建、编辑和操作 PDF 文档。使用 …

大带宽服务器和普通服务器相比较的优势

服务器作为各个企业线上业务中重要的网络设备&#xff0c;能够在网络中为其他客户机提供计算或者是应用服务&#xff0c;不同的应用场景中也会运用不同的服务器类型&#xff0c;本文就来为大家介绍一下大带宽服务器与普通服务器相比较来说的优势都有哪些&#xff01; 大带宽服务…

如何通过设置失效时间清除本地存储的数据

一、使用localStorage和时间戳&#xff08;JavaScript&#xff09; 1. 原理 localStorage是浏览器提供的一种在本地存储数据的方式&#xff0c;数据没有过期时间限制。但是可以通过自己记录时间戳来模拟数据过期的功能。在存储数据时&#xff0c;同时存储一个时间戳&#xff…

ImageNet 2.0?自动驾驶数据集迎来自动标注新时代

引言&#xff1a; 3DGS因其渲染速度快和高质量的新视角合成而备受关注。一些研究人员尝试将3DGS应用于驾驶场景的重建。然而&#xff0c;这些方法通常依赖于多种数据类型&#xff0c;如深度图、3D框和移动物体的轨迹。此外&#xff0c;合成图像缺乏标注也限制了其在下游任务中的…

stm32 智能语音电梯系统

做了个stm32智能语音控制的电梯模型&#xff0c;总结一下功能&#xff0c;源码用ST的HAL库写的&#xff0c;整体流程分明。 实物图 这个是整个板子的图片&#xff0c;逻辑其实并不复杂&#xff0c;只是功能比较多&#xff0c;在我看来都是一些冗余的功能&#xff0c;但也可能是…

多模态论文笔记——CogVLM和CogVLM2

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍多模态模型的LoRA版本——CogVLM和CogVLM2。在SD 3中使用其作为captioner基准模型的原因和优势。 文章目录 CogVLM论文背景VLMs 的任务与挑战现有方法及…

【react】Redux的设计思想与工作原理

Redux 的设计理念 Redux 的设计采用了 Facebook 提出的 Flux 数据处理理念 在 Flux 中通过建立一个公共集中数据仓库 Store 进行管理&#xff0c;整体分成四个部分即: View &#xff08;视图层&#xff09;、Action &#xff08;动作&#xff09;、Dispatcher (派发器)、Stor…

PCB层叠结构设计

PCB层叠结构设计 层叠结构设计不合理完整性相关案例&#xff1a;在构成回流路径时&#xff0c;由于反焊盘的存在&#xff0c;使高速信号回流路径增长&#xff0c;造成信号回流路径阻抗不连续&#xff0c;对信号质量造成影响。 PCB层叠结构实物&#xff1a;由Core 和 Prepreg&a…

爬虫在分析网站结构时的注意事项及代码示例

在进行网络爬虫的开发时&#xff0c;准确分析目标网站的结构是至关重要的一步。这不仅关系到爬虫的效率和效果&#xff0c;还涉及到是否能够合法合规地获取数据。本文将探讨在分析网站结构时需要注意的几个关键点&#xff0c;并提供相应的代码示例。 1. 网站的响应方式 首先&…