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

        写这篇博客的原因是博主本人在看某篇文章的时候,发现自己只是知道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)需要大量资金——通常需要数十亿美元的投资。但中国…

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知识库如何影…

Android Camera压力测试工具

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

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 文档。使用 …

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…

【Cesium】七、设置Cesium 加载时的初始视角

文章目录 一、前言二、实现方法2.1 获取点位、视角2.2 设置 三、App.vue 一、前言 在前面的文章 【Cesium】三、实现开场动画效果 中有提到过 虽然也能回到初始点位但是有一个明显的动画过程。下面方法加载时就是在初始点位 没有动画效果&#xff0c;根据需求选择。 本文参考…

Edge安装问题,安装后出现:Could not find Edge installation

解决&#xff1a;需要再安装&#xff08;MicrosoftEdgeWebView2RuntimeInstallerX64&#xff09;。 网址&#xff1a;https://developer.microsoft.com/zh-cn/microsoft-edge/webview2/?formMA13LH#download 如果已经安装了edge&#xff0c;那就再下载中间这个独立程序安装就…

日期时间选择(设置禁用状态)

目录 1.element文档需要 2.禁用所有过去的时间 3.设置指定日期的禁用时间 <template><div class"block"><span class"demonstration">起始日期时刻为 12:00:00</span><el-date-pickerv-model"value1"type"dat…

【《python爬虫入门教程11--重剑无峰168》】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 【《python爬虫入门教程11--selenium的安装与使用》】 前言selenium就是一个可以实现python自动化的模块 一、Chrome的版本查找&#xff1f;-- 如果用edge也是类似的1.chrome…

系统架构风险、敏感点和权衡点的理解

系统架构是软件开发过程中的关键环节&#xff0c;它决定了系统的可扩展性、稳定性、安全性和其他关键质量属性。然而&#xff0c;架构设计并非易事&#xff0c;其中涉及的风险、敏感点和权衡点需要仔细考虑和处理。本文将详细探讨系统架构风险、敏感点和权衡点的概念&#xff0…

leetcode热题100(79. 单词搜索)dfs回溯 c++

链接&#xff1a;79. 单词搜索 - 力扣&#xff08;LeetCode&#xff09; 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的…

用PicGo向Github图床上传图片,然后通过markdown语言显示图片

目录 下载PicGo软件图床GitHub设置在Markdown中使用图片 下载PicGo软件 先进入Pic官网&#xff0c;然后点击下图中的免费下载 然后点击下载下图中PicGo-Setup-2.4.0-beta.9.exe这个可执行软件 图床GitHub设置 点击PicGo中的图床设置&#xff0c;再点击其中的Github&#xff…