堆优化模拟退火(List-Based Simulated Annealing|List-Based SA|LBSA|模拟退火) 算法
图炸了的话请多刷新几次(upd:8.9)
堆优化模拟退火(List-Based Simulated Annealing) 算法
引入
堆优化模拟退火(List-Based Simulated Annealing,简称 LBSA) 是一种对 模拟退火 的优化算法。由 Shi-hua Zhan,[1],[2] Juan Lin,[1:1] Ze-jun Zhang,[1:2] Yi-wen Zhong[1:3],[2:1] 提出。(以下我们以求最小值为例)
解释
我们定义当前温度为 \(t\) ,已知状态为 \(x\) ,新状态为 \(y\), 能量(值)的计算函数为 \(f\)。根据 模拟退火 可以得到发生状态转移(修改最优解)的概率 \(p\) 为(公式1):
1 & \text{if}\ f(y)\le f(x) \\
\exp({\frac{-(f(y)-f(x))}{t}}) & \text{otherwise}
\end{cases}
\]
相反,如果我们知道发生状态转移的概率 \(p\), 那么我们就可以计算出相应的温度 \(t\)。
证明过程
- 首先,将等式两边取对数,得到 \(\ln(p)=\frac{-(f(y)-f(x))}{t}\)。 
- 然后,将等式两边相乘得到 \(t\ln(p)=-(f(y)-f(x))\)。 
- 最后,将等式两边除以 \(\ln(p)\) 得到 \(t=\frac{-(f(y)-f(x))}{\ln(p)}\)。 
可以得到相应的温度 \(t\) 为(公式2):
\]
生成初始温度堆
顾名思义,堆优化,那肯定有堆!其实我们是要生成一个初始的温度堆,里面存储了大量的温度。温度堆怎么生成呢?下图表对此进行了解释:
a(温度堆生成开始) --> b[定义初始状态 $x$<br/>创建空的温度堆 $L$<br/>定义温度堆长度 $L$<sub>$max$</sub><br/>定义初始发生状态转移的概率 $p$<br/>$i=0$] --> c[创建新状态 $y$] --> d{"$f(y)<f(x)$ (解更优)"} --NO--> f["计算温度 $t=(-(f(y)-f(x)))/\ln(p)$(公式2)    <br/>将温度 $t$ 插入温度堆 $L$ 中<br/>$i++$"] --> g{"$i < L$<sub>$max$</sub>"} --Yes-->c
d --Yes--> e["$x=y$(更新状态)"] --> f
g --NO--> h[结束]
(做图表真的累)
我们一般定义 \(p=0.1\)。
这个温度堆为大根堆,即温度越高,优先级越高。重复相同的程序,直到填满。
温度控制
对于第 \(i\) 次模拟退火,我们会跑 \(M\) 次。定义当前温度堆最大值为 \(t_{max}\) ,已知状态与新状态的值差为 \(d_i\),那么发生状态转移的概率 \(p_i\) 为(公式3):
\]
以上可以通过公式 1 得出(应该是一毛一样)。
根据Metropolis算法(Metropolis acceptance criterion),每次遇到一个较差的新状态,生成一个从0到1的随机小数 \(r\)。如果 \(r\) 小于发生状态转移的概率 \(p\),则将接受较差的新状态,同时通过以下公式算出新的温度 \(t_i\)(公式4):
\]
证明可参见公式 2 的证明。
更新列表
对于第 \(i\) 次模拟退火,我们跑完 \(M\) 次后,将最大值 \(t_{max}\) 从堆里删去,插入上述 \(t_i\) 的平均值,然后进行下一次模拟退火。
下图表对此进行了详细解释:
a(LBSA开始) --> b[生成温度堆<br/>生成状态 $x$<br/>$k=0$] --> c[从温度堆 $L$ 堆顶取出最大值 $T$<sub>$max$</sub><br/>$k++,t=0,c=0,m=0$] --> d[创建新状态 $y$<br/>$m++$] --> e{"$f(y)<f(x)$ (解更优)"} --No--> f["定义$d_i=−(f(y)-f(x))$<br/>$p=exp(-d_i/t$<sub>$max$</sub>$)$(公式3)<br/>生成从0到1的随机数 $r$"] --> g{"$r\le p$"} --Yes--> h["$t=t+(-d_i/\ln(r))$     <br/>c++"] --> i["$x=y$     "] --> j[$m\le M$] --No--> k{"$c==0?$     "} --No--> l["弹出温度堆 $L$ 堆顶<br/>插入 $t/c$"] --> m{$k\le K$} --No--> n(LBSA结束)
e --Yes--> i
g --No--> j
j --Yes--> d
k --Yes--> m
m --Yes--> c
堆优化模拟退火(List-Based Simulated Annealing|List-Based SA|LBSA|模拟退火) 算法的更多相关文章
- Dijkstra算法堆优化
		转自 https://blog.csdn.net/qq_41754350/article/details/83210517 再求单源最短路径时,算法有优劣之分,个人认为在时间方面 朴素dijkstra ... 
- 模拟退火 Simulated annealing
		模拟退火 Simulated annealing 看看有空把图片完善一下好了 模拟退火算法的一些背景 既然要说模拟退火算法,就应该说一下模拟退火算法的背景,模拟退火算法是局部搜索算法的一种扩展,该算法 ... 
- uva10986 堆优化单源最短路径(pas)
		var n,m,s,t,v,i,a,b,c:longint;//这道题的代码不是这个,在下面 first,tr,p,q:..]of longint; next,eb,ew:..]of longint; ... 
- 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford  & 单源最短路SPFA)
		关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ... 
- 堆优化的Dijkstra
		SPFA在求最短路时不是万能的.在稠密图时用堆优化的dijkstra更加高效: typedef pair<int,int> pii; priority_queue<pii, vect ... 
- codeforces 449B Jzzhu and Cities (Dij+堆优化)
		输入一个无向图<V,E> V<=1e5, E<=3e5 现在另外给k条边(u=1,v=s[k],w=y[k]) 问在不影响从结点1出发到所有结点的最短路的前提下,最多可以 ... 
- POJ 1511 - Invitation Cards 邻接表 Dijkstra堆优化
		昨天的题太水了,堆优化跑的不爽,今天换了一个题,1000000个点,1000000条边= = 试一试邻接表 写的过程中遇到了一些问题,由于习惯于把数据结构封装在 struct 里,结果 int [10 ... 
- POJ 2502 - Subway Dijkstra堆优化试水
		做这道题的动机就是想练习一下堆的应用,顺便补一下好久没看的图论算法. Dijkstra算法概述 //从0出发的单源最短路 dis[][] = {INF} ReadMap(dis); for i = 0 ... 
- Bzoj 2834: 回家的路  dijkstra,堆优化,分层图,最短路
		2834: 回家的路 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 62 Solved: 38[Submit][Status][Discuss] D ... 
- Dij的堆优化
		#include<algorithm> #include<iostream> #include<cstdio> #include<cstring> #i ... 
随机推荐
- C语言指针--指针中的const
			文章目录 前言 一.const 1.什么是const 2.const的使用 二.const修饰一级指针 1.const放在 `*` 左边 2.const在`*`右边 三.const修饰二级指针 1.c ... 
- Redis的五大数据类型及其使用场景
			前言 redis是一个非常快速的非关系数据库解决方案.其简单的键值数据模型使 Redis 能够处理大型数据集,同时保持令人印象深刻的读写速度和可用性.redis提供了五种数据类型,分别是是: ... 
- DevOps|服务治理与服务保障实践指南
			朱晋君@君哥聊技术 我自己为了消化里边的内容,整理了一个脑图,希望对你有帮助. 凌晨四点被公司的监控告警叫醒了,告警的原因是生产环境跑批任务发生故障.即刻起床处理故障,但还是花了不少时间才解决. 这次 ... 
- SqlSugar本地缓存查询实现方式
			有C#的国产ORM SqlSugar 好久了,实在话还不错,不过毕竟是早期产物不能过分要求规范化,有些项目查询语句需要用到缓存,官方是redis,我写了个本地缓存借助ConcurrentBag,因为有 ... 
- 【pandas小技巧】--修改列的名称
			重命名 pandas 数据中列的名称是一种常见的数据预处理任务.这通常是因为原始数据中的列名称可能不够清晰或准确.例如,列名可能包含空格.大写字母.特殊字符或拼写错误. 使用 pandas 的 ren ... 
- 关于3D-AIGC的调研与探讨
			0.前言 本文是自己最近在项目上的需要做的一些调研和自己的一些看法,以分享为主. 2D AIGC(文生文.文生图.图生图)在今天大放异彩,产生了许多惊艳的效果,如ChatGPT系列.Imagen.DA ... 
- vue3探索——组件通信之事件总线
			Vue2.x使用EventBus进行组件通信,而Vue3.x推荐使用mitt.js. 比起Vue实例上的EventBus,mitt.js好在哪里呢?首先它足够小,仅有200bytes,其次支持全部事件 ... 
- module.exports和exports,应该用哪个
			在 Node.js 编程中,模块是独立的功能单元,可以在项目间共享和重用.作为开发人员,模块让我们的生活更轻松,因为我们可以使用模块来增强应用程序的功能,而无需亲自编写.它们还允许我们组织和解耦代码, ... 
- 10分钟理解契约测试及如何在C#中实现
			在软件开发中,确保微服务和API的可靠性和稳定性非常重要. 随着应用程序变得越来越复杂,对强大的测试策略的需求也越来越大,这些策略可以帮助团队在不牺牲敏捷性的情况下交付高质量的代码. 近年来获得广泛关 ... 
- MySQL 分表查询
			分表是一种数据库分割技术,用于将大表拆分成多个小表,以提高数据库的性能和可管理性.在MySQL中,可以使用多种方法进行分表,例如基于范围.哈希或列表等.下面将详细介绍MySQL如何分表以及分表后如何进 ... 
