模拟退火学习笔记

news/2024/11/16 13:33:52/文章来源:https://www.cnblogs.com/hangry/p/18327857

模拟退火学习笔记

前言

不知道为啥突然有闲情学这个...

模拟退火 (Simulated Annealing) , 简称 \(SA\) .

是一种基于随机化的算法,无门槛,主要是为了骗分...

不是正解!!!!

根据 爬山算法 的过程,我们发现:对于一个当前最优解附近的非最优解,爬山算法直接舍去了这个解。而很多情况下,我们需要去接受这个非最优解从而跳出这个局部最优解,即为模拟退火算法。

关于退火

什么是退火?

退火是一种金属热处理工艺,指的是将金属缓慢加热到一定温度,保持足够时间,然后以适宜速度冷却。目的是降低硬度,改善切削加工性;消除残余应力,稳定尺寸,减少变形与裂纹倾向;细化晶粒,调整组织,消除组织缺陷。准确的说,退火是一种对材料的热处理工艺,包括金属材料、非金属材料。而且新材料的退火目的也与传统金属退火存在异同。

贺的百度百科

\(E| \{x_i\} |\) 表示某一物质体系在微观状态 \(\{x_i\}\) 下的内能,对于给定温度 \(T\) , 若体系处于热平衡态时, \(E |\{x_i\}|\) 服从 Boltzmann 分布:

\[f = c(T) \times e ^ {- \frac{E|\{x_i\}|}{k \times T}} \]

其中 \(k\) 为 Boltzmann 常数。
\(T\) 下降, \(E\) 随之下降。只要温度下降足够慢,体系可以长久保持热平衡态。

当我们退火时,刚开始的时候温度高,分子运动剧烈,变化率较高;

然而对于温度降下来之后,分子逐渐趋于稳定,于是分子变化比较小。

模拟退火,就是模拟的这个过程。

具体实现

当然,什么都不能摆脱随机化。

我们设初始温度 \(T_0 > 1000\) , 降温系数 \(\zeta = \{0.996 , 0.995 , \dots\}\) , 末尾温度 \(T_k > 0\) , 在 \(10 ^ {-15}\) 左右 .

对于我们的新横坐标来说,显然他要有局部的特性,并随时间的延长,温度下降,转移地方要更加稳定,就是离旧的横坐标近一点,因此在随机时要有 \(T\) 这个自变量。

然而对于我们新的这个值 \(y\) , 旧的值为 \(x\) , \(\Delta = y - x\)

退火的过程、转移的概率如下:

\[P(x , y) = \begin{cases}1 \ , \ \Delta < 0 \\e ^ {- \frac{\Delta}{T}} \ , \ \Delta > 0\end{cases}\]

为什么会存在第二种转移呢?

是为了跳出局部最优解,可能进入新的更优解的地方。

贴图:

具体实现 [JSOI2004] 平衡点 / 吊打XXX

题目描述

如图,有 \(n\) 个重物,每个重物系在一条足够长的绳子上。

每条绳子自上而下穿过桌面上的洞,然后系在一起。图中 \(x\) 处就是公共的绳结。假设绳子是完全弹性的(即不会造成能量损失),桌子足够高(重物不会垂到地上),且忽略所有的摩擦,求绳结 \(x\) 最终平衡于何处。

注意:桌面上的洞都比绳结 \(x\) 小得多,所以即使某个重物特别重,绳结 \(x\) 也不可能穿过桌面上的洞掉下来,最多是卡在某个洞口处。

\(1\le n\le 1000\)

\(-10000\le x_i,y_i\le10000, 0<w_i\le1000\)

题解

假设平衡点坐标为 \((X , Y)\)

那么对于一个重物(坐标为 \(x_i , y_i\) )贡献的重力势能为:

\(E = \sqrt{(X - x_i) ^ 2 + (Y - y_i) ^ 2} \times w_i\)

我们是需要将所有的势能和最小化即可。

注意因为我们为了让答案尽可能的对, $SAS 过程要跑很多遍。

CODE
#include <bits/stdc++.h>
using namespace std ;
#define int long long 
const int N = 2e5 + 100 ; 
inline int read() {int x = 0 , f = 1 ; char c = getchar() ; while (c < '0' || c > '9') {if (c == '-') f = -f ; c = getchar() ; }while (c >= '0' && c <= '9') {x = x * 10 + c - '0' ; c = getchar() ; }return x * f ; 
}struct Physics {int x , y , gravity ; 
} a[N] ; 
int n ; double first , second , ans = 1000000000 , averx , avery ; void Energy(double x , double y , double & statics) {statics = 0 ; for (int i = 1 ; i <= n ; ++ i) {statics += sqrt((x - a[i].x) * (x - a[i].x) + (y - a[i].y) * (y - a[i].y)) * a[i].gravity ; }
}void SA() {double T = 3000 ; double x = first , y = second , now , delta_E ; while (T > 1e-16) {x = first + (rand() * 2ll - RAND_MAX) * T ; y = second + (rand() * 2ll - RAND_MAX) * T ; Energy(x , y , now) ; delta_E = now - ans ; if (delta_E < 0) {ans = now , first = x , second = y ; } else if (exp(- delta_E / T) * RAND_MAX > rand()) {first = x , second = y ; }T *= 0.996 ; }
}inline void solve() {SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; SA() ; 
}double sumx , sumy ; 
signed main() {srand((unsigned long long)(new char)) ; n = read() ; for (int i = 1 ; i <= n ; ++ i) {a[i] = {read() , read() , read()} ; sumx += a[i].x ; sumy += a[i].y ; }averx = 1.0 * sumx / n ; avery = 1.0 * sumy / n ; Energy(averx , avery , ans) ; first = averx , second = avery ; solve() ; printf("%.3lf %.3lf" , first , second) ; 
}

结尾撒花 \(\color{pink}{✿✿ヽ(°▽°)ノ✿}\)

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

录取查询

这道题赛时是想出来了,但是线段树出锅了,只得了20分。 首先根据题目我们可以得出,一个序列要是为T的子串,就必须满足以下三个条件。 1.该序列单调不降。如 ba肯定是不合法的。 2.该序列除去开头和结尾的字母,其他字母的数量必须为整个序列全部的该字母数量。 如 abbcba 选…

NaplesPU或NPU技术开发文档合成全部(修改版)

NaplesPU或NPU技术开发文档合成全部(修改版) http://www.naplespu.com/doc/index.php?title=Main_Page http://www.naplespu.com/ https://github.com/AlessandroCilardo/NaplesPU https://github.com/AlessandroCilardo/NaplesPU-toolchain http://www.naplespu.com/doc/in…

万恶资本主义观赏记录

万恶的资本主义到底如何没有体验过,我需要去体验,6月开始计划,参考了团队游项目,最终决定自由行。 行程从香港Hongkong飞伊斯坦布尔Istanbul,10小时,再飞纽约市New York City,10小时。再坐巴士去费城Philadelphia,一共15天。总结: 美国New York City,Philadelphia在美…

D. The Omnipotent Monster Killer

D. The Omnipotent Monster Killer题目大意: 有一棵树,树节点数不超过\(310^5\),每个节点的权值,定义为数组\(a(a_i<10^{12})\),初始\(sum=0\),每一轮执行如下操作:计算当前剩余所有的点权和,累计到\(sum\)中 任选若干个互不相邻的节点并移除重复这个操作直到树上没…

php 使用swoole 创建websocket服务

下载对应版本的swoole扩展, 我的php版本是7.4, 所以下载的swoole版本为4.8.* 地址如下https://pecl.php.net/package/swoole 通过源码编译安装, 可以参考官方文档https://wiki.swoole.com/zh-cn/#/environment 修改php.ini 开启扩展 extension=swoole.so 重启web服务器 php -m …

Labview笔记

1. 背景 Labview这个软件,从大学到现在,装了卸载,卸载了又装。来来回回不下10次了,那本大学时的教材Labview 2010基础教程,一直没丢,但也一直没看过。最近又装回来了,准备简单的系统性倒腾一下,当是个了解。一些杂项:快捷键:Ctrl+N:创建一个Labview项目 Ctrl+E:切换前…

二值图像

一、 二值图像概念 1. 二值图像含义二值图像(Binary Image)是指将图像上的每一个像素只有两种可能的取值或灰度等级状态,人们经常用黑白、B&W、单色图像表示二值图像。 二值图像是指在图像中,灰度等级只有两种,也就是说,图像中的任何像素点的灰度值均为0或者255,分别…

17、flask-图书简单馆项目

为了掌握模型可以练一下、以下是代码: app.py from App import create_appapp = create_app()if __name__ == __main__:app.run(debug=True)views.py from flask import Blueprint, render_template from datetime import datetime from .models import *#创建蓝图(路由) bl…

全网最适合入门的面向对象编程教程:25 类和对象的Python实现-Python判断输入数据类型

本文主要介绍了在使用Python面向对象编程时,如何使用type函数、isinstance函数和正则表达式三种方法判断用户输入数据类型,并对相关语法进行介绍。全网最适合入门的面向对象编程教程:25 类和对象的 Python 实现-Python 判断输入数据类型摘要: 本文主要介绍了在使用 Python …

[数据结构] 堆与堆排序

本文介绍了堆这种数据结构的性质,以及堆排序算法,最后介绍了堆的相关应用场景。这篇文章使用 JavaScript 语言进行相关代码的编写。数据结构——堆 heap 基本概念与性质 堆是一颗完全二叉树,根据父子节点之间值的大小关系可以分为:大根堆:每一个节点的值 大于或等于 其子节…

详解 Hough 变换(基本原理与直线检测)

Hough 变换原理与应用前言: 详细介绍了 Hough 变换的基本思想、基本原理和应用等。其中大多都是自己的理解,难免有偏差,仅供参考。文章目录Hough 变换原理与应用1. 基本概述1.1 一些基本问题 1.2 以例子说明1.2.1 例子1:直线 y = k x + b y = kx + by=kx+b​​​​​​​ 到…