三、python实现模拟退火算法

一、概述

  模拟退火算法是一种通用的优化算法,理论上算法具有概率的全局优化性能,目前已在工程中得到了广泛应用,诸如机器学习、神经网络、信号处理等领域。

二、算法原理

  模拟退火算法的思想借鉴于固体的退火原理,当固体的温度很高的时候,内能比较大,固体的内部粒子处于快速无序运动,当温度慢慢降低的过程中,固体的内能减小,粒子的慢慢趋于有序,最终,当固体处于常温时,内能达到最小,此时,粒子最为稳定。模拟退火算法便是基于这样的原理设计而成。
   模拟退火算法从某一高温出发,在高温状态下计算初始解,然后以预设的邻域函数产生一个扰动量,从而得到新的状态,即模拟粒子的无序运动,比较新旧状态下的能量,即目标函数的解。如果新状态的能量小于旧状态,则状态发生转化;如果新状态的能量大于旧状态,则以一定的概率准则发生转化。当状态稳定后,便可以看作达到了当前状态的最优解,便可以开始降温,在下一个温度继续迭代,最终达到低温的稳定状态,便得到了模拟退火算法产生的结果。
  根据以上描述,可以得出模拟退火算法的计算步骤如下:

  1. 初始化: 初始温度 T T T (充分大),温度下限 T min ⁡ T_{\min } Tmin (充分小),初始解状态 x x x (是算法迭代的起点),每个 T T T 值的迭代 次数 L L L;
  2. l = 1 , 2 , … , L l=1,2, \ldots, L l=1,2,,L 做第 3 至第 6 步;
  3. 产生新解 x new.  x new  = x + Δ x ; Δ x x_{\text {new. }} x_{\text {new }}=x+\Delta x ; \Delta x xnew. xnew =x+Δx;Δx [ d min ⁡ , d max ⁡ ] \left[d_{\min }, d_{\max }\right] [dmin,dmax] 之间的随机数;
  4. 利计算增量 Δ f = f ( x n e w ) − f ( x ) \Delta f=f\left(x_{n e w}\right)-f(x) Δf=f(xnew)f(x) ,其中 f ( x ) f(x) f(x) 为优化目标;
  5. Δ f < 0 \Delta f<0 Δf<0 (若寻找最大值, Δ f > 0 \Delta f>0 Δf>0 ) 则接受 x n e w x_{n e w} xnew 作为新的当前解,否则以概率 exp ⁡ ( − Δ f / ( k T ) ) \exp (-\Delta f /(k T)) exp(Δf/(kT)) 接受 x n e w x_{n e w} xnew 作为新的 当前解;
  6. 如果满足终止条件则输出当前解作为最优解,结束程序。(终止条件通常取为连续若干个新解都没有被接受时终止算 法;
  7. T T T 逐渐减少,且 T > T min ⁡ T>T_{\min } T>Tmin ,然后转第 2步。

三、python实现

3.1 构建目标函数

import numpy as np
import matplotlib.pyplot as plt

# 构建目标函数
def aimFunc(x):
    y = 11 * np.sin(x) + 7*np.cos(5*x)
    return y

# 展示目标函数在待求区间的曲线
x = np.arange(-3, 3, 0.01)
y = aimFunc(x)
plt.plot(x, y)
plt.show()

在这里插入图片描述

3.2 算法实现

# 构建新位置
def new_x(x, T, x_l, x_h):
    # 计算新的位置
    _x_new = x + np.random.uniform(-1, 1) * T
    # 若新位置超出上、下限,对位置进行重新调整
    if(_x_new < x_l):
        _x_new = x - np.random.uniform(0, 1)*(x-x_l)
    if(_x_new > x_h):
        _x_new = x + np.random.uniform(0, 1)*(x_h-x)
    return _x_new
  
# 定义x的范围
x_l = -3
x_h = 3
# 定义初始温度
T = 1000
# 定义内循环次数
N = 20
# 定义初始位置
_x = np.random.uniform(low=x_l, high=x_h)
_y = aimFunc(_x)
# 定义记录仪
_x_track = []
_y_track = []
while T >= 0.001:
    for i in range(N):
        # 获取新的位置
        _x_new = new_x(_x, T, x_l, x_h)
        # 计算新位置对应的函数值
        _y_new = aimFunc(_x_new)
        # 判断是否接受新的位置
        flag_1 = _y_new < _y
        flag_2 = np.exp(-(_y_new-_y)/T) > np.random.uniform()
        if(flag_1 | flag_2):
            _x = _x_new
            _y = _y_new
    _x_track.append(_x)
    _y_track.append(_y)
    # 更新温度
    T = T * 0.8

# 展示计算结果
print(_x)
print(_y)
plt.plot(_x_track)
plt.show()
plt.plot(_y_track)
plt.show()
plt.plot(x, y)
plt.scatter(_x, _y, c='r')
plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、Tips

  模拟退火算法存在以下三个调参问题:

  1. 温度T的初始值设置问题
      温度T的初始值设置是影响模拟退火算法全局搜索性能的重要因素之一、初始温度高,则搜索到全局最优解的可能性大,但因此要花费大量的计算时间;反之,则可节约计算时间,但全局搜索性能可能受到影响。
  2. 退火速度问题,即每个T值的迭代次数L
      模拟退火算法的全局搜索性能也与退火速度密切相关。一般来说,同一温度下的“充分”搜索是相当必要的,但这也需要计算时间。循环次数增加必定带来计算开销的增大。
  3. 温度管理问题
      温度管理问题也是模拟退火算法难以处理的问题之一。实际应用中,由于必须考虑计算复杂度的切实可行性等问题。
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白银时代_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值