首页 > 其他分享 >模拟退火

模拟退火

时间:2023-11-27 22:55:20浏览次数:32  
标签:单峰函数 int 新解 模拟退火 爬山 最优

引入

模拟退火,一种由金属退火启发的随机化(玄学)算法,。

当问题的方案数及其巨大甚至是无穷,而且不是一个线性或单峰函数时,模拟退火是一个较好的解决方案。

解释

先介绍一下它的前置算法——爬山算法。

爬山算法

爬山算法是一种局部择优的方法,采用启发式方法,是对深度优先搜索的一种改进,它利用反馈信息帮助生成解的决策。

说人话,也就是生成一个新解,将新解与当前最优解比较,如果更优,转移,否则不变,继续生成新解。

听不懂?举个可爱的例子。

假设我们现在有一个如下的单峰函数:

很明显,最优值就是红色箭头所在的地方。

把这个单峰函数比作一座山,可以举个例子:

现在有一只胡萝卜吃多了的软萌可爱的小兔纸,她的家在山顶(最优解)处,而她现在在山脚(初始值)。

粉色箭头为小兔纸初始位置

她每次都跳一步,拿出气压计看看有没有比原先高(是否更优),如果是的,那么就从这里继续跳,否则,那就只好跳回去啦(回溯?)。

那就可以一步一步地走,一路 向云端(安安安安安安安~),一定会到家的。

但这样实在太慢了!万一这座山是珠穆朗玛峰,小兔纸变成冰雕了还没到家吧……

于是小兔纸想出一个办法,她一口气跳超级远,不就好啦。

淡绿色为小兔纸跳跃后的位置

那确实挺快的,但又有个问题,跳的距离太远,不小心跳过山顶,就算她再翻过来,因为跳跃距离是固定的,还是会再次跳过山顶,那不就怎么跳都再也到不了家了吗?

所以就要改变策略,先一开始跳很远,然后慢慢地减少跳跃距离,越来越谨慎,这样就可以慢慢接近山顶了。

序号表示小兔子跳的顺序

就这样,小兔子终于到了家……

实现

一般来说,爬山需要利用一个名为⌈温度⌋的变量,温度可以理解为新解与当前最优解的更改幅度。

然后使用一个能量函数计算新解的能量,用于比较新解是否更优。

记得为当前最优解计算一个初始值。

例题:洛谷 P4035 [JSOI2008] 球形空间产生器

观察可以发现,这是一个单峰函数,爬山解决。

#include<bits/stdc++.h>
using namespace std;
const int N = 15;
const double d = 0.99995;
int n;
double dis[N],ans[N],cans[N],f[N][N];
double t = 10000;
void check(){ // 能量函数
	double res = 0;
	for(int i = 1;i <= n + 1;i ++){
		dis[i] = 0;
		cans[i] = 0;
		for(int j = 1;j <= n;j ++)
			dis[i] += (f[i][j] - ans[j]) * (f[i][j] - ans[j]);
		dis[i] = sqrt(dis[i]),res += dis[i];
	}
	res /= (n + 1);
	for(int i = 1;i <= n + 1;i ++)
		for(int j = 1;j <= n;j ++)
			cans[j] += (dis[i] - res) * (f[i][j] - ans[j]) / res;
}
int main(){
	cin>>n;
	for(int i = 1;i <= n + 1;i ++)
		for(int j = 1;j <= n;j ++)
			cin>>f[i][j],ans[j] += f[i][j];
	for(int i = 1;i <= n;i ++)
		ans[i] /= (n + 1);
	while(t >= 0.0001){
		check();
		for(int i = 1;i <= n;i ++)
			ans[i] += cans[i] * t; // 计算新解
		t *= d; // 降温
	}
	for(int i = 1;i <= n;i ++)
		printf("%.3lf ",ans[i]);
	return 0;
}

但是如果需要解决的问题不是单峰函数,而是一个多峰函数呢?

那么如果初始值为粉色箭头处,爬山算法就很有可能会找到绿色箭头处的局部最优解,但很明显,全局最优解应为红色箭头处。

这时候就该请出模拟退火了。

标签:单峰函数,int,新解,模拟退火,爬山,最优
From: https://www.cnblogs.com/acangcang-Eliauk/p/17860775.html

相关文章

  • 模拟退火
    番外曾经看CY用模拟退火大杀四方,所以今天也来看一下这个算法,看了之后相见恨晚啊!我也不晓得为什么这么晚才学,多么优秀(暴力)的东西,QwQ在这里声明并不是完全原创,大部分选自Darth_Che的博客,介绍简介模拟退火算法(SimulateAnneal,SA)是一种通用概率演算法,用来在一个大的搜寻空间......
  • 【复建笔记】模拟退火
    简述一下我的理解:为什么要有那一行一定概率下接受答案?因为如果没有就会在当前峰下爬山,有的话才能跳到别的峰上,这一行与温度有关,当温度越低,跳的概率越低。退火随机一个二维点:nowx=limx+((rand()<<1)-RAND_MAX)*T;nowy=limy+((rand()<<1)-RAND_MAX)*T;......
  • 模拟退火算法(SA,Simulated Annealing)思想
    模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。模拟退火算法(SimulatedAnnealing,SA)最早由Kirkpatrick等应用于组合优化领域......
  • 模拟退火(浅谈)
    写在前面放眼历史,喧嚣过后终归无声,热寂才是最终归宿。算法思想世界上的万事万物总是比较容易稳定在低能量的状态,当物体温度较高时,内能较大,固体内部粒子处于快速无规则运动,在固体温度慢慢降低的过程中,固体内能减小,粒子慢慢趋于有序。举个现实生活的小栗子:在冶金工业中,通常会把......
  • 算法笔记(3)模拟退火
    原发表于个人博客=模拟退火的引入假如我们有一个函数,要求它的极大值,怎么求呢?如果这个函数满足单调性,可以用二分的方法。如果这是一个单谷(或单峰)函数,可以用三分法。那要是多峰函数怎么半呢?这时就可以用随机化算法。一种朴素的方法是:每次在当前找到的最优方案\(x\)附近寻找一......
  • 【学习笔记】模拟退火
    快一年前写的东西了。从洛谷上搬过来滴。以下是正文。简介模拟退火SimulateAnneal是一种随机化算法。用于求解方案数量极大(甚至是无穷的)而且不是一个单峰函数的问题。模拟退火的出发点是基于物理中固体物质的退火过程与一般组合优化问题之间的相似性。模拟退火算法是一种通......
  • 专题3——模拟退火
    P1337模拟退火是一门玄学,我发现全看手气,因此,为了避免消耗手气,赛前我只练四道。本题精度要求较高,因此选取较低温度,较高delta,温度下限取到1e-14。P2503这道题目中,随机化才是神。连续分段问题可以dp,这道题目,我们选择random_shuffle后再dp,正确率是很高的,因为最终的答案中,每......
  • 模拟退火详解
    模拟退火学习(030920一上午成果)目录模拟退火学习(030920一上午成果)前言:1.爬山算法由来:2.模拟退火:算法流程:初学(我)的问题用题来进行理解:BZOJ1844RunAway(cqbz的oj上有)回顾上面的问题:对于Q1对于Q2:Q2的补充:对于Q3前言:emmmm。你还在考虑dp死活写不出来吗?你还在担忧贪心算法的正确......
  • 模拟退火
    模拟退火解决问题——数值计算一般解决步骤多元方程:\[\begin{cases} {f_{1L}}(x)={f_{1R}}(x)\\ {f_{2L}}(x)={f_{2R}}(x)\\ \\\\\\\\\dots\dots\\ {f_{nL}}(x)={f_{nR}}(x)\\\end{cases}\]评价函数:\[\Huge{\rm{A=}}\sum\limits_{i=1}^n{}\fr......
  • 「学习笔记」浅入模拟退火
    什么是退火?来自百度百科退火是一种金属热处理工艺,指的是将金属缓慢加热到一定温度,保持足够时间,然后以适宜速度冷却。目的是降低硬度,改善切削加工性;降低残余应力,稳定尺寸,减少变形与裂纹倾向;细化晶粒,调整组织,消除组织缺陷。准确的说,退火是一种对材料的热处理工艺,包括金属材料、非......