数学建模(三):模拟退火算法(SA)

这篇具有很好参考价值的文章主要介绍了数学建模(三):模拟退火算法(SA)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

模拟退火算法(SA)

一、 概述

1、 算法简介

模拟退火算法(simulated annealing,SA)来源于固体退火原理,是一种基于概率的算法。

数学建模(三):模拟退火算法(SA)

模拟退火算法(SA)来源于固体退火原理,是一种基于概率的算法。将固体加温至充分高的温度,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,分子和原子越不稳定。而徐徐冷却时粒子渐趋有序,能量减少,原子越稳定。在冷却(降温)过程中,固体在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。

模拟退火算法从某一较高初温出发,伴随温度参数的不断下降,结合概率突跳特性在解空间中随机寻找目标函数的全局最优解,即在局部最优解能概率性地跳出并最终趋于全局最优。模拟退火算法是通过赋予搜索过程一种时变且最终趋于零的概率突跳性,从而可有效避免陷入局部极小并最终趋于全局最优的串行结构的优化算法。

2、 核心思想

模拟退火算法从某一较高初温出发,伴随温度参数的不断下降,结合一定的概率突跳特性在解空间中随机寻找目标函数的全局最优解,即在局部最优解能概率性地跳出并最终趋于全局最优。

这里的 “一定的概率” 的计算参考了金属冶炼的退火过程,这也是模拟退火算法名称的由来。将温度 T 当作控制参数,目标函数值 f 视为内能 E ,而固体在某温度 T 时的一个状态对应一个解 x i x_i xi,然后算法试图随着控制参数 T 的降低,使目标函数 f (内能 E )也逐渐降低,直至趋于全局最小值(退火中低温时的最低能量状态),就像金属退火过程一样。

关于爬山算法与模拟退火,有一个有趣的比喻:

  • 爬山算法:兔子朝着比现在高的地方跳去。它找到了不远处的最高山峰。但是这座山不一定是珠穆朗玛峰。这就是爬山算法,它不能保证局部最优值就是全局最优值。

  • 模拟退火:兔子喝醉了。它随机地跳了很长时间。这期间,它可能走向高处,也可能踏入平地。但是,它渐渐清醒了并朝最高方向跳去。这就是模拟退火。

3、 数学原理

从上面我们知道,会结合概率突跳特性在解空间中随机寻找目标函数的全局最优解,那么具体的更新解的机制是什么呢?如果新解比当前解更优,则接受新解,否则基于Metropolis准则判断是否接受新解。接受概率为:

数学建模(三):模拟退火算法(SA)

数学建模(三):模拟退火算法(SA)

假设开始状态在A,随着迭代次数更新到B局部最优解,这时发现更新到B时,能量比A要低,则说明接近最优解了,因此百分百转移,状态到达B后,发现下一步能量上升了,如果是梯度下降则是不允许继续向前的,而这里会以一定的概率跳出这个坑,这个概率和当前的状态、能量等都有关系,如果B最终跳出来了到达C,又会继续以一定的概率跳出来,直到到达D后,就会稳定下来。

4、 模拟退火的流程

(1) 初始化:初始温度 T (充分大),初始解状态S(是算法迭代的起点),每个 T 值的迭代次数 L

(2) 对 k=1, …, L 做第(3)至第(6)步:

(3) 产生新解 S′

(4) 计算增量 ΔT = C(S′)-C(S),其中 C(S) 为目标函数, C(S) 相当于能量

(5) 若 ΔT<0 则接受 S′ 作为新的当前解,否则以概率 exp(-ΔT/T) 接受S′作为新的当前解.

(6) 如果满足终止条件则输出当前解作为最优解,结束程序。

(7) T 逐渐减少,且 T->0 ,然后转第2步。

数学建模(三):模拟退火算法(SA)

其中有几个需要注意的点:

  • 初始点的选取对算法结果有一定的影响,最好是多次运行对结果进行综合判断。
  • 在算法运行初期,温度下降快,避免接受过多的差结果。当运行时间增加,温度下降减缓,以便于更快稳定结果。
  • 当迭代次数增加到一定次数时,结果可能已经达到稳定,但是距离算法结束还有一段时间。在设计程序时应该加入适当的输出条件,满足输出条件即可结束程序。

可以大概分为这四个步骤:

  1. 第一步是由一个产生函数从当前解产生一个位于解空间的新解;为便于后续的计算和接受,减少算法耗时,通常选择由当前新解经过简单地变换即可产生新解的方法,如对构成新解的全部或部分元素进行置换、互换等,注意到产生新解的变换方法决定了当前新解的邻域结构,因而对冷却进度表的选取有一定的影响。
  2. 第二步是计算与新解所对应的目标函数差。因为目标函数差仅由变换部分产生,所以目标函数差的计算最好按增量计算。事实表明,对大多数应用而言,这是计算目标函数差的最快方法。
  3. 第三步是判断新解是否被接受,判断的依据是一个接受准则,最常用的接受准则是 Metropolis 准则: 若 ΔT < 0 则接受 S′ 作为新的当前解 S,否则以概率 P 接受 S′ 作为新的当前解 S。
  4. 第四步是当新解被确定接受时,用新解代替当前解,这只需将当前解中对应于产生新解时的变换部分予以实现,同时修正目标函数值即可。此时,当前解实现了一次迭代。可在此基础上开始下一轮试验。而当新解被判定为舍弃时,则在原当前解的基础上继续下一轮试验。

二、 实例分析

数学建模(三):模拟退火算法(SA)

1、 初始化参数

# -*- coding: utf-8 -*-
"""
Created on Mon Apr  3 19:17:28 2023

@author: steve
"""
from random import random
import math
import matplotlib.pyplot as plt


max_iter = 100  # 每一次温度降低的迭代次数
alpha = 0.99  # 降温系数
T_f = 0.01  # 温度的终值
T_n = 100  # 当前的温度,也是初始温度
x, y = [random() * 10 - 5 for i in range(max_iter)], [random() * 10 - 5 for i in range(max_iter)] # 进行数据的初始化
f = lambda x, y : (4 * x ** 2 - 2.1 * x ** 4 + x ** 6 / 3 + x * y - 4 * y ** 2 + 4 * y ** 4)  # 我们需要求的函数
result = {
    "f": [], 
    "t": []
    }  # 用来存放每一次下降的最优解

2、 Metrospolis 准则

def metrospolis(T_n, old, new):
    """
    进行 Metrospolis 准则的判断

    Parameters
    ----------
    T_n : int
        当前的温度.  
    old : double
        函数扰动之前的值.
    new : double
        函数扰动之后的值.

    Returns
    -------
    int
        是否需要重新寻找值.
    """
    if old >= new:
        return 1
    else:
        p = math.exp((old - new) / T_n)
        if random() < p:
            return 1
        else:
            return 0

3、 生成新的值

def generate_new(T_n, x, y):
    """
    其为扰动的过程

    Parameters
    ----------
    T_n : int
        当前的温度.
    x : double
        DESCRIPTION.
    y : double
        DESCRIPTION.

    Returns
    -------
    list
        返回生成的新值.
    """
    while True:
        x_new = x + T_n * (random() - random())
        y_new = y + T_n * (random() - random())
        if (-5 <= x_new <= 5) & (-5 <= y_new <= 5):  
            break                                  #重复得到新解,直到产生的新解满足约束条件
    return x_new, y_new 

4、 获取最优值

def best(max_iter, f, x, y):
    """
    计算这个温度下的最优值

    Parameters
    ----------
    max_iter : int
        最大的迭代次数.
    f : function
        我们需要求的函数.
    x : double
        DESCRIPTION.
    y : double
        DESCRIPTION.

    Returns
    -------
    list
        返回最优值,以及它的索引.

    """
    min_val, min_inx = f(x[0], y[0]), 0
    for i in range(max_iter):
        val = f(x[i], y[i])
        if min_val > val:
            min_val, min_inx = val, i
            
    return [min_val, min_inx]

5、 主程序

def plot(result):
    plt.plot(result['t'], result['f'])
    plt.title('SA')
    plt.xlabel('t')
    plt.ylabel('f')
    plt.gca().invert_xaxis()
    plt.show()


def main(max_iter, alpha, T_f, T_n, x, y, f, result):
    count = 0  # 统计迭代了多少次
    while T_n > T_f:  # 外层循环,当前温度小于最低温度时,终止循环
        for i in range(max_iter):  # 内层循环
            x_new, y_new = generate_new(T_n, x[i], y[i])  # 产生新值
            if metrospolis(T_n, f(x[i], y[i]), f(x_new, y_new)):  # 将原值与新产生的值进行比较
                x[i] = x_new  # 如果接收新值,则存入数组中
                y[i] = y_new
        # 迭代 max_iter 后,记录该温度下的最优解
        [ft, _] = best(max_iter, f, x, y)
        result["f"].append(ft)
        result["t"].append(T_n)
        T_n = T_n * alpha  # 进行降温操作
        count += 1
        
    # 得到最优解
    [f_best, inx] = best(max_iter, f, x, y)
    print(f"F={f_best}, x_1={x[inx]}, x_2={y[inx]}")
    # 进行图像表示
    plot(result)

6、 总代码

# -*- coding: utf-8 -*-
"""
Created on Mon Apr  3 19:17:28 2023

@author: steve
"""
from random import random
import math
import matplotlib.pyplot as plt


def metrospolis(T_n, old, new):
    """
    进行 Metrospolis 准则的判断

    Parameters
    ----------
    T_n : int
        当前的温度.  
    old : double
        函数扰动之前的值.
    new : double
        函数扰动之后的值.

    Returns
    -------
    int
        是否需要重新寻找值.
    """
    if old >= new:
        return 1
    else:
        p = math.exp((old - new) / T_n)
        if random() < p:
            return 1
        else:
            return 0
        
        
def generate_new(T_n, x, y):
    """
    其为扰动的过程

    Parameters
    ----------
    T_n : int
        当前的温度.
    x : double
        DESCRIPTION.
    y : double
        DESCRIPTION.

    Returns
    -------
    list
        返回生成的新值.
    """
    while True:
        x_new = x + T_n * (random() - random())
        y_new = y + T_n * (random() - random())
        if (-5 <= x_new <= 5) & (-5 <= y_new <= 5):  
            break                                  #重复得到新解,直到产生的新解满足约束条件
    return x_new, y_new 
    
def best(max_iter, f, x, y):
    """
    计算这个温度下的最优值

    Parameters
    ----------
    max_iter : int
        最大的迭代次数.
    f : function
        我们需要求的函数.
    x : double
        DESCRIPTION.
    y : double
        DESCRIPTION.

    Returns
    -------
    list
        返回最优值,以及它的索引.

    """
    min_val, min_inx = f(x[0], y[0]), 0
    for i in range(max_iter):
        val = f(x[i], y[i])
        if min_val > val:
            min_val, min_inx = val, i
            
    return [min_val, min_inx]


def plot(result):
    plt.plot(result['t'], result['f'])
    plt.title('SA')
    plt.xlabel('t')
    plt.ylabel('f')
    plt.gca().invert_xaxis()
    plt.show()



def main(max_iter, alpha, T_f, T_n, x, y, f, result):
    count = 0  # 统计迭代了多少次
    while T_n > T_f:  # 外层循环,当前温度小于最低温度时,终止循环
        for i in range(max_iter):  # 内层循环
            x_new, y_new = generate_new(T_n, x[i], y[i])  # 产生新值
            if metrospolis(T_n, f(x[i], y[i]), f(x_new, y_new)):  # 将原值与新产生的值进行比较
                x[i] = x_new  # 如果接收新值,则存入数组中
                y[i] = y_new
        # 迭代 max_iter 后,记录该温度下的最优解
        [ft, _] = best(max_iter, f, x, y)
        result["f"].append(ft)
        result["t"].append(T_n)
        T_n = T_n * alpha  # 进行降温操作
        count += 1
        
    # 得到最优解
    [f_best, inx] = best(max_iter, f, x, y)
    print(f"F={f_best}, x_1={x[inx]}, x_2={y[inx]}")
    # 进行图像表示
    plot(result)
    


max_iter = 100  # 每一次温度降低的迭代次数
alpha = 0.99  # 降温系数
T_f = 0.01  # 温度的终值
T_n = 100  # 当前的温度,也是初始温度
x, y = [random() * 10 - 5 for i in range(max_iter)], [random() * 10 - 5 for i in range(max_iter)] # 进行数据的初始化
f = lambda x, y : (4 * x ** 2 - 2.1 * x ** 4 + x ** 6 / 3 + x * y - 4 * y ** 2 + 4 * y ** 4)  # 我们需要求的函数
result = {
    "f": [], 
    "t": []
    }  # 用来存放每一次下降的最优解

main(max_iter, alpha, T_f, T_n, x, y, f, result)

最后的运行结果为:

数学建模(三):模拟退火算法(SA)文章来源地址https://www.toymoban.com/news/detail-416348.html

到了这里,关于数学建模(三):模拟退火算法(SA)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数学建模】《实战数学建模:例题与讲解》第十四讲-模拟退火、遗传算法(含Matlab代码)

    本系列侧重于例题实战与讲解,希望能够在例题中理解相应技巧。文章开头相关基础知识只是进行简单回顾,读者可以搭配课本或其他博客了解相应章节,然后进入本文正文例题实战,效果更佳。 如果这篇文章对你有帮助,欢迎点赞与收藏~ 现代优化算法,自20世纪80年代初开

    2024年02月04日
    浏览(42)
  • 模拟退火算法与遗传算法求解多目标优化问题的算法实现(数学建模)

    模拟退火算法是一种全局优化算法,解决的问题通常是找到一个最小化(或最大化)某个函数的全局最优解。它通过模拟物理退火的过程来搜索解空间,在开始时以一定的温度随机生成初始解,然后一步步降低温度,同时在当前解的周围随机搜索新的解,并根据一定概率接受

    2024年02月02日
    浏览(35)
  • 数学建模|通过模拟退火算法求解供货与选址问题:问题二(python代码实现)

    今天继续用模拟退火算法供货与选址问题的问题二,如果还没看过问题一的可以看我之前的博客 数学建模|通过模拟退火算法求解供应与选址问题:问题一(python代码实现)-CSDN博客 这里还是把题目放上来(题目来自数学建模老哥的视频): 那么我们可以分析一下,第一问和

    2024年01月16日
    浏览(39)
  • 【数学建模】模拟退火全解析

    和局部束搜索相反,模拟退火将最优化策略改变,引入随机噪声,不一定每次都是最优,但是内部机制保证了最终的走向是最优,总的过程可以理解为初期广泛探索(Exploration),逐步过渡到深挖(Exploitation)。其中机理比较复杂,我们逐步去理解。 首先声明,我们这里还是

    2024年02月02日
    浏览(30)
  • 数学建模——模拟退火优化投影寻踪

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档   在考虑综合评价的时候,我们使用了各自主观、客观的方法去求解权重,客观权重的计算依靠着数据本身的分布来决定,有时候会出现各种各样不可抗拒的意外情况,其中在熵权法的解释在就有提到

    2024年02月11日
    浏览(32)
  • 数学建模-退火算法和遗传算法

    退火算法和遗传算法 一.退火算法 退火算法Matlab程序如下: [W]=load(\\\'D:100个目标经度纬度.txt\\\'); 二、遗传算法 [E]=xlsread(\\\'D:100个目标经度纬度\\\');  % 加载敌方 100 个目标的数据, 数据按照表格中的位置保存在纯文本文件 sj.txt 中 x=[E(:,1)]; y=[E(:,2)]; e =[x y]; d1=[70,40]; e =[d1;  e ;d1];

    2024年02月20日
    浏览(39)
  • 数学建模--退火算法求解最值的Python实现

    目录 1.算法流程简介 2.算法核心代码 3.算法效果展示

    2024年02月09日
    浏览(26)
  • 智能优化算法学习笔记(2)–模拟退火算法(SA)

    模拟退火算法( Simulated Annealing ,简称 SA )的思想最早是由 Metropolis 等提出的。其出发点是基于物理中固体物质的退火过程与一般的组合优化问题之间的相似性。模拟退火算法是一种通用的优化算法,其物理退火过程由以下三部分组成: 加温过程 。其目的是增强粒子的热运

    2024年02月05日
    浏览(34)
  • 回归预测 | MATLAB实现SA-SVM模拟退火算法优化支持向量机多输入单输出回归预测(多指标,多图)

    效果一览 基本介绍 回归预测 | MATLAB实现SA-SVM模拟退火算法优化支持向量机多输入单输出回归预测(多指标,多图),输入多个特征,输出单个变量,多输入单输出回归预测; 多指标评价,代码质量极高;excel数据,方便替换,运行环境2018及以上。 程序设计 完整源码和数据

    2024年02月12日
    浏览(30)
  • 回归预测 | MATLAB实现SA-ELM模拟退火算法优化极限学习机多输入单输出回归预测(多指标,多图)

    效果一览 基本介绍 回归预测 | MATLAB实现SA-ELM模拟退火算法优化极限学习机多输入单输出回归预测(多指标,多图),输入多个特征,输出单个变量,多输入单输出回归预测; 多指标评价,代码质量极高;excel数据,方便替换,运行环境2018及以上。 程序设计 完整源码和数据

    2024年02月11日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包