运筹学之模拟退火

news2025/4/20 17:47:32

目录

  • 一、历史
  • 二、精髓思想
  • 三、案例与代码实现

一、历史

  • 问:谁在什么时候提出模拟退火?
  • 答:模拟退火算法(Simulated Annealing,SA)是由斯图尔特·柯尔斯基(Scott Kirkpatrick) 等人在 1983年 提出的。
  • 论文:“Optimization by Simulated Annealing”, published in Science, Vol. 220
  • 动机:解决组合优化问题
    在这里插入图片描述

二、精髓思想

  • 精髓就两字:退火!
  • 解释:字面意思就是模拟打铁的退火过程,刚开始打铁吧温度比较高,铁烧的红红的容易打出各种形状,随着时间变长,温度逐渐冷却下来,铁更硬了,形状大方向基本确定。

不禁感叹,以前的物理学家、数学家灵感来源都是自然现象!
在这里插入图片描述
总结下来其实就3个step:

  1. 拿一块铁过来淬火
  2. 打一次看看如何
  3. 给我打到定型

三、案例与代码实现

  • 题干:
    6艘船靠3个港口,已知达到时间arrival和卸货时长handling,求最优停靠方案,即等待时长最短。

  • 数据:

ships = {
    'S1': {'arrival': 0.1, 'handling': 4},
    'S2': {'arrival': 2.1, 'handling': 3},
    'S3': {'arrival': 4.2, 'handling': 2},
    'S4': {'arrival': 6.3, 'handling': 3},
    'S5': {'arrival': 5.5, 'handling': 2},
    'S6': {'arrival': 3.9, 'handling': 4},
    'S7': {'arrival': 3.7, 'handling': 4},
    'S8': {'arrival': 3.4, 'handling': 4},
}
  • 实现:
    step1:拿一块铁过来淬火
# 随机初始化一块铁(船舶调度顺序)
initial_order = list(ships.keys()) # 船舶原始顺序['S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7', 'S8']
random.shuffle(initial_order)	#	打乱顺序 ,可能是['S2', 'S7', 'S6', 'S5', 'S1', 'S3', 'S4', 'S8']
  • step2:打一次看看如何

首先,先评价一下原始模样如何?用等待时间作为衡量,如下:

current_cost = evaluate(current)
NUM_BERTHS = 3  # 泊位数量
# 评价函数:计算某个调度顺序的总等待时间
def evaluate(order):
    berth_times = [0] * NUM_BERTHS
    total_wait = 0
    for ship_id in order:
        arrival = ships[ship_id]['arrival']
        handling = ships[ship_id]['handling']
        # 找到最早可用泊位
        berth_index = min(range(NUM_BERTHS), key=lambda i: max(arrival, berth_times[i]))
        # start_time = 开始卸货时间 = max(到达时间, 泊位可用时间)。
        # 解释:要卸货的话,船先到达了没有泊位可用也得等,反之,有空泊位了船还没到也得等。
        start_time = max(arrival, berth_times[berth_index])
        wait_time = start_time - arrival
        total_wait += wait_time
        berth_times[berth_index] = start_time + handling
    return total_wait

然后,开始下锤子了(称之为扰动)

# 生成邻域解(随机交换两艘船顺序)
def neighbor(order):
    new_order = order.copy()
    i, j = random.sample(range(len(order)), 2)
    new_order[i], new_order[j] = new_order[j], new_order[i]
    return new_order

紧接着,评估下现在模样和上一次区别,如下:

new = neighbor(current)
new_cost = evaluate(new)
delta = new_cost - current_cost	# 扰动之后的区别

最后,做决定是接着现在模样往下继续打,还是恢复回原来模样

# 情况1:delta < 0 说明等待时间变短了呀,打铁打得更好了,欣然接受。
# 情况2:delta >= 0 说明等待时间变长了,糟糕打偏了,不过没关系,这是艺术啊!不完美也是一种美!看心情决定~
# 于是有了 random.random() < math.exp(-delta / T)这一项
# 解释:random.random()就是一个随机值(类比于当时心情),值域范围[0.0, 1.0)
# math.exp(-delta / T)和delta、T有关系,这么来看吧,假设现在超级无敌高温,那么-delta / T趋于0,那么math.exp(-delta / T)趋于1,说明有很大概率接受比较差的解。假设现在温度快降到0了,那么-delta / T趋于负无穷,那么math.exp(-delta / T)趋于0,说明有极小概率接受比较差的解。
if delta < 0 or random.random() < math.exp(-delta / T):
	current = new
    current_cost = new_cost
  • step3:给我打到定型

循环的过程,就是往复step2的过程,持续下去直到定型,如下:

# 模拟退火主过程
# 初始顺序:initial_order, 温度:T=100.0, 冷却率:cooling_rate=0.95, 最低温度:T_min=1e-3
def simulated_annealing(initial_order, T=100.0, cooling_rate=0.95, T_min=1e-3):
    current = initial_order
    current_cost = evaluate(current)
    best = current
    best_cost = current_cost

    while T > T_min:
        for _ in range(100):  # 每个温度尝试多次扰动
            new = neighbor(current)
            new_cost = evaluate(new)
            delta = new_cost - current_cost
            if delta < 0 or random.random() < math.exp(-delta / T):
                current = new
                current_cost = new_cost
                if current_cost < best_cost:
                    best = current
                    best_cost = current_cost
        T *= cooling_rate  # 降温
    return best, best_cost

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

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

相关文章

树莓派5-开发应用笔记

0.树莓派系统目录 /home&#xff1a;用户目录。 除了root用户外&#xff0c;其他所有的使用者的数据都存放在这个目录下&#xff0c;在树莓派的系统中&#xff0c;/home目录中有一个pi的子目录,这个就是pi用户的默认目录。 /bin&#xff1a; 主要放置系统的必备执行文件目录。 …

8.5/Q1,Charls最新文章解读

文章题目&#xff1a;Atherogenic index of plasma, high sensitivity C-reactive protein and incident diabetes among middle-aged and elderly adults in China: a national cohort study DOI&#xff1a;10.1186/s12933-025-02653-4 中文标题&#xff1a;中国中老年人群血…

k8s 调整Node节点 Max_Pods

默认情况下&#xff0c;Kubernetes集群中一个Node最多能起110个Pod。 这是基于性能和资源管理的考虑&#xff0c;以确保Kubernetes集群的稳定性和可靠性。 查看kht125节点上支持的最大pod数量: kubectl describe node kht125 | grep -i “Capacity|Allocatable” -A 6 调整…

使用Service发布前后端应用程序

使用Service发布前后端应用程序 文章目录 使用Service发布前后端应用程序[toc]一、创建并发布后端应用程序二、创建并发布前端应用程序三、通过前端发送流量进行测试 部署前端&#xff08;Frontend&#xff09;微服务和后端&#xff08;Backend&#xff09;微服务是比较常见的应…

Ubuntu20.04下Docker方案实现多平台SDK编译

0 前言 熟悉嵌入式平台Linux SDK编译流程的小伙伴都知道,假如平台a要求必须在Ubuntu18.04下编译,平台b要求要Ubuntu22.04的环境,那我只有Ubuntu20.04,或者说我的电脑硬件配置最高只能支持Ubuntu20.04怎么办?强行在Ubuntu20.04下编译,编又编不过,换到旧版本我又不愿意,…

-SSRF 服务端请求Gopher 伪协议无回显利用黑白盒挖掘业务功能点

1 、 SSRF 漏洞原理 SSRF(Server-Side Request Forgery: 服务器端请求伪造 ) 一种由攻击者构造形成由服务端发起请求的一个安全漏洞 ; 一般情况下&#xff0c; SSRF 攻击的目标是从外网无法访问的内部系统。 &#xff08;正是因为它是由服务端发起的&#xff0c;所以它能…

《AI大模型应知应会100篇》第27篇:模型温度参数调节:控制创造性与确定性

第27篇&#xff1a;模型温度参数调节&#xff1a;控制创造性与确定性 摘要 在大语言模型的使用中&#xff0c;“温度”&#xff08;Temperature&#xff09;是一个关键参数&#xff0c;它决定了模型输出的创造性和确定性之间的平衡。通过调整温度参数&#xff0c;您可以根据任…

聊聊Doris的数据模型,如何用结构化设计解决实时分析难题

传统 OLAP 系统的局限 在大数据实时分析领域&#xff0c;数据模型设计直接决定了系统的查询性能、存储效率与业务适配性。Apache Doris作为新一代MPP分析型数据库&#xff0c;通过独创的多模型融合架构&#xff0c;在业内率先实现了"一份数据支持多种分析范式"的能力…

LNA设计

设计目的 为后级提供足够的增益以克服后级电路噪声 尽可能小的噪声和信号失真 确保输入和输出端的阻抗匹配 确保信号线性度 评价标准 噪声系数 功率增益 工作频率和带宽 输入信号功率动态范围 端口电压驻波比 稳定性 基于SP模型的LNA设计 直流分析 S参数分析 设计指标 &#xf…

JavaSpring 中使用 Redis

创建项目 配置 Redis 服务地址 创建 Controller 类 由于当前只是些简单的测试代码&#xff0c;所以就不进行分层了&#xff0c;只创建一个 Controller 来实现 jedis 通过 jedis 对象里的各种方法来操作 Redis 此处通过 StringRedisTemplate 来操作 Redis 最原始提供的类是 Re…

多线程使用——线程安全、线程同步

一、线程安全 &#xff08;一&#xff09;什么是线程安全问题 多个线程&#xff0c;同时操作同一个共享资源的时候&#xff0c;可能会出现业务安全的问题。 &#xff08;二&#xff09;用程序摹拟线程安全问题 二、线程同步 &#xff08;一&#xff09;同步思想概述 解决线…

Spring Boot 集成 tess4j 实现图片识别文本

tesseract是一个开源的光学字符识别&#xff08;OCR&#xff09;引擎&#xff0c;它可以将图像中的文字转换为计算机可读的文本。支持多种语言和书面语言&#xff0c;并且可以在命令行中执行。它是一个流行的开源OCR工具&#xff0c;可以在许多不同的操作系统上运行。 Tess4J是…

Redis命令——list

列表类型是用来存储多个有序的字符串&#xff0c;列表中的每个字符串称为元素&#xff08;element&#xff09;&#xff0c;⼀个列表最多可以存储个元素 在 Redis 中&#xff0c;可以对列表两端插入&#xff08;push&#xff09;和弹出&#xff08;pop&#xff09;&#xff0c;…

MicroDEM 与 OpenEV(FWTtools工具包):两款开源DEM相关小软件

大家好&#xff0c;今天为大家介绍的软件是MicroDEM 与 OpenEV&#xff0c;这两款小软件分别主要用于DEM数据的处理、数据查看与分析。MICRODEM是一款专注于地理空间分析和遥感数据处理的开源小软件。 MICRODEM官网网址为&#xff1a;https://microdem.org/&#xff0c;官网比较…

STM32使用rand()生成随机数并显示波形

一、随机数生成 1、加入头文件&#xff1a;#include "stdlib.h" 2、定义一个用作生成随机数种子的变量并加入到滴答定时器中不断自增&#xff1a;uint32_t run_times 0; 3、设置种子&#xff1a;srand(run_times);//每次生成随机数前调用一次为佳 4、生成一个随…

大语言模型智能体:安全挑战与应对之道

在当今科技飞速发展的时代&#xff0c;大语言模型驱动的智能体正逐渐融入我们生活和工作的方方面面&#xff0c;给我们带来了诸多便利。但与此同时&#xff0c;它们的安全问题也引起了广泛的关注。今天&#xff0c;咱们就一起来深入了解一下可信大语言模型智能体所面临的安全挑…

每日OJ_牛客_kotori和素因子_DFS_C++_Java

目录 牛客_kotori和素因子_DFS 题目解析 C代码 Java代码 牛客_kotori和素因子_DFS kotori和素因子 描述&#xff1a; kotori拿到了一些正整数。她决定从每个正整数取出一个素因子。但是&#xff0c;kotori有强迫症&#xff0c;她不允许两个不同的正整数取出相同的素因子…

快手OneRec 重构推荐系统:从检索排序到生成统一的跃迁

文章目录 1. 背景2. 方法2.1 OneRec框架2.2 Preliminary2.3 生成会话列表2.4 利用奖励模型进行迭代偏好对齐2.4.1 训练奖励模型2.4.2 迭代偏好对齐 3. 总结 昨天面试的时候聊到了OneRec&#xff0c;但是由于上次看这篇文章已经是一个月之前&#xff0c;忘得差不多了&#xff0c…

软件测试的页面交互标准:怎样有效提高易用性

当用户遇到"反人类"设计时 "这个按钮怎么点不了&#xff1f;"、"错误提示完全看不懂"、"我输入的内容去哪了&#xff1f;"——这些用户抱怨背后&#xff0c;都指向同一个问题&#xff1a;页面交互的易用性缺陷。作为软件测试工程师&a…

共享单车出行规律与决定因素的空间交互分析——以北京六大区为例

共享单车出行规律与决定因素的空间交互分析——以北京六大区为例 原文&#xff1a;Spatial Interaction Analysis of Shared Bicycles Mobility Regularity and Determinants: A Case Study of Six Main Districts, Beijing 这篇文章主要研究了北京六个主要城区共享单车的流动…