模拟退火算法(Python)

article/2025/9/20 23:44:01

一、模拟退火算法

1、模拟退火算法的定义

模拟退火算法是一种现代优化算法。基于蒙特卡洛迭代求解方法的随机寻优算法,模拟退火算法于1983 年成功地应用到组合优化领域。因固体物理退火过程与组合优化问题存在着相似性,模拟退火算法对固体物质的退火过程进行一定程度的模拟,来获得问题的最优解。

2、模拟退火算法的特点

优点

① 全局搜索能力强,统计上可以保证找到全局最优

缺点

① 找到最优解所耗费的时间较长,尤其是使用标准的Metropolis准则时

3、模拟退火算法的主要步骤

模拟退火算法本质是两层循环,外层循环控制温度由高向低变化;内层循环中,温度固定,对旧解添加随机扰动得到新解,并按一定规则接受新解。

① 解的编码

② 确定初始解

③ 邻域新解的生成

④ 确定能量函数

⑤ Metropolis准则

⑥ 搜索最优解

二、模拟退火算法基本模型

(以求解 x^{3}cosx(-1.57\leq x\leq 20.18) 的最小值为例)

 1、解的编码

由于该解的表示简单,采用实数编码即可。

2、确定初始解

根据定义域范围,随机生成初始解

#[start,end]为定义域
def initialization(start, end):return random.uniform(start, end)

3、邻域新解的生成

① 判断生成的解是否在定义域范围内

def in_range(x, start, end):return True if start <= x <= end else False

② 生成邻域新解

def generate_new(x, start, end):while True:#采用高斯分布生成新解upper_bound = end - xlower_bound = start - xsigma = max(upper_bound, lower_bound) / 3new_x = random.gauss(x, sigma)#判断是否在定义域内,在则返回;否则重复生成if in_range(new_x, start, end):return new_x

4、确定能量函数

能量越低,被接受的概率越高。因此,当求解最大值目标函数时,可以以目标函数的倒数作为能量函数;当求解最小值目标函数时,可以直接以目标函数作为能量函数

def e(x):return pow(x, 3) * math.cos(x)

5、新解接受准则

新解接受准则的三条原则

① 在固定温度下,接受使目标函数下降的候选解的概率要大于使目标函数上升的候选解概率;

② 随着温度的下降,接受使目标函数上升的解的概率要逐渐减小;

③ 当温度趋于零时,只能接受目标函数下降的解。

Metropolis准则

新解接受常采用标准的Metropolis准则

在这里插入图片描述

 若\Delta E< 0,接受新解作为当前解;否则,按照概率判断是否接受新解。

def metropolis(e, new_e, t):if new_e <= e:return Trueelse:p = math.exp((e - new_e) / t)return True if random.random() < p else False

6、搜索最优解

def search(all_x):best_e = 0xffffbest_x = all_x[0]for x in all_x:ex = e(x)if ex < best_e:best_e = exbest_x = xreturn best_x

7、主函数

#t0为初始温度,t_final为终止温度,alpha为冷却系数,inner_iter为内层迭代次数,[start,end]为定义域
def sa(t0, t_final, alpha, inner_iter, start, end):#记录每次内层迭代生成的解all_x = []#生成初始解并加入解集init = initialization(start, end)all_x.append(init)#设置初始温度t = t0#外层循环while t > t_final:x = search(all_x)ex = e(x)#内层循环for i in range(inner_iter):new_x = generate_new(x, start, end)new_ex = e(new_x)if metropolis(ex, new_ex, t):x = new_xex = new_exall_x.append(x)t = alpha * treturn all_x

8、问题求解

all_x = sa(3000, 10, 0.98, 200, -1.57, 20.18)
print(round(search(all_x), 3), round(e(search(all_x)), 3))
iteration = len(all_x)
all_x = np.array(all_x)
all_ex = all_x ** 3 * np.cos(all_x)
plt.xlabel("Iteration")
plt.ylabel("f(x)")
plt.plot(range(iteration), all_ex)
plt.show()

 输出结果如下

15.894 -3945.849

 三、模拟退火算法求解TSP模型

以下图为例,求从0号城市出发访问每一座城市并回到0号城市的最短回路

1、基本模型

① 解的编码 

求解TSP模型采用自然数编码,0节点代表初始城市,1-7节点表示其他7座城市。如 1,7,6,3,2,5,4 表示从0出发依次经过城市1、7、6、3、2、5、4最后回到0

② 确定初始解

随机生成一个由数字1-7各出现一次的数列。

③ 邻域新解的生成

采用两点逆转的方法,即对数列设置两个点,然后数列在这两点中发生逆转,改变数列。逆转操作如下:假设数列为A=1,4,5,2,3,6,7,随机生成两个点2和6,那么A1=4,5,2,3,6,逆转后A1=6,3,2,5,4,A=1,6,3,2,5,4,7。

④ 确定能量函数

TSP模型以最短路径为目标函数,因此直接以路径长度为能量函数即可。

⑤ 新解接受准则

采用标准的Metropolis准则。

⑥ 搜索最优解

根据已生成的所有解的能量,搜索能量最低的解,即为模拟退火算法的最优解

2、代码求解

① 确定初始解

#numbers为需要经过的其他城市的数量
def initialization(numbers):path_random = np.random.choice(list(range(1, numbers + 1)), replace=False, size=numbers)path_random = path_random.tolist()return path_random

② 邻域新解的生成

def generate_new(path):numbers = len(path)#随机生成两个不重复的点positions = np.random.choice(list(range(numbers)), replace=False, size=2)lower_position = min(positions[0], positions[1])upper_position = max(positions[0], positions[1])#将数列中段逆转mid_reversed = path[lower_position:upper_position + 1]mid_reversed.reverse()#拼接生成新的数列new_path = path[:lower_position]new_path.extend(mid_reversed)new_path.extend(path[upper_position + 1:])return new_path

 ③ 确定能量函数

#length_mat为各个节点之间的最短距离矩阵
def e(path, length_mat):numbers = len(path) - 1length = length_mat[0][path[0]] + length_mat[path[-1]][0]for i in range(numbers):length += length_mat[path[i]][path[i + 1]]return length

 ④ Metropolis准则

def metropolis(e, new_e, t):if new_e <= e:return Trueelse:p = math.exp((e - new_e) / t)return True if random.random() < p else False

 ⑤ 搜索最优解

def search(all_path, length_mat):best_e = 0xffffbest_path = all_path[0]for path in all_path:ex = e(path, length_mat)if ex < best_e:best_e = exbest_path = pathreturn best_path

⑥ 模拟退火算法主函数

#t0为初始温度,t_final为终止温度,alpha为冷却系数,inner_iter为内层迭代次数
#city_numbers为所需要经过的其他城市,length_mat为各个节点之间的最短距离矩阵
def sa(t0, t_final, alpha, inner_iter, city_numbers, length_mat):all_path = []all_ex = []init = initialization(city_numbers)all_path.append(init)all_ex.append(e(init, length_mat))t = t0while t > t_final:path = search(all_path, length_mat)ex = e(path, length_mat)for i in range(inner_iter):new_path = generate_new(path)new_ex = e(new_path, length_mat)if metropolis(ex, new_ex, t):path = new_pathex = new_exall_path.append(path)all_ex.append(ex)t = alpha * treturn all_path, all_ex

⑦ 主程序

先通过Floyd算法求每个节点的最短路径

graph = nx.Graph()
graph.add_nodes_from(range(0, 8))
edges = [(0, 1, 3), (0, 4, 2),(1, 4, 3), (1, 5, 4), (1, 7, 2),(2, 3, 5), (2, 4, 1), (2, 5, 4), (2, 6, 3),(3, 6, 1),(4, 5, 5),(5, 6, 2), (5, 7, 4),(6, 7, 4)]
graph.add_weighted_edges_from(edges)
shortest_length = dict(nx.shortest_path_length(graph, weight='weight'))
length_mat = []
for i in range(0, 8):i_j = []for j in range(0, 8):i_j.append(shortest_length[i][j])length_mat.append(i_j)

(图论详见(23条消息) 图论(Python networkx)_Zengwh_02的博客-CSDN博客)

再调用模拟退火算法求最优解,并可视化

all_path, all_ex = sa(3000, pow(10, -1), 0.98, 200, 7, length_mat)
print(search(all_path, length_mat), round(e(search(all_path, length_mat), length_mat)))
iteration = len(all_path)
all_path = np.array(all_path)
all_ex = np.array(all_ex)
plt.xlabel("Iteration")
plt.ylabel("Length")
plt.plot(range(iteration), all_ex)
plt.show()

 3、输出结果

[1, 7, 5, 6, 3, 2, 4] 19


http://chatgpt.dhexx.cn/article/5u3NCHOw.shtml

相关文章

模拟退火算法详细说明

来源&#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测…

Instrumentation 应用简介

引用&#xff1a; java-instrumentation 引用&#xff1a;Instrumentation 新功能 简介 java Instrumentation指的是可以用独立于应用程序之外的代理&#xff08;agent&#xff09;程序来监测和协助运行在JVM上的应用程序。这种监测和协助包括但不限于获取JVM运行时状态&#…

AndroidStudio单元测试——instrumentation

前言&#xff1a;这几天老大要我搞代码自动测试&#xff0c;eclispe的已经解决了&#xff0c;可他们都是用android studio&#xff0c;所以要在android studio 上重新试验&#xff0c;这个有难度啊&#xff0c;android studio国内资料极少&#xff0c;更不要说单元测试了。goog…

Android Instrumentation 简介

Instrumentation 简介 APIs && Source code 官方APIs地址(需要翻墙)Source code Instrumentation 特点 该框架基于JUnit&#xff0c;因此既可以直接使用Junit 进行测试&#xff0c;也可以使用Instrumentation 来测试Android 组件其为Android 应用的每种组件提供了测…

冲突域和广播域?

如何理解冲突域和广播域&#xff1f; 冲突域&#xff1a; 【定义】在同一个冲突域中的每一个节点都能收到所有被发送的帧。简单的说就是同一时间内只能有一台设备发送信息的范围。 【分层】基于OSI的第一层物理层 【设备】第二层设备能隔离冲突域&#xff0c;比如Switch。交…

广播域与冲突域

广播域与冲突域 一个集线器&#xff08;中继器&#xff09;连接的网络成为冲突域&#xff0c;因为每台主机都连接在了同一条线路上&#xff0c;所以传送信息时会冲突。 冲突域是基于第一层(物理层) 而交换机的本质是一个多借口网桥&#xff0c;就是说由交换机组成的网络中&…

冲突域广播域

网络互连设备可以将网络划分为不同的冲突域、广播域。但是&#xff0c;由于不同的网络互连设备可能工作在OSI模型的不同层次上。因此&#xff0c;它们划分冲突域、广播域的效果也就各不相同。如中继器工作在物理层&#xff0c;网桥和交换机工作在数据链路层&#xff0c;路由器工…