模拟退火算法 Simulated Annealing

news2025/2/27 16:30:14

模拟退火算法 Simulated Annealing

1. 介绍

模拟退火算法(Simulated Annealing, SA)是一种启发式的优化算法。它适用于在大型离散或连续复杂问题中寻找全局最优解,例如组合优化,约束优化,图问题等。模拟退火是一种随机(概率性)搜索算法,基于物理中固体晶体退火过程的模拟。退火过程中,晶体内部由高能状态向低能状态演化,最终在足够低的温度时稳定在能量最低的状态。

模拟退火算法的主要思想是在搜索过程中接受比当前解差的解,以跳出局部最优。具体来说,模拟退火算法过程如下:

  1. 初始化设置:设置初始解、初始温度、温度衰减系数,最低温度等参数。

  2. 在当前温度下,随机选取一个邻近解并计算其能量变化量。

  3. 如果能量降低(对于最小化问题),则接受该解作为当前解;如果能量增加,则以一定的概率(通常依赖于温度和能量变化量)接受该解。

  4. 更新温度(通常为当前温度乘以衰减系数)。

  5. 重复步骤2-4,直到温度降至最低温度并稳定。

  6. 输出最佳解。

模拟退火算法的关键在于选择合适的初始温度、衰减系数和结束条件,以及针对问题的邻近解生成策略和概率接受函数。

2. 经典应用

接下来,我们将以三个经典问题为例,展示如何使用模拟退火算法求解。

2.1 旅行商问题(TSP)

旅行商问题即求解在给定城市、距离的情况下,找到一条道路,使得从起点出发,经过所有城市后回到起点,且总距离最短。

import random
import math
import numpy as np

# 计算路径长度
def calculate_distance(path, distance_matrix):
    distance = 0
    for i in range(len(path)-1):
        distance += distance_matrix[path[i]][path[i+1]]
    distance += distance_matrix[path[-1]][path[0]]
    return distance

# 邻近解生成策略:交换两个城市的位置
def generate_neighbor(path):
    new_path = path.copy()
    i, j = random.sample(range(len(path)), 2)
    new_path[i], new_path[j] = new_path[j], new_path[i]
    return new_path

# 模拟退火算法求解TSP问题
def simulated_annealing_tsp(distance_matrix, initial_temperature, min_temperature, cooling_factor, max_iteration):
    n = len(distance_matrix)
    current_path = list(range(n))
    random.shuffle(current_path)
    current_distance = calculate_distance(current_path, distance_matrix)

    temperature = initial_temperature
    best_path = current_path[:]
    best_distance = current_distance

    for it in range(max_iteration):
        if temperature < min_temperature:
            break

        new_path = generate_neighbor(current_path)
        new_distance = calculate_distance(new_path, distance_matrix)

        delta_distance = new_distance - current_distance
        if delta_distance < 0:
            current_path = new_path
            current_distance = new_distance

            if new_distance < best_distance:
                best_path = new_path[:]
                best_distance = new_distance
        else:
            prob = math.exp(-delta_distance / temperature)
            if random.random() < prob:
                current_path = new_path
                current_distance = new_distance

        temperature *= cooling_factor

    return best_path, best_distance

# 用随机距离矩阵测试
n = 10
distance_matrix = np.random.randint(1, 100, size=(n, n))
initial_temperature = 1000
min_temperature = 1e-6
cooling_factor = 0.99
max_iteration = 10000

best_path, best_distance = simulated_annealing_tsp(distance_matrix, initial_temperature, min_temperature, cooling_factor, max_iteration)
print('Best path:', best_path)
print('Best distance:', best_distance)
2.2 函数寻优

给定一个连续空间的实数函数f(x),求解其在给定区间上的最小值。

import random
import math

# 定义函数
def f(x):
    return x * x - 4 * x + 4

def generate_neighbor(x, step):
    return x + random.uniform(-step, step)

def simulated_annealing_function_optimization(f, initial_temperature, min_temperature, cooling_factor, max_iteration, search_interval, neighbor_step):
    current_x = random.uniform(search_interval[0], search_interval[1])
    current_y = f(current_x)

    temperature = initial_temperature

    best_x = current_x
    best_y = current_y

    for it in range(max_iteration):
        if temperature < min_temperature:
            break

        new_x = generate_neighbor(current_x, neighbor_step)
        if new_x < search_interval[0] or new_x > search_interval[1]:
            continue

        new_y = f(new_x)
        delta_y = new_y - current_y

        if delta_y < 0:
            current_x = new_x
            current_y = new_y

            if new_y < best_y:
                best_x = new_x
                best_y = new_y
        else:
            prob = math.exp(-delta_y / temperature)
            if random.random() < prob:
                current_x = new_x
                current_y = new_y

        temperature *= cooling_factor

    return best_x, best_y

initial_temperature = 1000
min_temperature = 1e-6
cooling_factor = 0.99
max_iteration = 10000
search_interval = [0, 5]
neighbor_step = 0.1

best_x, best_y = simulated_annealing_function_optimization(f, initial_temperature, min_temperature, cooling_factor, max_iteration, search_interval, neighbor_step)
print('Best x:', best_x)
print('Best y:', best_y)
2.3 定点覆盖问题

给定一个二维平面,有若干个点和一定数量的覆盖盒。要求通过移动覆盖盒的位置使得尽可能多的点被覆盖。覆盖盒的形状为边长为1的正方形。

import random
import math

def point_covered(points, box):
    # 判断点是否在覆盖盒内
    return sum([1 for p in points if box[0] <= p[0] <= box[0]+1 and box[1] <= p[1] <= box[1]+1])

def generate_neighbor(box, step):
    # 随机生成一个相邻覆盖盒
    return (box[0] + random.uniform(-step, step), box[1] + random.uniform(-step, step))

def simulated_annealing_point_cover(points, n_boxes, initial_temperature, min_temperature, cooling_factor, max_iteration, neighbor_step):
    boxes = [(random.uniform(0, 5), random.uniform(0, 5)) for _ in range(n_boxes)]
    
    temperature = initial_temperature

    # 当前解:覆盖的点数量和覆盖盒集合
    current_cover = sum([point_covered(points, box) for box in boxes])
    current_boxes = boxes

    # 迭代过程
    for it in range(max_iteration):
        if temperature < min_temperature:
            break

        # 随机选择一个覆盖盒生成相邻解
        idx = random.randrange(len(boxes))
        new_box = generate_neighbor(boxes[idx], neighbor_step)
        new_boxes = boxes[:]
        new_boxes[idx] = new_box

        new_cover = sum([point_covered(points, box) for box in new_boxes])
        delta_cover = new_cover - current_cover

        if delta_cover > 0:
            current_boxes = new_boxes
            current_cover = new_cover
        else:
            prob = math.exp(delta_cover / temperature)
            if random.random() < prob:
                current_boxes = new_boxes
                current_cover = new_cover

        temperature *= cooling_factor

    return current_boxes

# 生成点集
points = [(random.uniform(0, 5), random.uniform(0, 5)) for _ in range(50)]
n_boxes = 5

initial_temperature = 1000
min_temperature = 1e-6
cooling_factor = 0.99
max_iteration = 10000
neighbor_step = 0.1

result = simulated_annealing_point_cover(points, n_boxes, initial_temperature, min_temperature, cooling_factor, max_iteration, neighbor_step)
print(result)

以上三个案例展示了如何使用模拟退火算法求解旅行商问题、函数寻优以及定点问题。请注意,模拟退火算法在每个问题中的效果取决于选择的初始参数和邻近解生成策略。

如果你想更深入地了解人工智能的其他方面,比如机器学习、深度学习、自然语言处理等等,也可以点击这个链接,我按照如下图所示的学习路线为大家整理了100多G的学习资源,基本涵盖了人工智能学习的所有内容,包括了目前人工智能领域最新顶会论文合集和丰富详细的项目实战资料,可以帮助你入门和进阶。

链接: 人工智能交流群(大量资料)

在这里插入图片描述

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

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

相关文章

Java多线程技术二:线程间通信——wait/notify机制

1 概述 线程时操作系统中独立的个体&#xff0c;但这些个体如果不经过特殊的处理是不能成为一个整体的。线程间的通信就是使线程成为整体的比用方案之一&#xff0c;可以说&#xff0c;是线程间进行通信后系统之间的交互性会更强大&#xff0c;CPU利用率会得以大幅提高&#xf…

前端开发环境与真实环境的接口联通的那些最佳实践

1. 背景 前端开发的产物通常是 app.js 、app.css &#xff0c;然后将这些资源放在真实环境域名下进行工作的。 但前端的开发环境通常是本地的 http://localhost:xxx&#xff0c;业务域名可能是 https://xxx.abc.com&#xff0c;两者不在一个域名下在调用接口或者调试时会非常不…

架构图是什么,怎么做?

架构图是一种用来描述系统或软件的结构和组成的图形表示。它展示了系统中各个组件之间的关系、交互和功能。通过绘制架构图&#xff0c;可以更好地理解和沟通系统的设计和实现。 绘制架构图的软件 目前市场上有许多用于绘制架构图的软件工具&#xff0c;下面简单…

【STM32】STM32学习笔记-课程简介(1)

00. 目录 文章目录 00. 目录01. 课程简介02. 硬件设备03. 软件工具04. 硬件套件4.1 面包板和跳线/飞线4.2 杜邦线和STM32最小系统板4.3 STLINK和OLED显示屏4.4 LED和按键4.5 电位器和蜂鸣器4.6 传感器和旋转编码器4.7 USB转串口和MPU60504.8 Flash闪存和电机模块4.9 SG90舵机 0…

【全栈开发】使用NestJS、Angular和Prisma 打造全栈Typescript开发

在开发Angular应用程序时&#xff0c;我非常喜欢Typescript。使用NestJS&#xff0c;您可以以与Angular非常相似的方式编写后端。 我偶然发现了这个库&#xff0c;发现它非常有趣&#xff0c;所以我想设置一个简单的测试项目。一般来说&#xff0c;我主要使用SQL数据库&#x…

FreeRTOS入门--任务

目录 一、什么是任务 二、创建任务---xTaskCreate函数 三、任务的删除 四、任务优先级 1.阻塞状态(Blocked) 2.暂停状态(Suspended) 3.就绪状态(Ready) 五、Delay 六、调度算法 一、什么是任务 在FreeRTOS中&#xff0c;任务就是一个函数&#xff0c;原型如下&#xff…

算法通关村第四关—栈的经典算法问题(白银)

emsp;emsp;栈的经典算法问题 一、括号匹配问题 emsp;首先看题目要求&#xff0c;LeetCode20.给定一个只包括’(‘&#xff0c;)’&#xff0c;‘{&#xff0c;’&#xff0c;[&#xff0c;]的字符串s&#xff0c;,判断字符串是否有效。有效字符串需满足&#xff1a; 1.左括号…

fl studio21.2最新汉化中文完整版网盘下载

fl studio 21中文版是Image-Line公司继20版本之后更新的水果音乐制作软件&#xff0c;很多用户不太理解&#xff0c;为什么新版本不叫fl studio 21或fl studio2024&#xff0c;非得直接跳到21.2版本&#xff0c;其实该版本是为了纪念该公司22周年&#xff0c;所以该版本也是推出…

【嵌入式-51单片机】常见位运算和数据类型以及sbit使用

51单片机中 数据类型如下&#xff1a; 位运算符如下&#xff1a; 按位左移<<&#xff1a;低位补零&#xff0c;高位移出 按位右移>>&#xff1a;高位补零&#xff0c;低位移出 按位与&&#xff1a;对应位上的值必须同时为1才为1&#xff0c;可以用来对指定位…

交换综合实验

目录 一、实验拓扑 二、实验要求 三、实验步骤 1、链路聚合&#xff08;配置Eth-trunk&#xff09; 2、配置vlan&#xff08;创建划分vlan&#xff0c;配置trunk干道&#xff09; 3、MSTP配置 4、VRRP配置 5、DHCP配置 6、vlan互通 7、NAT配置&#xff08;做ACL&#…

解决Linux的端口占用报错问题

文章目录 1 Linux报错2 解决方式 1 Linux报错 Port 6006 is in use. If a gradio.Blocks is running on the port, you can close() it or gradio.close_all(). 想起之前运行Gradio 6006&#xff0c;端口被占用 2 解决方式 输入 netstat -tpl查看当前一些端口号的占用号&a…

Nginx实战教程二

一.介绍 本文介绍SPRINGBOOTVUE项目配置API服务器的两种情况 NGINX 配置VUE项目 二.vue项目和后端api接口不在同一台服务器 如果打包好的vue项目应用(dist) 和后端 api 接口没有运行在同一个主机上 此时需要在开发环境下将 API 请求代理到 API 所在服务器。通过配置 vue.confi…

【开源存储】glusterfs分布式文件系统部署实践

文章目录 一、前言1、介绍说明2、术语说明3、冗余模式3.1、复制卷&#xff08;Replication&#xff09;3.2、纠删卷&#xff08;Erasure Code&#xff09; 二、部署说明1、软件安装2、集群部署2.1、前置准备2.2、部署过程a、添加节点b、配置存储c、创建glusterfs卷d、客户端挂载…

浅谈安科瑞AISD300系列智能三相安全配电装置的设计与应用-安科瑞 蒋静

1 概述 AISD300系列三相智能安全配电装置是安科瑞专为低压配电侧开发的一款智能安全配电产品&#xff0c;本产品主要针对低压配电系统人身触电、线路老化、短路、漏电等原因引起电气安全问题而设计。 产品主要应用于学校、加油站、医院、银行、疗养院、康复中心、敬老院、酒店…

关于微信公众号授权的几件事

背景 项目需要使用微信公众号发消息&#xff0c;然后就来接入这个微信授权啦&#xff0c;微信公众号发消息前提是还需要用户先关注公众号~ 微信授权是有点恶心的&#xff0c;真的真的需要先配置好环境&#xff0c;开发的话目前是可以使用测试号申请公众号使用测试号的appid~ …

N-135基于springboot,vue高校图书馆管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vueelementUI 服务端技术&#xff1a;springbootmybatisredis 本项…

微机原理——定时器学习2应用与设计

目录 简要说明 用户扩展的定时计数器应用举例 1 8254作测量脉冲宽度 2 8254作定时 3 8254作分频 4 8254同时用作计数与定时 硬件设计 ​编辑软件设计 微机系统中定时计数器应用举例 5 计时器设计 硬件设计 软件设计 6 发生器设计 硬件设计 软件设计 简要说明 定…

鸿蒙工具DevEco Studio调试Build task failed. Open the Run window to view details.

DevEco Studio 预览代码时候出现的问题 1.进入设置 2.打开设置&#xff0c;构建&#xff0c;执行&#xff0c;部署下面的Hvigor&#xff0c; 把构建守护进程关掉就行。 然后重启启动一下就好了

五子棋AI算法自动测试方法

先前发了几篇五子棋游戏程序设计的博文&#xff0c;设计了游戏程序&#xff0c;也设计了AI智能奕棋的算法&#xff0c;运行程序检测算法的可行性&#xff0c;完成人机模式游戏功能的设置。 本文主要介绍自动测试算法的方法。 AI智能奕棋的算法testAIq( )&#xff0c;主要是检测…

【Android】Android Framework系列--Launcher3桌面图标加载流程

Launcher3桌面加载流程 Android Launcher3(简称Launcher&#xff09;启动后会加载桌面。基于Android12代码&#xff0c;分析一下桌面加载的流程。 一些相关的概念&#xff1a; WorkSpace&#xff1a;桌面。在桌面上可以添加快捷方式、Hoseat或Dock&#xff08;就是手机或者车…