2023年第四届“华数杯”数学建模思路 - 案例:退火算法

news2024/9/24 1:20:56

## 0 赛题思路

(赛题出来以后第一时间在CSDN分享)

https://blog.csdn.net/dc_sinor?type=blog

1 退火算法原理

1.1 物理背景

在热力学上,退火(annealing)现象指物体逐渐降温的物理现象,温度愈低,物体的能量状态会低;够低后,液体开始冷凝与结晶,在结晶状态时,系统的能量状态最低。大自然在缓慢降温(亦即,退火)时,可“找到”最低能量状态:结晶。但是,如果过程过急过快,快速降温(亦称「淬炼」,quenching)时,会导致不是最低能态的非晶形。

如下图所示,首先(左图)物体处于非晶体状态。我们将固体加温至充分高(中图),再让其徐徐冷却,也就退火(右图)。加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小(此时物体以晶体形态呈现)。

在这里插入图片描述

1.2 背后的数学模型

如果你对退火的物理意义还是晕晕的,没关系我们还有更为简单的理解方式。想象一下如果我们现在有下面这样一个函数,现在想求函数的(全局)最优解。如果采用Greedy策略,那么从A点开始试探,如果函数值继续减少,那么试探过程就会继续。而当到达点B时,显然我们的探求过程就结束了(因为无论朝哪个方向努力,结果只会越来越大)。最终我们只能找打一个局部最后解B。

在这里插入图片描述

根据Metropolis准则,粒子在温度T时趋于平衡的概率为exp(-ΔE/(kT)),其中E为温度T时的内能,ΔE为其改变数,k为Boltzmann常数。Metropolis准则常表示为
在这里插入图片描述

Metropolis准则表明,在温度为T时,出现能量差为dE的降温的概率为P(dE),表示为:P(dE) = exp( dE/(kT) )。其中k是一个常数,exp表示自然指数,且dE<0。所以P和T正相关。这条公式就表示:温度越高,出现一次能量差为dE的降温的概率就越大;温度越低,则出现降温的概率就越小。又由于dE总是小于0(因为退火的过程是温度逐渐下降的过程),因此dE/kT < 0 ,所以P(dE)的函数取值范围是(0,1) 。随着温度T的降低,P(dE)会逐渐降低。

我们将一次向较差解的移动看做一次温度跳变过程,我们以概率P(dE)来接受这样的移动。也就是说,在用固体退火模拟组合优化问题,将内能E模拟为目标函数值 f,温度T演化成控制参数 t,即得到解组合优化问题的模拟退火演算法:由初始解 i 和控制参数初值 t 开始,对当前解重复“产生新解→计算目标函数差→接受或丢弃”的迭代,并逐步衰减 t 值,算法终止时的当前解即为所得近似最优解,这是基于蒙特卡罗迭代求解法的一种启发式随机搜索过程。退火过程由冷却进度表(Cooling Schedule)控制,包括控制参数的初值 t 及其衰减因子Δt 、每个 t 值时的迭代次数L和停止条件S。

2 退火算法实现

2.1 算法流程

(1) 初始化:初始温度T(充分大),初始解状态S(是算法迭代的起点), 每个T值的迭代次数L
(2) 对k=1,……,L做第(3)至第6步:
(3) 产生新解S′
(4) 计算增量Δt′=C(S′)-C(S),其中C(S)为评价函数
(5) 若Δt′<0则接受S′作为新的当前解,否则以概率exp(-Δt′/T)接受S′作为新的当前解.
(6) 如果满足终止条件则输出当前解作为最优解,结束程序。
终止条件通常取为连续若干个新解都没有被接受时终止算法。
(7) T逐渐减少,且T->0,然后转第2
在这里插入图片描述

2.2算法实现

import numpy as np
import matplotlib.pyplot as plt
import random

class SA(object):

    def __init__(self, interval, tab='min', T_max=10000, T_min=1, iterMax=1000, rate=0.95):
        self.interval = interval                                    # 给定状态空间 - 即待求解空间
        self.T_max = T_max                                          # 初始退火温度 - 温度上限
        self.T_min = T_min                                          # 截止退火温度 - 温度下限
        self.iterMax = iterMax                                      # 定温内部迭代次数
        self.rate = rate                                            # 退火降温速度
        #############################################################
        self.x_seed = random.uniform(interval[0], interval[1])      # 解空间内的种子
        self.tab = tab.strip()                                      # 求解最大值还是最小值的标签: 'min' - 最小值;'max' - 最大值
        #############################################################
        self.solve()                                                # 完成主体的求解过程
        self.display()                                              # 数据可视化展示

    def solve(self):
        temp = 'deal_' + self.tab                                   # 采用反射方法提取对应的函数
        if hasattr(self, temp):
            deal = getattr(self, temp)
        else:
            exit('>>>tab标签传参有误:"min"|"max"<<<')
        x1 = self.x_seed
        T = self.T_max
        while T >= self.T_min:
            for i in range(self.iterMax):
                f1 = self.func(x1)
                delta_x = random.random() * 2 - 1
                if x1 + delta_x >= self.interval[0] and x1 + delta_x <= self.interval[1]:   # 将随机解束缚在给定状态空间内
                    x2 = x1 + delta_x
                else:
                    x2 = x1 - delta_x
                f2 = self.func(x2)
                delta_f = f2 - f1
                x1 = deal(x1, x2, delta_f, T)
            T *= self.rate
        self.x_solu = x1                                            # 提取最终退火解

    def func(self, x):                                              # 状态产生函数 - 即待求解函数
        value = np.sin(x**2) * (x**2 - 5*x)
        return value

    def p_min(self, delta, T):                                      # 计算最小值时,容忍解的状态迁移概率
        probability = np.exp(-delta/T)
        return probability

    def p_max(self, delta, T):
        probability = np.exp(delta/T)                               # 计算最大值时,容忍解的状态迁移概率
        return probability

    def deal_min(self, x1, x2, delta, T):
        if delta < 0:                                               # 更优解
            return x2
        else:                                                       # 容忍解
            P = self.p_min(delta, T)
            if P > random.random(): return x2
            else: return x1

    def deal_max(self, x1, x2, delta, T):
        if delta > 0:                                               # 更优解
            return x2
        else:                                                       # 容忍解
            P = self.p_max(delta, T)
            if P > random.random(): return x2
            else: return x1

    def display(self):
        print('seed: {}\nsolution: {}'.format(self.x_seed, self.x_solu))
        plt.figure(figsize=(6, 4))
        x = np.linspace(self.interval[0], self.interval[1], 300)
        y = self.func(x)
        plt.plot(x, y, 'g-', label='function')
        plt.plot(self.x_seed, self.func(self.x_seed), 'bo', label='seed')
        plt.plot(self.x_solu, self.func(self.x_solu), 'r*', label='solution')
        plt.title('solution = {}'.format(self.x_solu))
        plt.xlabel('x')
        plt.ylabel('y')
        plt.legend()
        plt.savefig('SA.png', dpi=500)
        plt.show()
        plt.close()


if __name__ == '__main__':
    SA([-5, 5], 'max')

实现结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/823253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Nginx13】Nginx学习:HTTP核心模块(十)Types、AIO及其它配置

Nginx学习&#xff1a;HTTP核心模块&#xff08;十&#xff09;Types、AIO及其它配置 今天学习的内容也比较简单&#xff0c;主要的是 Types 相关的配置&#xff0c;另外还会了解一下 AIO 以及部分没有特别大的分类归属的配置指令的使用。后面的内容都是 HTTP 核心模块中比较小…

植物大战僵尸修改器制作--从入门到入土

文章目录 基础准备基址偏移表常规项目卡槽植物种植无冷却无限阳光浓雾透视基本原理HOOK除雾代码 种植植物基本原理远程线程注入dll函数远程线程卸载dll函数关键dll函数失败代码远程线程代码注入(推荐) 种植僵尸基本原理种植僵尸函数--dll注入版远程代码注入版 完整程序代码参考…

npm ERR! code EPERM npm ERR! syscall unlink npm ERR!错误解决方法

npm ERR! code EPERM npm ERR! syscall unlink npm ERR!错误解决方法 1、问题描述2、解决方法 1、问题描述 由于之前电脑系统的原因&#xff0c;电脑重置了一下&#xff0c;之前安装的环境都没了&#xff0c;然后在重新安装node.js后在使用npm安装时总是报如下错误&#xff1a…

如何在免费版 pycharm 中使用 github copilot (chatGPT)?

起因 在 vscode 中使用了 github copilot 以后&#xff0c;感觉这个人工智能还不错。 但 vscode 对于 python 项目调试并不是特别方便&#xff0c;所以想在 Pycharm 中也能使用同一个 github 账号&#xff0c;用上 copilot 的功能。 不需要等待&#xff0c;安装即用&#xff…

Android复习(Android基础-四大组件)—— Service

1. Service的概述 Service是一个可以在后台长期运行并且不需要和用户进行交互的应用组件。 主要负责&#xff1a;不需要和用户交互而且还要求长期运行的任务&#xff0c;比如耗时操作。 Service不是运行在一个独立的进程当中&#xff0c;不依赖于任何用户界面。 其依赖于创建…

无线电蓝牙音频-BES数字音频系统音频流图

+我V hezkz17进数字音频系统研究开发交流答疑群(课题组) (1)音乐播放音频流图 Decode"(解码)是指将编码后的数据转换回原始格式或可读取的形式的过程,SBC解码成PCM

Linux第三章之重定向 管道命令 环境变量PATH

一、了解Linux目录配置标准FHS FHS本质一套规定Linux目录结构&#xff0c;软件建议安装位置的标准。 使用Linux来开发产品或者发布软件的公司、个人太多&#xff0c;如果每家公司或者个人都按照自己的意愿来配置文件或者软件的存放位置&#xff0c;这无疑是一场灾难。 #进入…

WordPress--关闭主题和插件的自动更新

原文网址&#xff1a;WordPress--关闭主题和插件的自动更新_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何关闭WordPress主题和插件的自动更新提示。 方法 使用插件&#xff1a;Eay Updates Manager 安装完插件后&#xff0c;所有插件被管理&#xff0c;并自动关闭更新&…

PDM系统的协同优势

在现代制造业中&#xff0c;产品的复杂性和多样性日益增加&#xff0c;要实现高效的生产和交付&#xff0c;协同合作显得尤为重要。而PDM系统&#xff08;Product Data Management&#xff0c;产品数据管理&#xff09;作为关键工具&#xff0c;正是提升协同效率的有力支持。让…

NLP实战9:Transformer实战-单词预测

目录 一、定义模型 二、加载数据集 三、初始化实例 四、训练模型 五、评估模型 &#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学啊* 所有&#xff09; &#x1f356; 作者&#xff1a;[K同学啊] 模型结构图&#xff1a; &a…

【编程语言 · C语言 · malloc函数】

【编程语言 C语言 malloc函数】https://mp.weixin.qq.com/s?__bizMzg4NTE5MDAzOA&mid2247491503&idx1&sn856b0ee891614a00ae78e84161861e48&chksmcfade356f8da6a404f586365f1987cfc193c0465faf51d959bed9dc5e5e8ce6c112f607f18f3&payreadticketHOUhzlYV…

css图标 | 来自 fontawesome 字体文件的586 个小图标

1. css效果 /*!* Font Awesome 4.4.0 by davegandy - http://fontawesome.io - fontawesome* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)*/.fa-glass:before {content:"\f000"} .fa-music:before {content:"\f001"…

云原生势不可挡,如何跳离云原生深水区?

云原生是云计算领域一大热词&#xff0c;伴随云原生概念而来的是数字产业迎来井喷、数字变革来临、数字化得以破局以及新一波的技术红利等等。云原生即“云”原生&#xff0c;顾名思义是让“应用”最大程度地利用云的能力&#xff0c;发挥云价值的最佳路径。具体来说&#xff0…

transformers里的AutoTokenizer之返回值token_type_ids(二)

在很多案例中&#xff0c;AutoTokenizer会返回token_type_ids这个结果&#xff1a; token_type_ids的解释&#xff1a; 对于两个句子对来说&#xff0c;上一句都标识为0&#xff0c;下一句都标识为1。

ChatGPT + Stable Diffusion + 百度AI + MoviePy 实现文字生成视频,小说转视频,自媒体神器!(一)

ChatGPT Stable Diffusion 百度AI MoviePy 实现文字生成视频&#xff0c;小说转视频&#xff0c;自媒体神器&#xff01;(一) 前言 最近大模型频出&#xff0c;但是对于我们普通人来说&#xff0c;如何使用这些AI工具来辅助我们的工作呢&#xff0c;或者参与进入我们的生活…

K8s的详细介绍

1.编写yaml文件的方式 2.yaml里面的内容介绍 Pod实现机制&#xff1a;&#xff08;1&#xff09;共享网络&#xff08;2&#xff09;共享存储 共享网络:通过Pause容器&#xff0c;把其他业务容器加入到Pause容器里面&#xff0c;让所有业务容器在同一个名称空间中&#xff0c;…

Linux 基础入门篇

挂载点 先在这块新的存储上做文件系统&#xff0c;但是并不是挂载到全局目录树的根上了&#xff0c;你是想让/home 目录和它关联&#xff0c;所以你需要把它挂载到/home目录上 新的粉色的存储设备上的文件系统挂载在了/home 目录&#xff0c;全局目录树/home就和粉色文件系统的…

一起学算法(二维数组篇)

1.概念定义 1.矩阵的定义 矩阵A(nm)的定义时按照长方形排列的复数或实数集合&#xff0c;其中n代表的是行数&#xff0c;m代表的是列数。如下所示&#xff0c;代表的是一个4x3的矩阵 在Java中&#xff0c;我们可以用A[n][m]来代表一个n*m的矩阵&#xff0c;其中A[i][j]代表的是…

Java如何实现将类文件打包为jar包

目录 将类文件打包为jar包 1.写类文件2.编译3.测试4.打jar包jar包应该怎么打&#xff1f; 1.首先确保你的项目2.选中你的项目,点右键3.选择runnable jar file4.如下图,直接看图5.然后点finish 将类文件打包为jar包 为实际项目写了一个工具类&#xff0c;但是每次使用时都需要…

记录--一个好用的轮子 turn.js 实现仿真翻书的效果

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 国际惯例&#xff0c;官网链接 官网传送门 Github地址 github上有几个demos例子&#xff0c;介绍了基础用法。 我参考官网的例子&#xff0c;写了一个demo示例 安装 turn.js 依赖 jquery 库&#xff0…