模拟退火算法(附简单案例及详细matlab源码)

news2024/7/4 4:57:15

在这里插入图片描述

作者:非妃是公主
专栏:《智能优化算法》
博客地址:https://blog.csdn.net/myf_666
个性签:顺境不惰,逆境不馁,以心制境,万事可成。——曾国藩
在这里插入图片描述

文章目录

  • 专栏推荐
  • 一、概论
  • 二、物理退火
    • 1. 加温过程
    • 2. 等温过程
    • 3. 降温过程
  • 三、模拟退火原理
  • 四、模拟退火的优点
  • 五、算法具体流程
    • 1. 整体流程
    • 2. 细节处理
      • Ⅰ. 状态产生函数
      • Ⅱ. 初始温度
      • Ⅲ. 退温函数
      • Ⅳ. Markov 链长度
      • Ⅴ. 算法终止准则
  • 六、仿真实例:模拟退火求解函数最小值
    • 1. 题目
    • 2. 分析
    • 3. matlab求解
    • 4. 求解结果及分析
  • 七、模拟退火的一些改进方向
  • the end……

专栏推荐

专栏名称专栏地址
软件工程专栏——软件工程
计算机图形学 专栏——计算机图形学
操作系统专栏——操作系统
软件测试专栏——软件测试
机器学习专栏——机器学习
数据库专栏——数据库
算法专栏——算法

对于一个问题,解决他的第一步是建立模型,利用数学的方法,将问题抽象成一个数学模型(可能是一个函数,一个算法,一个方程……)。第二步,就是对这个问题进行求解,也叫做模型求解。

但对于模型求解来讲,不同的模型有着不同大小的难度。传统的算法,比如梯度下降,很可能会陷入局部最优解等问题,对于更加全局性的最优解搜索,智能优化算法有着很好的效果。而模拟退火算法,就是智能优化算法中的一种,有着很好的效果。

模拟退火算法(Simulated Annealing,SA)最早由Metropolis等人于 1953 年提出。1983 年Kirkpatrick等人第一次使用模拟退火算法求解组合优化问题后,它就发表在了 Science 上。1直到今天,它依然被广泛使用,这篇文章将详细介绍模拟退火算法的基本原理,以及matlab的代码实现。


一、概论

模拟退火算法其实就是一个类似于仿生学的算法,模仿的就是物理退火的过程。我们炼钢的时候,如果我们急速冷凝,这时候的状态是不稳定的,原子间杂乱无章的排序,能量很高。而如果我们让钢水慢慢冷凝,很缓慢的降温,那么这个时候的状态就是很稳定的,各个分子都趋向于自己能量最低的位置。

而模拟退火算法,恰恰就是利用了物理退火这一过程的原理,求解一个优化目标(目标函数)的最小值。


二、物理退火

如果想说清楚模拟退火,必然绕不过物理退火!

1. 加温过程

增强粒子热运动,使其偏离平衡位置。当温度足够高时,固体将溶解为液体,从而消除系统原先可能存在的非均匀态,使随后进行的冷却过程以某一平衡态为起点。溶解过程于系统的能量增大过程相联系,系统能量也随温度的升高而增大。


2. 等温过程

通过物理学知识得知,对于与周围环境交换热量而温度不变的封闭系统,系统状态的自发变化总是朝着自由能降低的方向进行;当自由能达到最低时,系统达到平衡态。


3. 降温过程

随着温度降低,分子热运动减弱,趋向有序,系统能量逐渐降低,从而得到了低能量的晶体结构。


三、模拟退火原理

而模拟退火算法,就是要通过如上3个部分的操作,获得低能量的晶体结构(最优解)。

物理退火与模拟退火中的各个状态对应如下:

物理退火模拟退火
粒子状态每个状态对应一个(可行)解
能量最低态最优解
溶解过程设定初温(设定参数T的值)
等温过程一个温度下,多次采样(Metropolis采样过程)
冷却控制参数下降
能量目标函数

主要思想,在搜索区间进行随机游走(通过生成随机数实现),再利用Metropolis抽样准则,使随机游走逐渐收敛于局部最优解。在这里,温度是一个重要的控制参数,这个参数的大小控制了随机过程向局部或全局最优解移动的快慢。具体的过程如下。

首先,定义一个 p p p
p = e − E 2 − E 1 T p=e^{-\frac{E_2-E_1}{T}} p=eTE2E1

这个公式表示,系统从 E 1 E_1 E1变化到 E 2 E_2 E2,其概率为 p p p,就是上述公式左边的部分。

如果 E 2 < E 1 E_2<E_1 E2<E1,那么证明系统向更低的方向转移了,我们无条件接受此状态。

否则,以上述的概率,接受这个较坏的结果 E 2 E_2 E2。注意,这里的原则,不同于贪心,每次选择最好的,而是有一定的概率接受坏一些的。(这个概率受到能量差和温度两个因素的影响)

p ( 1 → 2 ) = { 1 E 2 < E 1 e − E 2 − E 1 T E 2 > E 1 p(1\rightarrow2)= \begin{cases} 1& E_2<E_1\\ e^{-\frac{E_2-E_1}{T}}& E_2>E_1 \end{cases} p(12)={1eTE2E1E2<E1E2>E1

这样通过一定的迭代次数,我们就会找到一个比较好的解了。


四、模拟退火的优点

总结一下模拟退火的优点如下:

  • 以一定的概率接受恶化解。看似在接受恶化解,其实是寻找了全局最优解。
  • 引进算法控制参数——温度。温度的引进,使得算法更加智能、灵活。在前期,进行跳跃搜索,更容易跳出局部最优解,提高搜索的全局性。在后期,进行幅度较小的搜索,更容易收敛。
  • 对目标函数要求少。模拟退火算法其实是一种搜索或者说枚举的方法,我们经过大量的实验,最终得到最优解(或者一定程度上的较优解)。由于这种做法,因此对目标函数的要求很低。不需要依赖什么,直接猜就好。

五、算法具体流程

学习的过程是广度优先,层层深入的,前面大致了解了模拟退火算法的原理及思想,下面我们看一看模拟退火算法的具体算法流程。


1. 整体流程

  1. 初始化温度 T 0 T_0 T0,初始解状态 X 0 X_0 X0(算法迭代起点)、每个 T T T值的迭代次数 L L L(也叫做Markov 链长度,就是在同一个温度下,我们猜测的次数)。
  2. k = 1 , … , L k=1, …, L k=1,,L做第(3)至第(6)步;
  3. 产生新解 X ′ X' X
  4. 计算增量 Δ E = E ( X ′ ) − E ( X ) ΔE=E(X')-E(X) ΔE=E(X)E(X),其中 E ( X ) E(X) E(X)为评价函数(越低越好);
  5. Δ E < 0 ΔE<0 ΔE0,则接受 X ′ X' X作为新的当前解,否则以概率 e − Δ E T e^{\frac{-ΔE}{T}} eTΔE接受 X ′ X' X作为新的当前解;
  6. 如果满足终止条件,则输出当前解为最优解,结束程序;
  7. T T T逐渐减小,且 T → 0 T\rightarrow 0 T0,然后转第 2 步。

流程图如下:

在这里插入图片描述


2. 细节处理

Ⅰ. 状态产生函数

主要就是通过在邻域内随机进行选择产生的。


Ⅱ. 初始温度

初始温度对于算法的影响较大,而且效果的好坏与求解问题的求解空间有关。初温越大,获得高质量解的可能性越高,但是相应的时间也就越长,具体可以在此处进行取舍。

一种很好的做法是,可以均匀抽样一组状态,以各状态目标值的方差作为初温。

  • 这样,如果方差越大,证明该问题越有可能陷入到局部最优解(多峰型优化),因此初温较高,防止陷入。

  • 如果方差很小,说明该问题不容易陷入局部最优(单峰型优化),因此,初温较低,可以快速收敛。


Ⅲ. 退温函数

退温函数即温度更新函数,用于在外循环中修改温度值。目前,最常用的温度更新函数为指数退温函数,即 T ( n + 1 ) = K × T ( n ) T(n+1)=K×T(n) T(n+1)=K×T(n),其中 0 < K < 1 0<K<1 0K1 K K K为一个非常接近于1的常数。


Ⅳ. Markov 链长度

Markov 链长度是在等温条件下进行迭代优化的次数,其选取原则是在衰减参数 T T T 的衰减函数已选定的前提下,还要产生随机数的次数,一般 L 取100~1000。


Ⅴ. 算法终止准则

算法停止的条件。常用的有,温度降低到一定的阈值结束,迭代一定的次数后结束,最优值连续保持不变(或者变化值 < δ <\delta <δ)时停止搜索。


六、仿真实例:模拟退火求解函数最小值

1. 题目

计算函数 f ( x ) = ∑ i = 1 n x i 2 ( − 20 < = x i < = 20 ) f(x)=\sum_{i=1}^n x_i^2 (-20<=x_i<=20) f(x)=i=1nxi2(20<=xi<=20)的最小值,其中个体 x x x的维数为 n = 10 n=10 n=10


2. 分析

这时一个平方和函数,只有一个极小值 x = ( 0 , 0 , . . . , 0 ) x=(0,0,...,0) x=(0,0,...,0),理论最小值 f ( 0 , 0 , . . . , 0 ) = 0 f(0,0,...,0)=0 f(0,0,...,0)=0

Markov链长度初始化为 L = 200 L=200 L=200,衰减参数设置为0.998,补偿因子为 S = 0.01 S=0.01 S=0.01,初始温度 T = 100 T=100 T=100,容差为 Y Z = 1 × 1 0 − 8 YZ=1\times 10^{-8} YZ=1×108(用于判断结束条件,如果最优值连续变化小于 Y Z YZ YZ,那么就终止搜索,输出这个较优解,其它参数上边都已经提到过了);随机产生初始解,并计算目标函数值。


3. matlab求解

%%%%%%%%%%%%%%%%%%%%%%模拟退火算法解决函数极值%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all;                      %清除所有变量
close all;                      %清图
clc;                            %清屏
D=10;                           %变量维数 
Xs=20;                          %上限                                
Xx=-20;                         %下限
%%%%%%%%%%%%%%%%%%%%%%%%%%%冷却表参数%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
L = 200;                        %马可夫链长度
K = 0.998;                      %衰减参数
S = 0.01;                       %步长因子
T=100;                          %初始温度
YZ = 1e-8;                      %容差
P = 0;                          %Metropolis过程中总接受点
%%%%%%%%%%%%%%%%%%%%%%%%%%随机选点 初值设定%%%%%%%%%%%%%%%%%%%%%%%%%
PreX = rand(D,1)*(Xs-Xx)+Xx;
PreBestX = PreX;
PreX = rand(D,1)*(Xs-Xx)+Xx;
BestX = PreX;
%%%%%%%%%%%每迭代一次退火一次(降温), 直到满足迭代条件为止%%%%%%%%%%%%
deta=abs(func1(BestX)-func1(PreBestX));
while (deta > YZ) && (T>0.001)
    T=K*T; 
    %%%%%%%%%%%%%%%%%%%%%在当前温度T下迭代次数%%%%%%%%%%%%%%%%%%%%%%
    for i=1:L  
        %%%%%%%%%%%%%%%%%在此点附近随机选下一点%%%%%%%%%%%%%%%%%%%%%
        NextX = PreX + S* (rand(D,1) *(Xs-Xx)+Xx);
        %%%%%%%%%%%%%%%%%边界条件处理%%%%%%%%%%%%%%%%%%%%%%%%%%
        for ii=1:D
            if NextX(ii)>Xs | NextX(ii)<Xx
                NextX(ii)=PreX(ii) + S* (rand *(Xs-Xx)+Xx);
            end
        end            
        %%%%%%%%%%%%%%%%%%%%%%%是否全局最优解%%%%%%%%%%%%%%%%%%%%%%
        if (func1(BestX) > func1(NextX))
            %%%%%%%%%%%%%%%%%%保留上一个最优解%%%%%%%%%%%%%%%%%%%%%
            PreBestX = BestX;
            %%%%%%%%%%%%%%%%%%%此为新的最优解%%%%%%%%%%%%%%%%%%%%%%
            BestX=NextX;
        end
        %%%%%%%%%%%%%%%%%%%%%%%% Metropolis过程%%%%%%%%%%%%%%%%%%%
        if( func1(PreX) - func1(NextX) > 0 )
            %%%%%%%%%%%%%%%%%%%%%%%接受新解%%%%%%%%%%%%%%%%%%%%%%%%
            PreX=NextX;
            P=P+1;
        else
            changer = -1*(func1(NextX)-func1(PreX))/ T ;
            p1=exp(changer);
            %%%%%%%%%%%%%%%%%%%%%%%%接受较差的解%%%%%%%%%%%%%%%%%%%%
            if p1 > rand        
                PreX=NextX;
                P=P+1;         
            end
        end
        trace(P+1) = func1(BestX);
    end
    deta = abs(func1(BestX) - func1(PreBestX)); 
end
disp('最小值在点:');
BestX
disp( '最小值为:');
func1(BestX)
figure
plot(trace(2:end))
xlabel('迭代次数')
ylabel('目标函数值')
title('最优解变化曲线')

其中,目标函数(适应度函数)fun1的定义如下:

%%%%%%%%%%%%%%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%%%%%%%%%%%
function result=func1(x)
summ=sum(x.^2);
result=summ;

4. 求解结果及分析

求解的适应度变化曲线如下:

在这里插入图片描述

可以看到,随着迭代次数的增加,目标函数值下降速度还是很快的,说明算法收敛速度较好。

最终搜索结果如下:

在这里插入图片描述

可以看到,我们在理论最优解 0 附近找到了近似最优解 0.0103,求解效果还是不错的。

继续运行代码,求解结果如下:

在这里插入图片描述

可以看到求解过程以及最终的结果都不太相同,因此,对于模拟退火这种启发式智能优化算法,求解结果是有一定随机性的。但是,会随着迭代次数的增加,越发趋于稳定。


七、模拟退火的一些改进方向

  • 增加记忆功能
  • 增加升温或重升温过程。
  • 对每一当前状态,采用多次搜索策略,以概率接受区域内的最优状态,而不是标准模拟退火算法的单次比较方式。
  • 与其他搜索机制的算法(如遗传算法、免疫算法等)相结合。可以综合其他方法的优点,提高运行效率和求解质量。2

the end……

模拟退火算法到这里就要结束啦~~到此既是缘分,欢迎您的点赞评论收藏关注我,不迷路,我们下期再见!!

😘😘😘 我是Cherries,一位计算机科班在校大学生,写博客用来记录自己平时的所思所想!
💞💞💞 内容繁杂,又才疏学浅,难免存在错误,欢迎各位大佬的批评指正!
👋👋👋 我们相互交流,共同进步!

:本文由非妃是公主发布于https://blog.csdn.net/myf_666,转载请务必标明原文链接:https://blog.csdn.net/myf_666/article/details/129061318


  1. Kirkpatrick S,Gelatt C,Vecchi M.Optimization by simulated Anealing.Science,1983(220):671-680. ↩︎

  2. 包子阳,智能优化算法及其matlab实例.电子工业出版社. ↩︎

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

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

相关文章

MyBatis - CRUD 操作

文章目录 1.环境配置1.1 导入相关依赖1.2 基本配置1.3 数据模型 2.基于 XML 开发2.1 创建 Mapper 接口2.2 创建 XML 映射文件2.3 insert2.4 select2.5 delete2.6 update2.7 编写单元测试 3.基于注解开发3.1 常用注解3.2 创建 Mapper 接口 MyBatis 支持通过 XML 和注解两种方式来…

chatgpt赋能python:Python运行程序没反应怎么办?

Python运行程序没反应怎么办&#xff1f; Python作为一种高级编程语言&#xff0c;已经成为了很多开发者的首选语言。然而&#xff0c;在使用Python编写程序时&#xff0c;有时候会出现运行程序却没有任何反应的情况。这是什么原因导致的呢&#xff1f;本文将为大家介绍Python…

单例模式的饿/懒汉模式

目录 1. 什么是单例模式2. 饿汉模式2.1 饿汉模式概念2.2 饿汉模式代码 3. 懒汉模式3.1 懒汉模式概念3.2 单线程情况下的懒汉模式3.3 单例模式的写法(保证线程安全) 4. wait 和 sleep 的区别 1. 什么是单例模式 保证某个类在程序中只存在一份实例&#xff0c;而不会创建多个实例…

Apache Kafka - 跨集群数据镜像 MirrorMaker

文章目录 概述跨集群数据镜像的原理MirrorMaker配置小结 概述 在分布式系统中&#xff0c;数据镜像是一项重要的功能&#xff0c;它可以将数据从一个集群复制到另一个集群&#xff0c;以保证数据的高可用性和容错性。Apache Kafka是一个流处理平台&#xff0c;它提供了一种跨集…

程序设计综合实习(C语言):学生成绩单制作

一、目的 1&#xff0e;掌握结构体变量及数组的定义、赋值、初始化、输入、输出 2&#xff0e;结构体数组的操作。 二、实习环境 Visual Stdio 2022 三、实习内容、步骤与要求 1&#xff0e;定义一个结构体数组&#xff0c;存放10个学生的学号&#xff0c;姓名&#xff0c;三…

Linux 设备树文件手动编译的 shell 脚本

前言 前面通过 Makefile 实现手动编译 Linux 设备树 dts 源文件及其 设备树依赖 dtsi、.h 头文件&#xff0c;如何写成一个 shell 脚本&#xff0c;直接编译呢&#xff1f; 其实就是 把 Makefile 重新编写为 shell 脚本即可 编译设备树 shell 脚本 脚本内容如下&#xff1a…

【六一 iKun】Happy LiuYi, iKuns

六一了&#xff0c;放松下。 Python iKun from turtle import * screensize(1000,1000) speed(6)#把衣服画出来&#xff0c;从右肩膀开始#领子 penup() goto(-141,-179) pensize(3) fillcolor("black") pencolor("black") begin_fill() pendown() left(1)…

【Python实战】Python采集高校信息

前言 大家好,我们今天来爬取某站的高校名单,把其高校名单,成员和内容数获取下来,不过,我们发现这个网站比我们平时多了一个验证,下面看看我是怎么解决的。 环境使用 python 3.9pycharm模块使用 requests模块介绍 requests requests是一个很实用的Python HTTP客户端…

【线性dp必学四道题】线性dp四道经典例题【最长上升子序列】、【最长公共子序列】、【最长公共上升子序列(maxv的由来)】【最长公共子串】

【最长上升子序列】、【最长公共子序列】、【最长公共上升子序列】 最长上升子序列f[i] 表示以i结尾的最长子序列 最长公共子序列f[i][j] 表示 a前i 和 b前j个 最长公共长度 最长公共上升子序列f[i][j]代表所有a[1 ~ i]和b[1 ~ j]中以b[j]结尾的公共上升子序列的集合 最长公共子…

Spring Boot如何实现分布式追踪和监控

Spring Boot如何实现分布式追踪和监控 在分布式系统中&#xff0c;由于服务数量的增加和服务之间的相互调用&#xff0c;会出现跨服务的请求链路较长&#xff0c;难以追踪问题和定位性能瓶颈等问题。因此&#xff0c;分布式追踪和监控变得越来越重要。本文将介绍如何使用 Spri…

怎样一元钱部署自己的AI网站

前段时间我开发了一个简洁的AI问答网站&#xff0c;好多朋友感兴趣&#xff0c;因此我将网站代码在github上开源&#xff0c;并编写此教程&#xff0c;帮助大家快速部署自己的AI网站&#xff0c;会编程的朋友们也可在此基础上定制开发。 前提条件&#xff1a;有自己的ChatGPT账…

AI实战营:开源计算机视觉神器OpenMMLab

目录 OpenMMLab概述 OpenMMLab各开源算法库详细介绍 OpenMMLab开源生态 OpenMMLab概述 部署框架&#xff1a;MMdeploy 算法框架&#xff1a;MMPretrain预训练多模态、MMDetection目标检测、MMDetection3D目标检测、MMRotate旋转目标检测、MMSegmentation语义分割、MMPose姿…

操作系统_进程

操作系统_进程 1 冯•诺依曼体系结构2 操作系统&#xff08;Operator System&#xff09;2.1 设计OS的目的2.2 OS的定位 3 进程3.1 什么是进程&#xff1f;3.2 查看进程3.3 通过fork创建进程使用 if 进行分流如何杀死一个进程 3.4 进程状态R - 运行状态S - 浅睡眠状态D - 磁盘休…

Java中关于ConditionObject的signal()方法的分析

代码块的展示 isHeldExclusively()这个仅持有锁资源的方法&#xff0c;在ReentrantLock中重写进行判断&#xff0c;要是没有持有锁资源那么会返回false&#xff0c;就会出现直接抛异常IllegalMonitorStateException&#xff08;非法监视器状态异常&#xff09;获取排在Conditi…

zookeeper相关,安装,认识......

目录 Zookeeper 1 第一章 Zookeeper简介... 1 1.1 Zookeeper概述和功能... 1 1.2 Zookeper安装... 1 1.3 Zookeper数据模型... 3 第二章 Zookeeper命令操作... 4 1.1 Zookeeper Client 4 1.2 Zookeeper JavaClient 6 第三章 集群角色... 28 Zookeeper 第一章 Zookeepe…

详解Servlet API

目录 前言 HttpServlet HttpServletRequest 代码实例 打印请求信息 通过URL中的queryString进行传递。 通过post请求的body&#xff0c;使用form表单传递 通过POST 请求中的 body 按照 JSON 的格式进行传递 HttpServletResponse 核心方法代码实例 设置状态码 自动刷…

【C++初阶】string 类的认识与学习

在学习string类之前&#xff0c;先在这里推荐2个好用的网站&#xff0c;可以用来查阅C的相关知识 https://cplusplus.com https://en.cppreference.com/w/ 上面的是非官方的&#xff0c;下面的官方的&#xff0c;但是个人感觉还是上面的好用。 一.string 类是什么 简单来说&…

State of GPT (ChatGPT 原理及现状介绍)

State of GPT 演讲信息&#xff1a; 演讲人&#xff1a;Andrej Karpathy (现在OpenAI任职)&#xff0c;之前是特斯拉视觉研发负责人&#xff0c;斯坦福深度学习入门课程 CS231N 讲师演讲主题&#xff1a;受到微软 BUILD2023 邀请&#xff0c;介绍 GPT 的原理及研发现状&#x…

VMware虚拟机安装Ubuntu 22.04详细教程(2023年新版教程)

VMware虚拟机安装Ubuntu 22.04详细教程&#xff08;保姆级教程&#xff09; 大家好&#xff0c;我是洲洲&#xff0c;欢迎关注&#xff0c;一个爱听周杰伦的程序员。关注公众号【程序员洲洲】即可获得10G学习资料、面试笔记、大厂独家学习体系路线等…还可以加入技术交流群欢…

代码创作世界——pytorch深度学习框架数据类型

代码创作世界——pytorch深度学习框架数据类型 torch中的数据类型张量&#xff08;tensor&#xff09; pytorch中的 在数学中&#xff0c;一个单独的数可以成为标量&#xff0c;一行或者一列数组可以称为向量&#xff0c;一个二维数组称为一个矩阵&#xff0c;矩阵中的每一个元…