Simulate Anneal模拟退火算法,是一种用于得到最优解的随机化算法。

如果可以打一手漂亮的随机化搜索,也许当你面对一筹莫展的神仙题时就有一把趁手的兵器了。

这篇题解将教你什么?SA的基本思路,什么时候能用SA。

标题是浅谈,所以本篇博客参杂了些许个人简介,若有疑问或异议,欢迎提出指正。

我也很感谢你们给出的建议,它们真的能让我变好、变强。

那么我们进入本篇正题。

1. 什么是模拟退火:

模拟退火是一种在广大的搜索空间寻找最优解的随机化算法。我们看名字就明白,这个算法实在模拟物理中退火的过程。知识很多时候都是相通的,我们学习的大部分知识都是有用的。

为什么通过模拟退火的过程可以得出最优解呢?在物理中,固体物质的退火过程和一般的组合优化问题有着很高的相似度。

2. 模拟退火基本要素:

满足这些你就可以将SA算法愉快地嵌入你的程序里了。

第一个要素就是状态空间和状态的产生函数,我们需要有一个搜索空间,而且范围较大。

什么是搜索空间呢?我们学习搜索的时候应该接触过,我们的搜索算法本质就是在问题的求解空间中进行遍历,寻找最优解。模拟退火的状态空间也类似,它就是我们自定义出来的最优解的有限集合。

我们光有状态空间还不够啊,我们真正需要的是状态。学函数的时候,老师就说过了,一个函数要有“域”。我们的状态空间就是状态产生函数的“域”。而我们如果想写一个好的退火,我们的搜索空间要足够大,足够让函数生成不同的新解。

第二个就是候选解,我们在状态空间内通过生成的随机数在一定密度内随机选择我们的候选解。

其实还有一条是概率分布,大部分采用均匀分布,少数情况我们会用到指数分布。

至于状态转移概率,我目前接触到的SA算法统统采用了Metropolis准则,我接下来会介绍它。

3. 模拟退火基本流程:

一. 由一个状态产生函数从当前解产生一个新解,一般采用增量构造(即由原解加上/减去产生函数产生的值)来得到。

二. 计算新解的目标函数差Δt'。

三. 判断新解是否被接受,

这里介绍Metropolis准则:若Δt'<0,我们接受它,否则以exp(-Δt'/T)的多项式概率接受它。

**T是我们模拟退火过程中的温度**

四. 当新解被接受时,用新解代替当前解,否则继续下一轮试验。

4. 模拟退火中的参数控制:

调参可以说是SA算法最难的部分,也是决定你的算法得分率的部分。

这里分享一下神仙FlashHu(LCT导师Orz)写SA时调参的经验,我总结了一下就是这样:

对于eps,可以根据数据范围和精度要求粗略得到eps的大概大小,手动微调可以得到最终的eps。

对于T和ΔT(温度的变化率,一般在0.95-0.99间),先开大一点跑出最优解,然后一边退火一边输出当前的T、ans等信息,大致感受解的下降速率,越均匀表示参数越好(神仙称之为观察法)

5. 注意事项:

SA可能会陷入当前解卡在局部最小的情况,也就是这样:

图中,红色是我们的当前解,蓝色是我们的最优解,红色的线代表SA算法得到的新解,我们会发现,如果参数不佳,我们就有可能出现卡在局部最优解的情况。本身算法的设计就有避免这一种情况,还记得吗?Metropolis准则,就算这不是最优解,我们也以一定概率接受它(答案不更新),就是为了防止这种情况,然而在参数不佳的情况下,它仍可能发生。所以我们要改进对温度的控制方式。

这里还是以那道经典到不能再经典的模拟退火模板做例题:平衡点/吊打xxx

这里直接贴上代码,关于算法中需要注意的地方我会打上注释。

#include<bits/stdc++.h>
#define down 0.997//ΔT,模拟徐徐降温
using namespace std;
inline int read(){
int data=,w=;char ch=;
while(ch!='-' && (ch<''||ch>''))ch=getchar();
if(ch=='-')w=-,ch=getchar();
while(ch>='' && ch<='')data=data*+ch-'',ch=getchar();
return data*w;
}
int n;
struct point{
int x,y,w;
}object[];//物体信息
double ansx,ansy,answ;//答案
double energy(double x,double y){//物理学知识:能量总和越小越稳定
double r=,dx,dy;
for(int i=;i<=n;i++){
dx=x-object[i].x;dy=y-object[i].y;
r+=sqrt(dx*dx+dy*dy)*object[i].w;//力臂乘重力
}
return r;
}
void SA(){
double t=3e3+;//初始温度要高
while(t>1e-){//exp略大于0
double ex=ansx+(rand()*-RAND_MAX)*t;
double ey=ansy+(rand()*-RAND_MAX)*t;
double ew=energy(ex,ey);
double de=ew-answ;
if(de<){//此答案更优
ansx=ex;ansy=ey;answ=ew;
}else if(exp(-de/t)*RAND_MAX>rand()){//Metropolis准则,以多项式概率接受
ansx=ex;ansy=ey;
}t*=down;//逐步降温
}
}
void solve(){
SA();SA();SA();SA();SA();
}
int main(){
n=read();
for(int i=;i<=n;i++){
object[i].x=read();object[i].y=read();object[i].w=read();
ansx+=object[i].x;ansy+=object[i].y;
}
ansx/=n;ansy/=n;//设平均值为初值
answ=energy(ansx,ansy);
solve();
printf("%.3lf %.3lf\n",ansx,ansy);
return ;
}

游戏结束。

[随机化算法] 听天由命?浅谈Simulate Anneal模拟退火算法的更多相关文章

  1. Manacher算法(马拉车算法)浅谈

    什么是Manacher算法? 转载自百度百科 Manachar算法主要是处理字符串中关于回文串的问题的,它可以在 O(n) 的时间处理出以字符串中每一个字符为中心的回文串半径,由于将原字符串处理成两倍 ...

  2. 大数质因解:浅谈Miller-Rabin和Pollard-Rho算法

    2017-07-19 08:54 Amphetamine:能发一下代码吗? 应我那位谜一样好友的邀约,我打算好好看一看Miller-Rabin和Pollard-Rho算法.很奇怪,各种地方有很多代码描 ...

  3. 浅谈Java数据结构和算法

    今天的突然看集合底层的时候发现了好多算法和数据结构.再次就比较一下和汇总一下. 数据结构分类:线性结构和非线性结构 问题一: 什么是线性和非线性: 我个人的理解是:数据结构中线性结构指的是数据元素之间 ...

  4. [HDU1109]模拟退火算法

    模拟退火的基本思想: (1) 初始化:初始温度T(充分大),初始解状态S(是算法迭代的起点),每个T值的迭代次数L (2) 对k=1,……,L做第(3)至第6步: (3) 产生新解$S\prime $ ...

  5. 模拟退火算法SA原理及python、java、php、c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径

    模拟退火算法SA原理及python.java.php.c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径 模拟退火算法(Simulated Annealing,SA)最早的思 ...

  6. 浅谈URLEncoder编码算法

    一.为什么要用URLEncoder 客户端在进行网页请求的时候,网址中可能会包含非ASCII码形式的内容,比如中文. 而直接把中文放到网址中请求是不允许的,所以需要用URLEncoder编码地址, 将 ...

  7. 浅谈Hex编码算法

    一.什么是Hex 将每一个字节表示的十六进制表示的内容,用字符串来显示. 二.作用 将不可见的,复杂的字节数组数据,转换为可显示的字符串数据 类似于Base64编码算法 区别:Base64将三个字节转 ...

  8. 浅谈Base64编码算法

    一.什么是编码解码 编码:利用特定的算法,对原始内容进行处理,生成运算后的内容,形成另一种数据的表现形式,可以根据算法,再还原回来,这种操作称之为编码. 解码:利用编码使用的算法的逆运算,对经过编码的 ...

  9. 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...

随机推荐

  1. 将CDH中的hive和hbase相互整合使用

    一..hbase与hive的兼容版本: hive0.90与hbase0.92是兼容的,早期的hive版本与hbase0.89/0.90兼容,不需要自己编译. hive1.x与hbase0.98.x或则 ...

  2. Proxy实现java动态代理

    在java设计模式中代理模式的应用比较广泛, 比如我在编写一写web程序时在filter修改request或response时, 而request中并没有相应的set方法, 这样要做到修改就需要使用一 ...

  3. Eureka参数配置->Server端参数

    1.基本参数 参数 默认值 说明 eureka.server.enable-self-preservation true 是否开启自我保护模式 eureka.server.renewal-percen ...

  4. web前端之浏览器: 知识汇总

    一.URL到页面 准备阶段: 输入URL,Enter进入查找 浏览器在本地查找host文件,匹配对应的IP: 找到返回浏览器并缓存 没有,则进入路由查找: 找到返回浏览器并缓存 再没有,再进入公网DN ...

  5. js常用正则整理

    个人博客: http://mcchen.club //校验是否全由数字组成 function isDigit(s) { var patrn=/^[0-9]{1,20}$/; if (!patrn.ex ...

  6. Spring Boot 定时任务 @Scheduled

    项目开发中经常需要执行一些定时任务,比如在每天凌晨,需要从 implala 数据库拉取产品功能活跃数据,分析处理后存入到 MySQL 数据库中.类似这样的需求还有许多,那么怎么去实现定时任务呢,有以下 ...

  7. Chrome插件开发(一)

    作为一个开发人员,我们在日常工作中肯定会用到 Chrome 浏览器,同时也会用到谷歌的一些插件,比如 Tampermonkey,AdBlock等,在之前的文章本人还是用了 Tampermonkey,传 ...

  8. 超级好用的c#解析JSON

    分享c# 一款非常好用的操作Json的dll,litjson VS2017 NuGet 搜索litjson,如下图: 例子: 在项目中新建一个txt文本文件,内容如下: [ { , "use ...

  9. UVA1420 Priest John's Busiest Day【贪心】

    题意简介 有一个司仪,要主持n场婚礼,给出婚礼的起始时间和终止时间,每个婚礼需要超过一半的时间做为仪式,并且仪式不能终止.问说司仪能否主持n场婚礼. 输入格式 多组数据,每组数据输入一个\(N\)(\ ...

  10. shark恒破解笔记1-壳内寻找注册码

    记录学习shark恒大教程的学习记录 壳内寻找注册码 OD打开 明显有壳 F9先运行程序 2.Ctrl+G输入401000到解码段,如果出现db ** 说明已经解码过,脱离了程序本身的壳 鼠标右键-& ...