数学建模赛前备赛——模拟退火算法

news2024/12/23 3:27:15

一.什么是智能优化算法

智能优化算法本质上是一个优化算法,它通过不断优化模型的参数,使得系统表现达到最优,常见的只能优化算法有很多,比如说蚁群算法,遗传算法以及我们今天的主角——模拟退火算法。

二.模拟算法的前身——爬山算法

爬山算法是一种简单的优化算法,它每次会从当前解的临近解空间中选取一个最优解来作为当前解,直到达到一个局部最优解,但是爬山算法有一个致命的缺陷,就是容易陷入局部最优解,无法跳出局部最优解,从而无法找到全局最优解。像下面这个图:
在这里插入图片描述

如果我们从C开始,按照爬山算法,我们最终会陷入局部最优解A,无法找到全局最优解B。其实也是比较好理解,如果把图像看做某个函数的图像,我们找到的只是一个极值点,而不一定是最大值点或者最小值点。

三.模拟退火算法的原理

模拟退火算法是一种基于概率的全局优化算法,它模拟了金属退火的过程,通过在解空间中随机搜索,并利用概率接受较差的解,从而避免陷入局部最优解。模拟退火算法的基本思想是:在高温下,系统中的粒子具有较高的能量,可以自由地移动和交换位置,从而在解空间中搜索到全局最优解。随着温度的降低,粒子的能量逐渐减少,搜索范围逐渐缩小,最终在低温下达到全局最优解。
相比于爬山算法,它引入了温度这一变量设计了一个高温,让粒子的初始状态保持了一个较大活性,可以尝试更多可能性,进而跳出局部最优解,最终找到全局最优解。

四. 算法的实现流程

  • 初始化:初始化温度T(充分大),每个T值的迭代次数L,降温系数alpha(0,1)和终止温度eps(充分小)
  • 随机生成初始解A,计算对应的f(A)
  • 在A附近生成新解,计算增量
  • 判断是否接受新解
  • 降温
  • 判断是否达到终止条件, 如果达到,则结束,否则回到第二步

五.算法的为伪代码实现

我们可以将模拟退火算法写作一个双重迭代算法,分为下面的两个过程:

  • 外循环(退火过程):模拟初始温度很大温度逐渐下降的过程
  • 内循环(搜索过程):模拟某一温度下粒子的跳动过程

首先是外循环:我们首先将固体达到较高的温度(设置一个较高的初始的温度)。然后我们根据降温系数alpha使温度按照一定的比例下降,当达到终止温度eps时,冷却结束,模拟退火结束

T=2000 #初始温度
eps=1e-8  #终止温度
alpha=0.99  #降温系数(越接近1结果越精确)
while T>eps:
    T*=alpha

然后是内循环:我们首先在当前温度下随机选择一个解,然后计算这个解的适应度值,然后计算新解的适应度值,如果新解的适应度值比当前解的适应度值要高,那么我们就接受新解,否则我们以一定的概率接受新解,这个概率的计算公式为exp(-ΔE/T),其中ΔE为新解的适应度值减去当前解的适应度值,T为当前温度。然后我们更新当前解为新解,继续进行内循环,直到达到终止温度eps,模拟退火结束,大致的流程如下:
在这里插入图片描述

大家有可能不是很理解为什么在左边出现更差的结果我们还会有一定的可能接受这个较差的解,而这就是模拟退火算法的核心思想,它允许算法在搜索过程中接受较差的解,从而避免陷入局部最优解,最终找到全局最优解。

六.算法的优缺点

优点:

  • 模拟退火算法是一种全局优化算法,它可以在解空间中搜索到全局最优解,而不会陷入局部最优解。
  • 不受问题约束条件的限制,可以处理各种类型的优化问题。
  • 解与初始解无关,算法的搜索过程是随机的,因此可以避免陷入局部最优解。
  • 可以灵活地调整参数,如初始温度、降温系数和终止温度等,来平衡搜素时间与搜素质量。

缺点:

  • 模拟退火算法的计算复杂度较高,对于大规模问题,计算时间较长。
  • 算法收敛速度较慢,需要较大的计算资源。
  • 需要合适的初始解与参数调整

七.算法的应用

这里我们以旅行商问题(Travelling Salesman Problem,TSP)为例,来演示模拟退火算法的应用。旅行商问题是一个经典的组合优化问题,要求找到一条最短的路径,使得旅行商能够访问所有的城市并返回到起点。旅行商问题是一个NP-hard问题,没有已知的高效算法可以解决所有实例。因此,模拟退火算法是一种有效的解决旅行商问题的方法,我们来看一下如何基于模拟退火算法解决旅行商问题,代码如下:

import random
import math
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

class SA_TSP:
    def __init__(self, n, X, Y, n_Tk, r, T_f, T0):
        self.n = n  # 城市数量
        self.X = X  # 城市坐标
        self.Y = Y  # 城市坐标
        self.n_Tk = n_Tk  # 内循环次数
        self.r = r  # 降温系数
        self.T_f = T_f  # 终止温度
        self.T0 = T0  # 初始温度
        self.alpha = r  # 温度更新系数
      
    # 计算路径长度
    def fitness(self, X0):
        s = 0
        for i in range(self.n):
            if i != self.n - 1:
                s += np.sqrt((self.X[X0[i]] - self.X[X0[i + 1]]) ** 2 + (self.Y[X0[i]] - self.Y[X0[i + 1]]) ** 2)
            else:
                s += np.sqrt((self.X[X0[i]] - self.X[X0[0]]) ** 2 + (self.Y[X0[i]] - self.Y[X0[0]]) ** 2)
        return s
    
    def exchange(self, X0, i, j):
        X1 = X0.copy()
        X1[i], X1[j] = X1[j], X1[i]
        return X1
    
    def initialX0(self, n):
        X0 = np.random.permutation(range(n))
        return X0
    
    def SA_TSP(self):
        X0 = self.initialX0(self.n)
        # 记录最优路径
        X_min = [X0]
        # 记录最优路径长度
        s_min = [self.fitness(X0)]
        k = 0
        while self.T0 > self.T_f:
            for _ in range(self.n_Tk):
                i, j = random.sample(range(self.n), 2)
                X1 = self.exchange(X0, i, j)
                s1 = self.fitness(X0)
                s2 = self.fitness(X1)
                # 更新历史最优解
                if s2 < min(s_min):
                    s_min.append(s2)
                    X_min.append(X1)
                else:
                    s_min.append(s_min[-1])
                    X_min.append(X_min[-1])

                # 判断是否更新解
                if s2 < s1:
                    X0 = X1
                else:
                    E = math.exp(-(s2 - s1) / self.T0)
                    R = random.uniform(0, 1)
                    if E > R:
                        X0 = X1

                k += 1
            
            self.T0 *= self.alpha  # 温度更新

        # 绘制优化过程
        plt.plot(range(k+1), s_min)
        plt.xlabel('迭代次数')
        plt.ylabel('最优路径长度')
        plt.show()
        
        # 绘制最优路径
        W = X_min[-1]
        for i in range(self.n):
            if i != self.n - 1:
                plt.plot([self.X[W[i]], self.X[W[i + 1]]], [self.Y[W[i]], self.Y[W[i + 1]]], c='plum')
            else:
                plt.plot([self.X[W[i]], self.X[W[0]]], [self.Y[W[i]], self.Y[W[0]]], c='plum')
        plt.scatter(self.X, self.Y, c='red')
        plt.title("路线图")
        plt.xlabel("x")
        plt.ylabel("y")
        plt.show()
        
        return X_min[-1], s_min[-1]

# 定义城市坐标
n = 30
city_x = [41, 37, 54, 25, 7, 2, 68, 71, 54, 83, 64, 18, 22, 83, 91, 25, 24, 58, 71, 74, 87,
          18, 13, 82, 62, 58, 45, 41, 44, 4]
city_y = [94, 84, 67, 62, 64, 99, 58, 44, 62, 69, 60, 54, 60, 46, 38, 38, 42, 69, 71, 78, 76,
          40, 40, 7, 32, 35, 21, 26, 35, 50]
# 内循环的迭代次数
n_Tk = 300
# 降温变化
r = 0.9
# 终止温度
T_f = 0.001
# 初始温度
T0 = 2000
# 创建对象
city30 = SA_TSP(n, city_x, city_y, n_Tk, r, T_f, T0)
# 方法
Xmin, smin = city30.SA_TSP()
print("最短路径为:", Xmin)
print("最短路径长度为:", smin)

运行结果如下:
在这里插入图片描述
在这里插入图片描述

相比于其他智能优化算法,模拟退火算法适用范围光,全局搜素能力强,不容易陷入局部最优解,这些都是我们可以在论文中去体现的东西,今天的算法介绍就到此为止了,下篇见

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

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

相关文章

【Python入门】第1节 基础语法

&#x1f4d6;第1节 基础语法 ✅字面量✅注释✅变量✅数据类型&#x1f9ca;数据类型转换 ✅标识符✅运算符✅字符串扩展&#x1f9ca;字符串的三种定义方式&#x1f9ca;字符串拼接&#x1f9ca;字符串格式化&#x1f9ca;格式化的精度控制&#x1f9ca;字符串格式化方式2&…

equals与== 区别,全面总结如何使用(Java)

先理解JVM内存模型 虚拟机栈&#xff1a;JVM 运行过程中存储当前线程运行方法所需的数据&#xff0c; 指令、 返回地址本地方法栈&#xff1a;Java程序自动调用底层C/C函数库程序计数器&#xff1a;当前线程执行的字节码的行号指示器堆&#xff1a;存放我们申请的对象&#xff…

【Python 千题 —— 基础篇】入门异常处理

Python 千题持续更新中 …… 脑图地址 👉:⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目描述 题目描述 编写一个程序,要求在处理用户输入时捕获各种异常情况,并为每种异常提供相应的处理方式。具体要求如下: 定义一个函数 divide_numbers(),它接…

php mail函数配置SMTP服务器发邮件的指南!

php mail函数安全性考虑&#xff1f;PHP mail()函数漏洞利用技巧&#xff1f; 在使用PHP进行开发时&#xff0c;发送邮件是一个常见的需求。使用php mail函数配置SMTP服务器发邮件&#xff0c;则是实现这一需求的有效途径。AokSend将详细探讨如何通过php mail函数来配置SMTP服…

Density-invariant Features for Distant Point Cloud Registration 论文解读

目录 一、导言 二、先导知识 1、FCGF 三、相关工作 1、深度学习的点云配准 2、对抗密度变化的方法 3、对比学习 四、GCL方法 1、U型曲线假设 一、导言 该论文来自于ICCV2023&#xff0c;上海交通大学提出的基于组对比学习的方案&#xff0c;来提取密度不变的几何特征&…

【终端IDPS】开源安全平台Wazuh之Wazuh Server

引言 Wazuh是一个开源的、免费的企业级安全监控解决方案&#xff0c;专注于威胁检测、完整性监控、事件响应和合规性。它由部署在受监控系统的端点安全代理和管理服务器组成&#xff0c;服务器收集并分析代理收集的数据。Wazuh支持多平台&#xff0c;包括Windows、Linux、macOS…

Linux学习笔记4 重点!网络排障命令

网络排障命令 命令行下载工具wget wget https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.20.17.tar.gz wget https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.20.17.tar.gz 限速下载 wget --limit-rate1M https://mirrors.edge.kernel.or…

【已解决】Vue Duplicate keys detected: ‘[object Object]’

【已解决】Vue Duplicate keys detected: ‘[object Object]’ 在Vue项目开发过程中&#xff0c;我们可能会遇到这样的报错&#xff1a;“Duplicate keys detected: ‘[object Object]’. This may cause an update error.”。这个错误通常发生在Vue的虚拟DOM进行渲染更新时&a…

上书房信息咨询:医疗满意度调研

随着人们生活水平的不断提高&#xff0c;医疗服务的需求日益增长。近期&#xff0c;上书房信息咨询受托完成了某市医疗市场的满意度调研&#xff0c;旨在深入了解市民对医疗服务的评价和需求&#xff0c;为提升医疗服务质量提供有力支持。 近年来&#xff0c;某市致力于推进医…

鸿蒙ArkTS语言学习(五):扩展(函数)@Extend@Styles@Builder

如何实现结构、样式复用呢&#xff1f; Extend&#xff1a;扩展组件&#xff08;样式、事件&#xff09; 作用&#xff1a;将相同组件复用的属性结构抽取封装&#xff0c;将不同的结构通过传入参数进行修改。 1. 定义语法 Extend(组件名) function 函数名{ ... } 2. 调用 组件…

一起学习LeetCode热题100道(60/100)

60.单词搜索(学习) 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那…

selenium消除启动特征避免被反爬-使用已经打开的浏览器

selenium消除启动特征避免被反爬 启动特征很多&#xff0c;如何消除selenium启动特征呢&#xff1f;这个也是因站而异&#xff0c;如果规避常规的检测&#xff0c;做到以下2点就可以。 1 是消除window.navigator.webdriver的值&#xff1b; 2 是修改chromedriver.exe的源码…

鸿蒙开发 数组改变,ui渲染没有刷新

问题描述&#xff1a; 数组push, 数组长度改变&#xff0c;ui也没有刷新 打印出了数组 console.log(this.toDoData.map(item > ${item.name}).join(, ), this.toDoData.length) 原代码&#xff1a; Text().fontSize(36).margin({ right: 40 }).onClick(() > {TextPicker…

在SpringBoot项目中使用多线程(配合线程池)加快从MySQL导入数据到ElasticSearch的速度

文章目录 1. 准备工作1.1 索引库1.2 建表1.3 实体类1.3.1 item.java1.3.2 itemDocument.java 1.4 编写配置文件1.5 编写 Mapper 类和 Service 类 2. 没有使用多线程的情况2.1 编码2.2 测试结果 3. 使用多线程&#xff08;配合线程池&#xff09;的情况3.1 自定义类&#xff0c;…

EM-7肽;EM-7-NH2;CAS:289632-61-7

【EM-7 简介】 EM-7&#xff0c;也被称为EM-7-NH2&#xff0c;其化学名称为[D-Glu5,D-Trp7,9,10]-Substance P (5-11)&#xff0c;分子式为C57H66N12O10S&#xff0c;分子量为1111.273。 【中文名称】(D-谷氨酰 5,D-色氨酰 7,9,10)-物质 P (5-11) 【英文名称】(D-Glu5,D-Trp7…

openlayers+vite+vue3实现规划某一特定行政区(二)

在前一期实现离线地图初始化的基础上&#xff0c;本文中主要阐述如何实现规划某一特定行政区&#xff0c;并展示其行政区的区县名称。 提示&#xff1a;因前文中阐述了如何实现离线地图的初始化&#xff0c;所以在此不再进行书写并详解初始化的过程和流程&#xff0c;如有不明…

Task-Embedded Control Networks for Few-Shot Imitation Learning

发表时间&#xff1a;CoRL 2018 论文链接&#xff1a;https://readpaper.com/pdf-annotate/note?pdfId4500197057754718210&noteId2424798567891365120 作者单位&#xff1a;Imperial College London Motivation&#xff1a;就像人类一样&#xff0c;机器人应该能够利用来…

力扣经典题目之->另一颗树的子树(subRoot是否是root的子树)

一&#xff1a;题目 本题需要用到力扣经典题目之-&#xff1e;相同的树&#xff08;递归判断两颗二叉树是否相同&#xff09;-CSDN博客 中的isSameTree&#xff0c;直接cv即可。 二&#xff1a;代码 三&#xff1a;解释 第一个函数&#xff1a; 力扣经典题目之-&#xff1e;相…

模型 分形理论

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。自相似&#xff0c;无限细节。 1 分形理论的应用 1.1 字节跳动的分形创新增长引擎 字节跳动作为一家全球领先的科技公司&#xff0c;其快速的发展和创新能力在业界引起了广泛关注。公司通过分形创新…

大数据-105 Spark GraphX 基本概述 与 架构基础 概念详解 核心数据结构

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…