数学建模常用算法-模拟退火算法

一、模拟退火算法

模拟退火的灵感来源于物理中的 “退火过程”—— 将金属加热到高温后,缓慢冷却,金属原子会在热能作用下自由运动,逐渐形成能量最低的稳定结构。算法将这一过程抽象为数学模型:

  • “温度 T”:对应物理中的温度,控制算法探索新解的 “自由度”—— 温度越高,越容易接受较差的解,帮助跳出局部最优;温度越低,越倾向于接受更优解,逐渐收敛到稳定解。
  • “能量 E”:对应优化问题中的目标函数值(如函数值、路径长度等),算法的目标是找到 “能量最低” 的状态(即目标函数的最优解)。
  • “冷却策略”:温度随迭代逐步降低的规则,决定了算法的探索效率和收敛速度。

二、核心原理:Metropolis 接受准则

模拟退火算法的核心是Metropolis 接受准则—— 它决定了算法是否接受一个新生成的解,即使这个解比当前解更差。具体规则如下:

  1. 设当前解为\(x\),对应的目标函数值为\(f(x)\);新生成的解为\(x_1\),对应的函数值为\(f(x_1)\)。
  1. 若新解更优(如求最小值时\(f(x_1) < f(x)\)),则直接接受新解,更新当前解为\(x_1\)。
  1. 若新解较差(如求最小值时\(f(x_1) > f(x)\)),则以概率\(P\)接受新解:

\(P = \exp\left( \frac{f(x) - f(x_1)}{T} \right)\)

    • 温度\(T\)越高,\(P\)越大,越容易接受较差解;
    • 温度\(T\)越低,\(P\)越小,越难接受较差解;
    • 当\(T \to 0\)时,\(P \to 0\),算法仅接受更优解,收敛到稳定状态。

三、代码逐行解析:从框架到细节

结合你提供的模拟退火算法框架,我们逐部分拆解代码逻辑,理解每一步的作用和设计思路。

1. 算法参数初始化

double T = 2000; // 初始温度:控制初始探索范围double dT = 0.99; // 温度衰减系数:控制冷却速度double eps = 1e-14; // 温度下限:算法终止条件
  • 初始温度\(T\):通常设为较大值(如 2000、1000),保证初始阶段有足够的 “自由度” 探索解空间,避免过早陷入局部最优。
  • 衰减系数\(dT\):一般取 0.95~0.99 之间的小数,系数越接近 1,温度下降越慢,探索越充分,但迭代次数越多;系数越小,冷却越快,可能导致探索不充分。
  • 温度下限\(eps\):当温度低于该值时,算法基本不再接受较差解,此时可终止迭代,输出当前最优解。

2. 目标函数定义

// 用自变量计算函数值,支持单变量或多变量(如f(x,y,z))double func(int x, ... ) {// 此处根据具体问题实现目标函数计算double ans = ....... // 例:若求f(x)=x²的最小值,ans = x*x;return ans;}
  • 这是算法的 “核心输入”,需根据具体建模问题定义。例如:
    • 若求解函数\(f(x) = x^2 - 4x + 5\)的最小值,func需返回\(x^2 - 4x + 5\);
    • 若解决 TSP 问题,func需计算当前路径的总长度(输入为城市序列,输出为路径和)。
  • 支持多变量优化(如\(f(x,y)\)),只需在参数列表中添加变量(如func(int x, int y, ...)),后续新解生成和更新时同步处理即可。

3. 初始解生成

// 生成初始解(随机值)double x = rand(); // 初始自变量x0(单变量情况)double f = func(x,...); // 初始解对应的目标函数值f(x0)
  • 初始解通常随机生成(利用rand()函数),保证解的随机性,避免初始位置对结果的影响。
  • 若问题有明确的解空间限制(如\(x \in [0, 100]\)),需在初始生成时添加约束(如x = rand() % 101),或后续通过定义域检查修正。

4. 核心迭代:退火过程

while(T > eps) { // 温度未降到下限,持续迭代// 步骤1:生成新解x1(幅度与温度正相关)double dx = (2*rand() - RAND_MAX) * T;// 解释:(2*rand() - RAND_MAX)生成[-RAND_MAX, RAND_MAX]的随机数,// 除以RAND_MAX后范围变为[-1, 1],再乘以T,使新解的探索幅度随温度降低而减小。// 步骤2:定义域检查(可选,根据问题需求添加)while(x + dx > 上限 || x + dx < 下限) { // 若新解超出可行域dx = (2*rand() - RAND_MAX) * T; // 重新生成新解,直到符合要求}double x1 = x + dx; // 最终合法的新解// 步骤3:计算新解的目标函数值double f1 = func(x1, ...); // f1 = f(x1)// 步骤4:Metropolis接受准则——判断是否接受新解// 情况1:新解更优(此处假设求最小值,即f1 < f)if(f1 < f) {x = x1; // 更新自变量为新解f = f1; // 更新目标函数值为新值// 若为多变量(如x,y),需同步更新:y = y1;}// 情况2:新解较差,按概率接受else {// 计算接受概率P = exp((f - f1)/T)(求最小值时,f - f1为负数,P∈(0,1))double prob = exp((f - f1) / T);// 生成[0,1)的随机数,若小于P则接受新解if(prob * RAND_MAX > rand()) {x = x1;f = f1;}}// 步骤5:冷却温度——按衰减系数降低温度T = T * dT;}
  • 新解生成逻辑:新解的探索幅度与温度\(T\)正相关,这是模拟退火的关键设计 —— 高温时大步探索,低温时精细调整,既保证全局搜索能力,又兼顾局部收敛效率。
  • 定义域检查:若问题对解有明确范围限制(如资源分配问题中 “人数不能为负”),必须添加此步骤,否则可能生成无效解,导致算法出错。
  • 接受准则细节:需根据 “求最大值” 或 “求最小值” 调整公式:
    • 求最小值:较差解的接受概率为\(P = \exp((f - f1)/T)\)(\(f1 > f\),分子为负,\(P < 1\));
    • 求最大值:较差解的接受概率为\(P = \exp((f1 - f)/T)\)(\(f1 < f\),分子为负,\(P < 1\))。

5. 输出最优解

cout << "最优自变量x:" << x << endl;

cout << "最优目标函数值f(x):" << f << endl;

  • 迭代结束后,输出当前找到的最优解(自变量\(x\))和对应的目标函数值\(f(x)\)。
  • 由于算法存在随机性(初始解、新解生成均为随机),建议多次运行算法,取多次结果中的最优值,提高结果的可靠性。

四、参数调优:让算法更高效

模拟退火算法的性能很大程度上依赖参数设置,以下是常见的调优技巧:

  1. 初始温度\(T\):
    • 若\(T\)过小:初始探索不充分,易陷入局部最优;
    • 若\(T\)过大:迭代次数过多,算法效率低;
    • 调优建议:可先设较大值(如 1000、2000),观察迭代次数,再根据时间限制调整。
  1. 衰减系数\(dT\):
    • 若\(dT\)过小(如 0.8):温度下降快,探索不充分;
    • 若\(dT\)过大(如 0.995):迭代次数多,耗时久;
    • 调优建议:多数问题取 0.98~0.99,平衡探索效率和收敛速度。
  1. 温度下限\(eps\):
  • 一般设为\(1e-10 \sim 1e-15\),无需频繁调整 —— 当温度低于此值时,算法已基本收敛,继续迭代意义不大。
  1. 迭代次数
  • 若问题复杂(如多变量、解空间大),可增加 “固定迭代次数” 作为额外终止条件(如while(T > eps && iter < 1e6)),避免算法超时。

五、应用场景:模拟退火能解决哪些问题?

模拟退火算法的适用范围极广,尤其适合数学建模中 “复杂、多局部最优” 的优化问题,常见场景包括:

  1. 函数极值求解:单变量或多变量函数的全局最大值 / 最小值(如\(f(x,y) = x^2 + y^2 - 2x\)的最小值)。
  2. 组合优化问题
  • 旅行商问题(TSP):寻找访问所有城市且路径最短的路线;
  • 背包问题:在重量限制下,选择物品使总价值最大;
  • 图着色问题:用最少颜色给图的顶点着色,相邻顶点颜色不同。
  1. 工程优化问题:资源分配、生产调度、参数优化(如机器学习模型的超参数调优)。

六、实战案例:用模拟退火求解函数极值

以 “求解\(f(x) = x^2 - 4x + 5\)的最小值” 为例,我们完善代码并运行:

#include <iostream>#include <cmath>#include <cstdlib>#include <ctime>using namespace std;// 目标函数:f(x) = x² -4x +5double func(double x) {return x*x - 4*x + 5;}int main() {srand((unsigned int)time(NULL)); // 初始化随机种子,保证每次运行结果不同// 1. 参数初始化double T = 2000.0; // 初始温度double dT = 0.99; // 衰减系数double eps = 1e-14; // 温度下限double x = rand() % 100; // 初始解x0(随机取0~99的整数)double f = func(x); // 初始函数值// 2. 退火迭代while(T > eps) {// 生成新解x1double dx = (2.0 * rand() - RAND_MAX) / RAND_MAX * T; // 范围[-T, T]double x1 = x + dx;// 计算新解的函数值double f1 = func(x1);// Metropolis准则if(f1 < f) { // 新解更优,接受x = x1;f = f1;} else { // 按概率接受较差解double prob = exp((f - f1)/T);if(prob * RAND_MAX > rand()) {x = x1;f = f1;}}// 冷却温度T *= dT;}// 3. 输出结果cout << "函数f(x) = x² -4x +5的最优解:" << endl;cout << "最优x值:" << x << endl;cout << "最小函数值:" << f << endl;// 理论最优解:x=2,f(x)=1,实际运行结果会接近此值return 0;}
  • 运行结果:由于随机性,每次输出的\(x\)可能略有不同(如 1.999999 或 2.000001),但函数值会接近理论最小值 1,验证了算法的有效性。

七、总结

模拟退火算法是数学建模中 “化繁为简” 的利器 —— 它不依赖问题的具体结构,只需定义目标函数和解的生成规则,就能有效跳出局部最优,寻找全局最优解。掌握它的核心原理(Metropolis 准则)、代码框架和参数调优技巧,能让你在面对复杂优化问题时更有底气。

当然,模拟退火也有局限性(如随机性导致结果不稳定、大规模问题效率低),实际建模中可结合 “遗传算法”“粒子群优化” 等算法,或通过多次运行取最优值来弥补。希望这篇文章能帮你真正学会模拟退火,在建模竞赛中披荆斩棘!

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

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

相关文章

架构很简单:业务架构图

缘起业务架构是一个复杂的体系&#xff0c;如何更简单的表达&#xff0c;并能使用起来呢&#xff1f;所谓&#xff1a;大道至简。基于此&#xff0c;这篇文章就开始了。业务是一切架构的开始&#xff0c;如果没有业务&#xff0c;架构又有什么作用呢&#xff1f;所以做架构首先…

【前端埋点】纯前端实现 A/B Test

“纯前端实现 A/B Test”&#xff0c;意思就是 没有后端分流、也不依赖流量网关&#xff0c;那么只能靠前端逻辑来做“流量切分”。 &#x1f3af; 目标 80% 的用户 → A 页面20% 的用户 → B 页面且要保证 同一个用户每次访问结果一致&#xff08;否则用户刷新页面时 A/B 会跳…

Day22_【机器学习—集成学习(3)—Boosting—Adaboost算法】

Adaptive Boosting(自适应提升)是基于 Boosting思想实现的一种集成学习算法&#xff0c;核心思想是通过逐步提高那些被前一步分类错误的样本的权重来训练一个强分类器。一、Adaboost算法直线相当于一个弱学习器&#xff0c;正确的数据权重减小&#xff0c;错误的数据权重增加二…

C#语言入门详解(18)传值、输出、引用、数组、具名、可选参数、扩展方法

C#语言入门详解&#xff08;18&#xff09;传值、输出、引用、数组、具名、可选参数、扩展方法一、传值参数1. 值类型2. 引用类型&#xff0c;并且创建对象3. 引用类型&#xff0c;不创建对象二、引用参数1. 值类型2. 引用类型&#xff0c;创建新对象3. 引用类型&#xff0c;不…

模型部署:(二)安卓端部署Yolov5-v6.0目标检测项目全流程记录

模型部署&#xff1a;&#xff08;二&#xff09;安卓端部署Yolov5-v6.0目标检测项目全流程记录1、下载NCNN项目2、下载基于安卓的yolov5项目3、修改相应的配置文件4、将项目打包成apk包5、部署自己训练的yolov5模型6、相关资料下载&#xff1a;1、下载NCNN项目 # 链接地址 ht…

图形基础算法:如何将点与带曲线边的多边形位置关系算法做稳定

简介判断点与多边形位置关系算法是几何算法中最基础的算法之一&#xff0c;包括布尔运算在内的非常非常多的算法都会用到它。它的稳定是算法库稳定的关键。下面我们从一个边都是直线的多边形开始了解射线法的原理。然后看看引入曲线后会带来哪些问题&#xff0c;以及在实际应用…

react的filber架构

好问题 &#x1f44d; 你问的是 React Fiber 架构。这是 React 16 引入的核心机制&#xff0c;用来解决 React 在大规模更新时的性能问题。下面我给你从 背景 → Fiber 是什么 → 原理 → 优点 → 流程 来系统讲。一、为什么需要 Fiber&#xff1f;在 React 15 及以前&#xff…

Lucky STUN穿透结合群晖NAS实现docker下transmission监听端口动态更新

参考文章 LCUKY系列教程 一 「LUCKY STUN穿透」使用 cURL 自动修改 Transmission 的监听端口 二 「LUCKY STUN穿透」使用 Webhook 自动修改 qbittorrent 的监听端口 三 LUCKY STUN穿透在Windows上使用UPnP工具为BT客户端自动添加内外端口号不同的映射规则 四「LUCKY STUN穿透」…

如何在Ubuntu畅玩鸣潮等游戏

本教程只包括Steam上的游戏。# 更新软件源 sudo apt update # 安装Steam sudo apt install steam首先&#xff0c;在Ubuntu的snap商店安装Steam&#xff0c;启动&#xff0c;登陆&#xff0c;下载游戏。到这里的操作都比较简单&#xff0c;对于没有反作弊的游戏&#xff0c;往往…

机器学习09——聚类(聚类性能度量、K均值聚类、层次聚类)

上一章&#xff1a;机器学习08——集成学习 下一章&#xff1a;机器学习10——降维与度量学习 机器学习实战项目&#xff1a;【从 0 到 1 落地】机器学习实操项目目录&#xff1a;覆盖入门到进阶&#xff0c;大学生就业 / 竞赛必备 文章目录一、聚类任务&#xff08;无监督学习…

解决 Docker 构建中 Python 依赖冲突的完整指南

问题背景 在基于 registry.cn-shenzhen.aliyuncs.com/all_dev/dev:invoice-base 镜像构建 Docker 容器时,我们遇到了一个常见的 Python 依赖管理问题: ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-…

光子计算芯片实战:Lightmatter Passage互连架构性能评测

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 摘要 随着人工智能计算需求呈指数级增长&#xff0c;传统电子计算…

基于树莓派与Jetson Nano集群的实验边缘设备上视觉语言模型(VLMs)的性能评估与实践探索

概述 2018年&#xff0c;TensorFlow Lite团队的Pete Warden曾提出&#xff1a;“机器学习的未来在于微型化”。如今&#xff0c;随着人工智能向高性能视觉强大的视觉语言模型&#xff08;Vision-language models, VLMs&#xff09;发展&#xff0c;对高性能计算资源的需求急剧…

华为Ai岗机考20250903完整真题

华为Ai岗机考20250903 华为自26届秋招&#xff08;2025年起&#xff09;对AI岗位机考进行了改革&#xff0c;考试题型调整为20道选择题&#xff08;15道单选(6分)5道不定项选择(12分)&#xff09;2道编程题(150300)。 题目核心围绕人工智能技术&#xff08;如Transformer架构…

k8s+jenkins+harbor构建Devops平台

一、环境准备1、准备一主一从k8s机器&#xff0c;&#xff08;设备好可以一主多从也行&#xff09;2、一台harbor仓库机器&#xff08;dockerhub访问不了&#xff09;二、安装nfs服务1、在k8s机器上yum install nfs-utils -y systemctl start nfs systemctl enable nfs2、创建共…

为什么 socket.io 客户端在浏览器能连上,但在 Node.js 中报错 transport close?

网罗开发&#xff08;小红书、快手、视频号同名&#xff09;大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等方…

人才教育导向下:老年生活照护实训室助力提升学生老年照护服务能力

一、老年生活照护实训室建设背景与意义 &#xff08;一&#xff09;适应老龄化社会需求 我国老龄化程度持续加深&#xff0c;老年照护服务人才缺口不断扩大。培养专业照护人才成为当务之急&#xff0c;职业教育需承担重要责任。点击获取实训室建设方案 &#xff08;二&…

我在嘉顺达蓝海的安全坚守

作为嘉顺达蓝海的资深安全员&#xff0c;每天清晨 6 点&#xff0c;我都会站在物流基地的入口处&#xff0c;看着一队队橙色的嘉顺达蓝海危险品运输车整齐列队。那抹醒目的橙色&#xff0c;不仅是嘉顺达蓝海的标志&#xff0c;更是我和 200 多名同事坚守 12 年的安全承诺。今天…

云原生监控系统 Prometheus大总结 20250909

本章内容如下&#xff1a; Prometheus 介绍 Prometheus 部署和配置 Node Exporter 采集数据 Pushgateway 采集数据 PromQL 查询语言 Grafana 图形化展示 Prometheus 标签管理 Prometheus 告警机制 Prometheus 服务发现 各种Exporter 高级功能 Prometheus 实现容器监控 Promethe…

EPNN:基于嵌入式偏振神经网络的水下成像增强方法(未做完)

Enhancing Underwater Imaging for Robot through Embedded Polarization Neural Network EPNN:基于嵌入式偏振神经网络的水下成像增强方法 1 论文核心概念 本文提出了一种名为嵌入式偏振神经网络(Embedded Polarization Neural Network, EPNN) 的方法,用于显著提升水下…