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


最近老师要求做模拟退火算法实验,看了很多博客之后感觉还是不太清楚,最后问了老师之后才搞明白。想把自己的理解写下来,帮助大家更好的理解。本篇文章是在另一篇博客的基础上加了一下自己的理解,然后又把我们在实验中的实例写下来,还有参考代码。希望大家看了之后能够加深对模拟退火算法的理解。

另一篇博客链接: 深度学习 — 模拟退火算法详解.

(一)模拟退火算法简介

模拟退火算法(SA)来源于固体退火原理,是一种基于概率的算法。将固体加温至充分高的温度,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,分子和原子越不稳定。而徐徐冷却时粒子渐趋有序,能量减少,原子越稳定。在冷却(降温)过程中,固体在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。
模拟退火算法从某一较高初温出发,伴随温度参数的不断下降,结合概率突跳特性在解空间中随机寻找目标函数的全局最优解,即在局部最优解能概率性地跳出并最终趋于全局最优。模拟退火算法是通过赋予搜索过程一种时变且最终趋于零的概率突跳性,从而可有效避免陷入局部极小并最终趋于全局最优的串行结构的优化算法。

(二)模拟退火算法原理

模拟退火算法包含两个部分即Metropolis算法和退火过程,,分别对应内循环和外循环。外循环就是退火过程,将固体达到较高的温度(初始温度T(0)),然后按照降温系数alpha使温度按照一定的比例下降,当达到终止温度Tf时,冷却结束,即退火过程结束。
Metropolis算法是内循环,即在每次温度下,迭代L次,寻找在该温度下能量的最小值(即最优解)。下图中所示即为在一次温度下,跌代L次,固体能量发生的变化。在该温度下,整个迭代过程中温度不发生变化,能量发生变化,当前一个状态x(n)的能量大于后一个状态x(n+1)的能量时,状态x(n)的解没有状态x(n+1)的解好,所以接受状态x(n+1)。但是如果下一状态的能量比前一个状态的能量高时,该不该接受下一状态呢?在这里设置一个接受概率P,即如果下一状态的能量比前一个状态的能量高,则接受下一状态的概率为P,下面具体讲一下如何接受下一个状态。

在这里插入图片描述

Metropolis算法就是如何在局部最优解的情况下让其跳出来(如图中B、C、E为局部最优),是退火的基础。1953年Metropolis提出重要性采样方法,即以概率来接受新状态,而不是使用完全确定的规则,称为Metropolis准则,计算量较低。

假设开始状态在A,多次迭代之后更新到B的局部最优解,这时发现更新到B时,能力比A要低,则说明接近最优解了,因此百分百转移,状态到达B后,发现下一步能量上升了,如果是梯度下降则是不允许继续向前的,而这里会以一定的概率跳出这个坑,这各概率和当前的状态、能量等都有关系。所以说这个概率的设计是很重要的,下面从数学方面进行解释。

假设前一个状态为x(n),系统根据某一指标(梯度下降,上节的能量),状态变为x(n+1),相应的,系统的能量由E(n)变为E(n+1),定义系统由x(n)变为x(n+1)的接受概率P为:
在这里插入图片描述

从上式我们可以看到,如果能量减小了,那么这种转移就被接受(概率为1),如果能量增大了,就说明系统偏离全局最优值位置更远了,此时算法不会立刻将其抛弃,而是进行概率操作:首先在区间【0,1】产生一个均匀分布的随机数 ϵ \epsilon ϵ,如果 ϵ \epsilon ϵ<P,则此种转移接受,否则拒绝转移,进入下一步,往复循环。其中P以能量的变化量和T进行决定概率P的大小,所以这个值是动态的。
用固体退火模拟组合优化问题,将内能E模拟为目标函数值f,温度T演化成控制参数t,即得到解组合优化问题的模拟退火算法:由初始解i和控制参数初值t开始,对当前解重复“产生新解→计算目标函数差→接受或舍弃”的迭代,并逐步衰减t值,算法终止时的当前解即为所得近似最优解,退火过程由冷却进度表(Cooling Schedule)控制,包括控制参数的初值t及其衰减因子Δt、每个t值时的迭代次数L和停止条件Tf。而温度的作用就是来计算转移概率P的。当温度每次下降后,转移概率也发生变化,因此在所有温度下迭代L次的结果也都是不相同的。在每个温度下迭代L次来寻找当前温度下的最优解,然后降低温度继续寻找,直到到达终止温度,即转移概率P接近于0.

接受状态的三条原则:

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

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

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

(三)退火过程中参数控制

(1)初始的温度T(0)应选的足够高,使的所有转移状态都被接受。初始温度越高,获得高质量的解的概率越大,耗费的时间越长。

(2)退火速率,即温度下降,最简单的下降方式是指数式下降:
T(n) = α \alpha αT(n) ,n =1,2,3,…
其中 α \alpha α是小于1的正数,一般取值为0.8到0.99之间。使的对每一温度,有足够的转移尝试,指数式下降的收敛速度比较慢。

(3)终止温度
如果温度下降到终止温度或者达到用户设定的阈值,则退火完成。

模拟退火算法(Simulated Annealing)是一种随机优化算法,用于求解复杂的优化问题。它灵感来自物理中的退火过程,通过在搜索过程中接受一定概率上不太好的解,能够避免陷入局部最优解,最终找到全局最优解。 算法步骤如下: 1. 初始化温度(T)和初始解(x),将当前解设为当前最优解。 2. 在当前解的邻域中随机选择一个新的解(y)。 3. 计算新解和当前最优解之间的差值(delta_E)。 4. 如果delta_E小于等于0,接受新解,并将其设为当前最优解。 5. 如果delta_E大于0,根据一定的概率决定是否接受新解。概率计算公式为:P = exp(-delta_E / T),其中T为当前温度。 6. 重复步骤2-5,直到满足停止条件(如达到最大迭代次数或温度降低到一定程度)。 下面是使用模拟退火算法解决旅行商问题的Python代码示例: ```python import random import math def distance(x1, y1, x2, y2): return math.sqrt((x1-x2)**2 + (y1-y2)**2) def total_distance(path, cities): total = 0 for i in range(len(path)-1): city1 = cities[path[i]] city2 = cities[path[i+1]] total += distance(city1[0], city1[1], city2[0], city2[1]) return total def simulated_annealing(cities, T, alpha, stopping_condition): current_path = list(range(len(cities))) random.shuffle(current_path) current_cost = total_distance(current_path, cities) best_path = current_path[:] best_cost = current_cost while T > stopping_condition: i = random.randint(0, len(cities)-1) j = random.randint(0, len(cities)-1) new_path = current_path[:] new_path[i], new_path[j] = new_path[j], new_path[i] new_cost = total_distance(new_path, cities) delta_E = new_cost - current_cost if delta_E <= 0: current_path = new_path current_cost = new_cost if new_cost < best_cost: best_path = new_path[:] best_cost = new_cost else: p = math.exp(-delta_E / T) if random.random() < p: current_path = new_path current_cost = new_cost T *= alpha return best_path, best_cost # 测试 cities = [(0, 0), (1, 5), (5, 7), (3, 2), (7, 6)] T = 100 alpha = 0.99 stopping_condition = 0.01 best_path, best_cost = simulated_annealing(cities, T, alpha, stopping_condition) print("最优路径:", best_path) print("最优路径长度:", best_cost) ``` 以上代码实现了模拟退火算法解决旅行商问题。首先定义了计算两个城市间距离的函数distance和计算整个路径长度的函数total_distance。然后通过simulated_annealing函数执行模拟退火算法,在给定的城市列表中找到最短路径。最后输出最优路径和路径长度。 模拟退火算法是一种强大的优化算法,可以用于求解各种复杂的优化问题。
评论 58
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值