模拟退火

浅谈模拟退火

瘦欲@ 提交于 2020-03-21 15:52:43
原谅我将模拟退火放到骚操作的范畴,比较玄学调参,玄学AC。。。。。。(我要当欧皇TAT) 模拟退火算法 模拟退火是一种随机化算法, 用于求函数的极值qwq 比如给出一个问题, 我们要求最优解的值, 但是可能的方案数量极大, 直接搜索会T飞(或者方案是连续的总数无穷根本没法搜), 这种时候我们一般会有两种选择: 爬山算法 爬山算法每次在当前找到的方案附近寻找一个新的方案(常见方式是随机一个差值), 然后如果这个解更优那么直接转移. 对于单峰函数来说这显然可以直接找到最优解(不过你都知道它是单峰函数了为啥不三分呢?) 但是对于多数我们求解的函数来说, 它并不一定会长成这个样子...于是就极其有可能钻进一个局部的最优解出不来了 算法得出的最优解与初始解的位置以及搜寻的附近解的区域大小有关. 当然如果你寻找新方案的区间很大的话有概率跳出去, 但是太大的话又可能跳来跳去跳乱了从而找不到最优解... 欧皇专用最优化求解方式 然而并不是所有人都是欧皇, 像博主这样的非酋要怎么办捏? 当然是求助于自然规律(大雾) 退火的理论部分 退火其实本来是冶金工业里的术语...大概过程是先把晶体加热到极高的温度再缓慢降温, 在这个过程中减少晶体中的缺陷(达到能量最低的最稳定状态) 然后机智的我们发现这个过程最终和我们的最优化过程类似! 于是我们去模拟这个过程, 按照退火的规律引入更多随机因素,

模拟退火算法

允我心安 提交于 2020-03-14 17:29:10
著名的模拟退火算法,它是一种基于蒙特卡洛思想设计的近似求解最优化问题的方法。 一点历史——如果你不感兴趣,可以跳过 美国物理学家 N.Metropolis 和同仁在1953年发表研究复杂系统、计算其中能量分布的文章,他们使用蒙特卡罗模拟法计算多分子系统中分子的能量分布。这相当于是本文所探讨之问题的开始,事实上,模拟退火中常常被提到的一个名词就是Metropolis准则,后面我们还会介绍。 美国IBM公司物理学家 S.Kirkpatrick、C. D. Gelatt 和 M. P. Vecchi 于1983年在《Science》上发表了一篇颇具影响力的文章:《以模拟退火法进行最优化(Optimization by Simulated Annealing)》。他们借用了Metropolis等人的方法探讨一种旋转玻璃态系统(spin glass system)时,发觉其物理系统的能量和一些组合最优(combinatorial optimization)问题(著名的旅行推销员问题TSP即是一个代表例子)的成本函数相当类似:寻求最低成本即似寻求最低能量。由此,他们发展出以 Metropolis 方法为本的一套算法,并用其来解决组合问题等的寻求最优解。 几乎同时,欧洲物理学家 V.Carny 也发表了几乎相同的成果,但两者是各自独立发现的;只是Carny“运气不佳”,当时没什么人注意到他的大作

模拟退火

心不动则不痛 提交于 2020-03-01 22:08:52
贪心+概率 解决:函数最值、TSP旅行商问题、最小园覆盖、最小求覆盖 模板: //模拟退火 int eps=1e-8; //终止温度 int T=100; //初始温度 double delta=0.98; //降温系数 double js(int x) ; //评价函数 double now,next; while(T>eps){ js(next); js(now); de=g(next)-g(now); if(de>=0) now=next; //新状态更好,就受 else if(exp(de/T)>rand()) now=next; //新状态更差,以一定概率接受 T*=delat; } hud 2899 #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<stack> #include<cstdio> #include<queue> #include<map> #include<vector> #include<set> using namespace std; const int maxn=1010; const int INF=0x3fffffff; typedef long long LL; //模拟退火 double y; double eps=1e-8;

SCOI2010 传送带 [三分/模拟退火]

馋奶兔 提交于 2020-01-16 23:38:26
题目描述 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间 输入输出格式 输入格式: 输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整数,表示C和D的坐标,分别为Cx,Cy,Dx,Dy 第三行是3个整数,分别是P,Q,R 输出格式: 输出数据为一行,表示lxhgww从A点走到D点的最短时间,保留到小数点后2位 输入输出样例 输入样例#1: 0 0 0 100 100 0 100 100 2 2 1 输出样例#1: 136.60 说明 对于100%的数据,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000 1<=P,Q,R<=10 题解 这道题其实可以用模拟A掉 把平面上的线段全部看成向量,因为有了ABCD四个点的坐标,所以我们可以用坐标来表示向量,除此之外我们需要设置一个变量 * 上这个初始向量就可以得到这个向量方向上的任意一条向量,也就是用两种循环来枚举,每次变量的改变多少就需要自己调试参数了 正解还是三分法,也可以用模拟退火,以后再补 #include<iostream> #include<cstdio> #include

模拟退火

走远了吗. 提交于 2020-01-15 04:57:06
//根据标记,进行分割操作、可以是分句或者分词 def segment(text, segs): words= [] last = 0 for i in range(len(segs)): if segs[i] =='1': words.append(text[last:i+1]) last = i+1 words.append(text[last:]) return words //计算得分值 def evaluate(text, segs): words= segment(text, segs) text_size = len(words) lexicon_size = len(' '.join(list(set(words)))) return text_size + lexicon_size from random import randint //改变某一个标记串的某一位(1变成0,0变成1) def flip(segs, pos): return segs[:pos] + str(1-int(segs[pos])) + segs[pos+1:] //根据整数N,随机改变N个位置,形成一个猜测的序列 def flip_n(segs, n): for i in range(n): segs = flip(segs, randint(0,len(segs)-1))

模拟退火小记

烂漫一生 提交于 2019-12-05 11:29:28
模拟退火可真是让人AC率--,但又能简单的骗到80+pts的好算法 -------------(手动分割)------------------------------------------- 模拟退火有什么用鸭? 模拟退火用来解决最优性问题,比如求个最大/最小值什么的。如果让求方案数还是老老实实写正(pian)解(fen)叭。 众所周知玄学贪心不需要证明。但如果想到的贪心是错的,那么会导致陷入局部最优解的情况。模拟退火则会以一定的概率跳出这个局部最优解来得到全局最优解。 当然不能保证100%一遍AC辣(后面会讲一些调参小技巧) 模拟退火思想 我们先来扯扯为什么这个算法叫做模拟退火。 顾名思义就是模拟物理退火的过程,但是博主是物(全)理(科)学渣所以并不会用物理语言来描述退火。 退火就是物体有高温缓慢降到低温的过程,在这个过程中,由于是缓慢降温,所以物体的分子会有序的排列。我们要模拟这个过程来使最终答案趋于最优解。 我们每次随机出一个状态来,如果这个状态的解比当前算过的最优解要优,则更新当前最优解,否则我们以一定的概率来接受这个劣解从而达到跳出局部最优的效果。 我们设定一开始的温度 \(T\) (为了模拟物理上的退火qwq)是一个比较大的数 当然要小心不要让代码自燃了 ,并设定一个略小于1的常数 \(nxt\) ,通过 \(T\times nxt\) 来达到徐徐降温的效果

HDU 2899 Strange fuction (模拟退火)

巧了我就是萌 提交于 2019-12-03 02:44:38
题目链接: HDU 2899 Problem Description Now, here is a fuction: F(x) = 6 * x^7+8 x^6+7 x^3+5 x^2-y x (0 <= x <=100) Can you find the minimum value when x is between 0 and 100. Input The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has only one real numbers Y.(0 < Y <1e10) Output Just the minimum value (accurate up to 4 decimal places),when x is between 0 and 100. Sample Input 2 100 200 Sample Output -74.4291 -178.8534 Solution 题意 给定 \(y\) ,求函数 \(F(x) = 6x^7 + 8x^6 + 7x^3 + 5x^2 - yx\) 的最小值,其中 \(x\) 的范围是 \([0, 100]\) 。

模拟退火初步讲解

匿名 (未验证) 提交于 2019-12-03 00:37:01
以前在介绍某个算法的时候我都会想当然的取个“xxxx算法详解”,然而这个只是用到了初步讲解。原因是我只在做计算几何上用到了这个算法,并且实质上不完全是这个算法的具体表现。所以对这个算法的理解可能还不太透彻。所以才用的初步讲解。。 一下内容参考自: https://blog.csdn.net/qq_34374664/article/details/7 833 2983 爬山算法也是一个用来求解最优化问题的算法,每次都向着当前上升最快的方向往上爬,但是初始化不同可能会得到不同的局部最优值,模拟退火算法就可能跳出这种局部最优解的限制。模拟退火算法是模拟热力学系统中的退火过程。在退火过程中是将目标函数作为能量函数。大致过程如下 初始高温 => 温度缓慢下降=> 终止在低温 (这时能量函数达到最小,目标函数最小) P i ( T k ) = C k e x p ( E i T k ) P i ( T k ) = C k e x p ( E i T k ) 模拟退火算法也是贪心算法,但是在其过程中引入了随机因素,以一定的概率接受一个比当前解要差的解,并且这个概率随着时间的推移而逐渐降低。 若 F ( Y ( i + 1 ) ) > F ( Y ( i ) ) F ( Y ( i + 1 ) ) > F ( Y ( i ) ) ,即移动后得到更优的解,那么总是接受该移动。 若 F ( Y ( i

[模拟退火][UVA10228] A Star not a Tree?

匿名 (未验证) 提交于 2019-12-02 23:48:02
好的,在 h^ovny 的安利下做了此题 模拟退火中的大水题, 想当年联赛的时候都差点打了退火, 正解貌似是三分套三分 ,我记得上一道三分套三分的题我就是退火水过去的... 貌似B班在讲退火这个大玄学... 这题还是比较简单的啦~ 随机化坐标x,y就可以啦 然而格式错了n遍.....死的心都有了 最后输出是 四舍五入!!! 四舍五入!!! 四舍五入!!! 两组答案中间 有空行!!! 有空行!!! 有空行!!! 然后只要会退火的板子就可以啦 //LevenKoko#include<bits/stdc++.h> using namespace std; inline int read(){ int ans=0,f=1;char chr=getchar(); while(!isdigit(chr)){if(chr=='-')f=-1;chr=getchar();} while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();} return ans*f; } int x[1005],y[1005],n; double ansx,ansy,ans; const double delta=0.998; inline double DIS(double x1,double x2,double y1,double y2)