模拟退火算法的改进

article/2025/9/20 23:21:14
  1. 模拟退火算法的物理模型
    在物理退火过程中,当固体的温度很高时,内能较大,固体内部的粒子处于无序运动状态,当温度慢慢降低时,固体的内能减小,粒子的运动趋于有序,如果温度降低得足够慢,在每个温度下粒子都会保持一个平衡状态,最终,当固体处于常温时,内能达到最小,此时粒子最为稳定。
    模拟退火算法从初始温度出发(初始温度为较高温度),伴随着温度下降,目标函数的解趋于稳定(能量最低点),但是,这个稳定的解可能是局部最优解,因此,当到达一个较差的解时,算法会以一定的概率接受差解,从而跳出局部最优解,以寻找目标函数的全局最优解。
    为了找到全局最优解,即能量最低点,设在温度下降的过程中,粒子的前一状态为x(n),通过邻域函数(也称状态产生函数,在某状态空间以某一概率密度函数随机采样跳转到下一状态)改变粒子的状态,变为x(n+1)。相应的,系统能量也由E(n)变为E(n+1)。当E(n+1)<E(n)时,系统能量减小了,我们以概率为1接受转换的状态(较优解);当E(n+1)>E(n)时,系统能量增大了,认为该状态偏离了全局最优位置(能量最低点),为差解,但是为了跳出局部最优解,算法不会立刻抛弃差解,而会以一定的概率 接受差解,当在区间[0,1]内产生的一个均匀分布的随机数小于p时,接受差解,即接受转换后的状态,否则拒绝接受。继续降温(降温可以降低接受差解的概率p),通过邻域函数改变粒子状态,判断是否接受下一状态,直到到达终止条件(终止条件可设最低温,也可设迭代的轮次)。

  2. 算法流程图
    在这里插入图片描述

  3. 针对函数优化问题对模拟退火算法进行性能改进的方法和思路以及代码实现
    以求解测试函数
    在这里插入图片描述
    的最小值为例,(资料显示两个函数的最小值都为f(0,0)=0),函数f1的图像如图3-1-1所示,函数f2的图像如图3-1-2所示。
    在这里插入图片描述
    在这里插入图片描述
    根据图2-1模拟退火算法的算法流程图编写如附录中表1所示的求解函数f1(x,y)最小值的程序清单,改进之处已在该程序清单中修改(求解函数f2的程序清单相似)。
    在运行该程序时,为了获得更优解,我尝试了以下几种方法:
    (1) 选择合适的初始值。
    初始值包括初始温度,最低温度和初始状态。
    在这个例子中,对于初始状态有两种方法,方法一是在定义域内随机生成初始状态;方法二是先随机生成一组状态,取求得的目标函数值最小的状态,两种方法的对比如表3-1-1所示。方法二虽然能获得较优的解,但在初始化的选择目标函数值最小时的状态时,容易后续操作导致陷入局部最优。
    对于初始温度来说,当然是和最低温相差越大越好,但是在多次运行的情况下,不论温差有多大,仍有些解无法达到全局最优。
    (2) 选择合适的邻域函数。
    在本例中,我分别选取了正态分布和随机分布作为领域函数,在多次运行后,随机分布算出来的最小值整体上偏大于正态分布的算出来的最小值。
    而选择正态分布作为邻域函数时还要注意调整方差,方差设置得较大,容易跳出最优解,方差设置得较小,又容易陷入全局最优。在多次尝试不同函数后,可以看出方差的选取和函数的定义域有关,定义域较大时,方差也应较大。在本例中,由于定义域较小,选取的方差为2。
    (3) 选择合适的降温方式。
    降温的作用是降低接受差解的概率,温度下降太快会导致难以跳出局部最优,在本例中,采用书本中经典模拟退火算法的降温方式。
    按照以上三个方法调整后,f2多次运行,大概率能获得较好的最低值,而由于f1有较多局部最优解,多次运行的结果大多仍然很难跳出局部最优或跳出了局部最优,又陷入了另一个局部最优。f1和f2在迭代过程中对解的记录曲线如下图3-3、图3-4所示。由两个图看出,算法还需要改进,因此,我又做了如(4)所示的调整。
    在这里插入图片描述
    在这里插入图片描述
    (4) 记录最优解。
    从图3-3、图3-4中不难看出,在迭代过程中,算法跳出了在该迭代中目标函数的最优解,为了不错过全局最优解,可以在迭代的过程中把较优解记录下来,迭代完成后和最后一个解进行比较,解的值低的作为最优解输出。
    改进后运行分别一次求解f1和f2最小值的程序,控制台的输出结果如图3-5、图3-6所示。
    在这里插入图片描述

  4. 测试代码

import numpy as np
import matplotlib.pyplot as plt
import math
import random
from scipy.stats import norm
from mpl_toolkits.mplot3d import Axes3D# 目标函数
def Function(x, y):return -20 * np.exp(-0.2*np.sqrt(0.5*(x*x+y*y)))\-np.exp(0.5*(np.cos(2*np.pi*x)+np.cos(2*np.pi*y)))+20+np.e# 初始化状态
def initN(low, high):'''随机生成一组状态取能量最低的状态:param low::param high::return:'''x = random.uniform(low, high)y = random.uniform(low, high)z = Function(x, y)for i in range(20):x1 = random.uniform(low, high)y1 = random.uniform(low, high)z1 = Function(x1, y1)if z1 < z:x = x1y = y1z = z1return x, y# 绘制目标函数
def figureFuc(low, high):X = np.linspace(low, high, 500)Y = np.linspace(low, high, 500)XX, YY = np.meshgrid(X, Y)Z = -20 * np.exp(-0.2*np.sqrt(0.5*(XX*XX+YY*YY)))\-np.exp(0.5*(np.cos(2*np.pi*XX)+np.cos(2*np.pi*YY)))+20+np.efig = plt.figure()ax = Axes3D(fig)ax.plot_surface(XX, YY, Z, cmap=plt.get_cmap('rainbow'))plt.show()# Metropolis准则接受新解
def Metropolis(detaF, T):  # detaF为f(n+1) - f(x)if detaF < 0:return 1else:pTk = math.exp(-detaF/T)if pTk > random.random():return 1else:return 0# 利用正态分布产生新解
def get_normal_random_number(x,y,scale):  # 正态分布''':param x: 均值:param y: 均值:param scale: 方差:return:'''fx = np.random.normal(x, scale)x = norm.ppf(fx)fy = np.random.normal(y, scale)y = norm.ppf(fy)return x, y# 利用均匀分布产生新解
def get_uniform_random_number(low, high):''':param low::param high::return:'''x = np.random.uniform(low, high)y = np.random.uniform(low, high)return x, y# 冷却函数
def descT(T, k):# return T/np.log(1 + k)return 0.9*T# 主函数
def startMain():# 初始化low = -5high = 5T = 10000Tmin = 10k = 1# figureFuc(low, high)  # 画图#x = random.uniform(low, high)#y = random.uniform(low, high)x, y = initN(low, high)z = Function(x, y)min_value = zrecord_value = []  # 用数组记录被接受的新解并绘图,方便分析while(T > Tmin and k <= 1000):x1, y1 = get_normal_random_number(x, y, 2)  # 利用正态分布产生新解# x1, y1 = get_uniform_random_number(low, high)  # 利用随机分布产生新解if x1 < low or x1 > high or y1 < low or y1 > high:   # 新解不在定义域内时跳出本次循环breakz1 = Function(x1, y1)  # 计算新解的目标函数值deltaE = z1 - zmin_value = min(min_value, z1)if Metropolis(deltaE, T) == 1:  # 接受按照Metropolis准则接受新解x = x1y = y1z = z1record_value.append(z)if deltaE > 0:T = descT(T, k)else:k += 1print('迭代到组后的解:', z)print('记录下的最优解:', min_value)#  打印解的变化曲线x=[i+1 for i in range(len(record_value))]plt.plot(x, record_value)plt.show()if __name__ == "__main__":startMain()

http://chatgpt.dhexx.cn/article/RgMsd9sI.shtml

相关文章

模拟退火算法简单理解

模拟退火算法 算法流程图 1. 引言 模拟退火算法&#xff08;Simulate Anneal&#xff0c;SA&#xff09;是一种通用概率演算法&#xff0c;用来 在一个大的搜寻空间内找寻命题的最优解 。模拟退火是由S.Kirkpatrick, C.D.Gelatt和M.P.Vecchi在1983年所发明的。V.Čern在198…

理解模拟退火算法

目录 文章目录 目录退火原理爬山算法模拟退火模拟退火伪代码算法评价参考文献 退火原理 模拟退火算法来源于固体退火原理&#xff0c;将固体加温至充分高&#xff0c;再让其徐徐冷却。加温时&#xff0c;固体内部粒子随温升变为无序状&#xff0c;内能增大&#xff0c;而徐徐冷…

量子退火算法入门(6):初识量子退火算法的发明过程

文章目录 一、量子计算机二、模拟退火算法三、量子退火算法的物理基础1. 量子涨落替换热涨落&#xff0c;提出量子退火算法2. 绝热量子演化解决横向磁场强度缓慢变化3. D-Wave Systems公司实现物理量子退火机 总结 一、量子计算机 提示&#xff1a;量子退火机的发展简史&#…

模拟退火算法(SA)详解

一.算法来源&#xff1a;模拟退火算法(SA)源于固体退火原理&#xff0c;是一种基于概率的算法。将固体加温至充分高的温度&#xff0c;再让其徐徐冷却&#xff0c;加温时&#xff0c;固体内部粒子随温升变为无序状&#xff0c;内能增大&#xff0c;分子和原子越不稳定。而徐徐冷…

模拟退火算法介绍和实例实现

一、模拟退火算法简介 模拟退火算法(SA)来源于固体退火原理&#xff0c;是一种基于概率的算法。将固体加温至充分高的温度&#xff0c;再让其徐徐冷却&#xff0c;加温时&#xff0c;固体内部粒子随温升变为无序状&#xff0c;内能增大&#xff0c;分子和原子越不稳定。而徐徐冷…

模拟退火算法(Python)

一、模拟退火算法 1、模拟退火算法的定义 模拟退火算法是一种现代优化算法。基于蒙特卡洛迭代求解方法的随机寻优算法&#xff0c;模拟退火算法于1983 年成功地应用到组合优化领域。因固体物理退火过程与组合优化问题存在着相似性&#xff0c;模拟退火算法对固体物质的退火过…

模拟退火算法详细说明

来源&#xff1a;固体退火。一种处理工艺&#xff1a;将金属缓慢加热到一定程度&#xff0c;保持足够的时间&#xff0c;然后以适宜的速度冷却。退火后的金属具有了新的属性降低硬度等。 一、爬山算法 1.爬山算法是一种局部择优的方法&#xff0c;是一种局部贪心的最优算法。…

【算法】模拟退火

文章目录 1.模拟退火介绍1.1模拟退火的可行性1.2退火模型 2.详解退火2.1退火过程2.2各变量说明2.2.1关于接收概率 3.退火模拟求根号n的值4.洛谷POJ-2420 1.模拟退火介绍 ​ 模拟退火是模拟物理上退火方法&#xff0c;通过N次迭代&#xff08;退火&#xff09;&#xff0c;逼近…

模拟退火算法的原理+应用

本文转自https://www.cnblogs.com/ranjiewen/p/6084052.html 模拟退火算法 著名的模拟退火算法&#xff0c;它是一种基于蒙特卡洛思想设计的近似求解最优化问题的方法。 一点历史——如果你不感兴趣&#xff0c;可以跳过 美国物理学家 N.Metropolis 和同仁在1953年发表研究复杂…

优化算法——模拟退火算法

模拟退火算法原理 爬山法是一种贪婪的方法&#xff0c;对于一个优化问题&#xff0c;其大致图像(图像地址)如下图所示&#xff1a; 其目标是要找到函数的最大值&#xff0c;若初始化时&#xff0c;初始点的位置在 C C C处&#xff0c;则会寻找到附近的局部最大值 A A A点处&a…

模拟退火算法详细讲解(含实例python代码)

模拟退火算法详细讲解&#xff08;含实例python代码&#xff09; &#xff08;一&#xff09;模拟退火算法简介&#xff08;二&#xff09;模拟退火算法原理&#xff08;三&#xff09;退火过程中参数控制&#xff08;四&#xff09;算法步骤&#xff08;五&#xff09;实例分析…

模拟退火算法(SA)

一、算法简介 模拟退火算法(SA) 一种模拟物理退火过程而设计的优化算法 初始处于一个高温状态下&#xff0c;然后逐渐退火&#xff0c;在每个温度下慢慢冷却&#xff0c;最终达到物理基态&#xff08;相当于算法找到最优解&#xff09; 求解TSP问题(旅行商问题)、最值问题、全…

模拟退火算法(Simulated Annealing,SA)

这是一篇关于模拟退火算法的总结博客&#xff0c;包括算法思想&#xff0c;算法步骤&#xff0c;Python实现&#xff0c;MATLAB实现&#xff0c;算法进阶等。 目录 1 算法思想2 算法步骤3 SA解函数最小值&#xff08;python实现&#xff09;4 SA解旅行商问题&#xff08;MATLA…

退火算法(Annealing)简介与详解

模拟退火算法&#xff08;Simulated Annealing&#xff0c;SA&#xff09; 秒懂爬山算法&#xff08;Hill Climbing&#xff09;退火算法 详解算法来源数学推导来源&#xff1a;metropolis准则&#xff08;蒙特卡洛准则&#xff09; 算法流程算法优劣例题 秒懂 爬山算法&#…

Instrumentation框架分析及其使用

本文旨在从Android系统源码出发,简单梳理Instrumentation框架的行为及逻辑结构,供有兴趣的同学一起学习 从am instrument谈起 am instrument命令的执行 我们知道,命令行运行Android测试的命令是adb shell am instrument,这个命令是如何调起我们的测试代码来进行测试的呢,…

android.app.instrumentation解析

已经在Android SDK中学习了很多关于JUnit的内容&#xff0c;但是感觉一直有几个问题没有解决&#xff08;不知道大家是否有同样的感受&#xff09;JUnit的测试都自动化的&#xff0c;完全是不需要任何操作的&#xff0c;有2个问题我一直都还没有找到答案&#xff0c;这2个问题如…

Java探针 Instrumentation

背景&#xff1a;假如我们想打印出某些系统->某些类->某些方法的执行耗时&#xff0c;方式有很多&#xff0c;但是想要无侵入的做到这一点&#xff0c;只有Java探针一种方式。这也是很多调用链系统依赖的技术基础。 什么是Java探针 通俗来讲&#xff0c;就是Java提供的一…

opentelemetry-java-instrumentation翻译

原文地址&#xff1a;原文 OpenTelemetry Instrumentation for Java 这个项目提供了一个Java agent JAR&#xff0c;这个jar可以attached to任何Java8的应用上&#xff0c;动态地注入&#xff08;inject&#xff09;字节码从大量的流行库和框架&#xff08;popular libraries …

Instrument

使用Instruments 里面的Automation&#xff0c;可以对iOS进行自动化测试。 参考这篇文章&#xff1a;http://www.codeproject.com/KB/iPhone/UI_Automation_Testing.aspx 我用的是xcode4.2。 在这里下载修改好的项目&#xff0c;xcode4.2下用的&#xff1a;http://download.csd…

android Instrumentation

Android提供了一系列强大的测试工具&#xff0c;它针对Android的环境&#xff0c;扩展了业内标准的JUnit测试框架。尽管你可以使用JUnit测试Android工程&#xff0c;但Android工具允许你为应用程序的各个方面进行更为复杂的测试&#xff0c;包括单元层面及框架层面。 Android测…