您好,欢迎访问三七文档
解析模拟退火算法一.爬山算法(HillClimbing)介绍模拟退火前,先介绍爬山算法。爬山算法是一种简单的贪心搜索算法,该算法每次从当前解的临近解空间中选择一个最优解作为当前解,直到达到一个局部最优解。爬山算法实现很简单,其主要缺点是会陷入局部最优解,而不一定能搜索到全局最优解。如图1所示:假设C点为当前解,爬山算法搜索到A点这个局部最优解就会停止搜索,因为在A点无论向那个方向小幅度移动都不能得到更优的解。二.模拟退火(SA,SimulatedAnnealing)思想爬山法是完完全全的贪心法,每次都鼠目寸光的选择一个当前最优解,因此只能搜索到局部的最优值。模拟退火其实也是一种贪心算法,但是它的搜索过程引入了随机因素。模拟退火算法以一定的概率来接受一个比当前解要差的解,因此有可能会跳出这个局部的最优解,达到全局的最优解。以图1为例,模拟退火算法在搜索到局部最优解A后,会以一定的概率接受到E的移动。也许经过几次这样的不是局部最优的移动后会到达D点,于是就跳出了局部最大值A。模拟退火算法描述:若J(Y(i+1))=J(Y(i))(即移动后得到更优解),则总是接受该移动若J(Y(i+1))J(Y(i))(即移动后的解比当前解要差),则以一定的概率接受移动,而且这个概率随着时间推移逐渐降低(逐渐降低才能趋向稳定)这里的“一定的概率”的计算参考了金属冶炼的退火过程,这也是模拟退火算法名称的由来。根据热力学的原理,在温度为T时,出现能量差为dE的降温的概率为P(dE),表示为:P(dE)=exp(dE/(kT))其中k是一个常数,exp表示自然指数,且dE0。这条公式说白了就是:温度越高,出现一次能量差为dE的降温的概率就越大;温度越低,则出现降温的概率就越小。又由于dE总是小于0(否则就不叫退火了),因此dE/kT0,所以P(dE)的函数取值范围是(0,1)。随着温度T的降低,P(dE)会逐渐降低。我们将一次向较差解的移动看做一次温度跳变过程,我们以概率P(dE)来接受这样的移动。关于爬山算法与模拟退火,有一个有趣的比喻:爬山算法:兔子朝着比现在高的地方跳去。它找到了不远处的最高山峰。但是这座山不一定是珠穆朗玛峰。这就是爬山算法,它不能保证局部最优值就是全局最优值。模拟退火:兔子喝醉了。它随机地跳了很长时间。这期间,它可能走向高处,也可能踏入平地。但是,它渐渐清醒了并朝最高方向跳去。这就是模拟退火。下面给出模拟退火的伪代码表示。三.模拟退火算法伪代码/**J(y):在状态y时的评价函数值*Y(i):表示当前状态*Y(i+1):表示新的状态*r:用于控制降温的快慢*T:系统的温度,系统初始应该要处于一个高温的状态*T_min:温度的下限,若温度T达到T_min,则停止搜索*/while(TT_min){dE=J(Y(i+1))-J(Y(i));if(dE=0)//表达移动后得到更优解,则总是接受移动Y(i+1)=Y(i);//接受从Y(i)到Y(i+1)的移动else{//函数exp(dE/T)的取值范围是(0,1),dE/T越大,则exp(dE/T)也if(exp(dE/T)random(0,1))Y(i+1)=Y(i);//接受从Y(i)到Y(i+1)的移动}T=r*T;//降温退火,0r1。r越大,降温越慢;r越小,降温越快/**若r过大,则搜索到全局最优解的可能会较高,但搜索的过程也就较长。若r过小,则搜索的过程会很快,但最终可能会达到一个局部最优值*/i++;}四.使用模拟退火算法解决旅行商问题旅行商问题(TSP,TravelingSalesmanProblem):有N个城市,要求从其中某个问题出发,唯一遍历所有城市,再回到出发的城市,求最短的路线。旅行商问题属于所谓的NP完全问题,精确的解决TSP只能通过穷举所有的路径组合,其时间复杂度是O(N!)。使用模拟退火算法可以比较快的求出TSP的一条近似最优路径。(使用遗传算法也是可以的,我将在下一篇文章中介绍)模拟退火解决TSP的思路:1.产生一条新的遍历路径P(i+1),计算路径P(i+1)的长度L(P(i+1))2.若L(P(i+1))L(P(i)),则接受P(i+1)为新的路径,否则以模拟退火的那个概率接受P(i+1),然后降温3.重复步骤1,2直到满足退出条件产生新的遍历路径的方法有很多,下面列举其中3种:1.随机选择2个节点,交换路径中的这2个节点的顺序。2.随机选择2个节点,将路径中这2个节点间的节点顺序逆转。3.随机选择3个节点m,n,k,然后将节点m与n间的节点移位到节点k后面。五.算法评价模拟退火算法是一种随机算法,并不一定能找到全局的最优解,可以比较快的找到问题的近似最优解。如果参数设置得当,模拟退火算法搜索效率比穷举法要高。模拟退火算法与其python实现模拟退火算法(SimulatedAnnealing)是基于Monte-Carlo迭代求解策略的一种随机寻优算法,主要用于组合优化问题的求解。假设现在有这么一个函数:现要求其在[0,100]范围内的最小值,如果不求导计算,可能第一反应都是穷举法,把范围内每个值都算一遍再比较大小。如果求的是整数范围,那么要算100遍,但是如果要精确到小数后8位,则要算10000000000次,即便使用计算机依然是一个庞大的运算过程。而优化问题中很多都类似于问题,无法用穷举法解出答案,我们叫这类问题为NP难问题(可查看维基百科:NP-hard)。(注:NP-hard,其中,NP是指非确定性多项式(non-deterministicpolynomial,缩写NP)。所谓的非确定性是指,可用一定数量的运算去解决多项式时间内可解决的问题。NP问题通俗来说是其解的正确性能够被“很容易检查”的问题,这里“很容易检查”指的是存在一个多项式检查算法。若NP中所有问题到某一个问题是图灵可归约的,则该问题为NP-hard问题。)于是,有人提出了爬山法:但是这个方法的缺点在于最优解的产生依赖于最初值的选取,无法解决非凸函数,即容易收敛于局部最优解:同时,也无法解决有平台的函数:于是,Kirkpatrick等提出了模拟退火算法,它是一种启发式搜索算法,即按照预定的控制策略进行搜索,在搜索过程中获取的中间信息将用来改进控制策略1.模拟退火算法的原理1.1概念模拟退火算法的思想借鉴于固体的退火原理,当固体的温度很高的时候,内能比较大,固体的内部粒子处于快速无序运动,当温度慢慢降低的过程中,固体的内能减小,粒子的慢慢趋于有序,最终,当固体处于常温时,内能达到最小,此时,粒子最为稳定。模拟退火算法便是基于这样的原理设计而成。模拟退火算法从某一高温出发,在高温状态下计算初始解,然后以预设的邻域函数产生一个扰动量,从而得到新的状态,即模拟粒子的无序运动,比较新旧状态下的能量,即目标函数的解。如果新状态的能量小于旧状态,则状态发生转化;如果新状态的能量大于旧状态,则以一定的概率准则发生转化。当状态稳定后,便可以看作达到了当前状态的最优解,便可以开始降温,在下一个温度继续迭代,最终达到低温的稳定状态,便得到了模拟退火算法产生的结果。1.2状态空间与邻域函数状态空间也称为搜索空间,它由经过编码的可行解的集合所组成。而邻域函数应尽可能满足产生的候选解遍布全部状态空间。其通常由产生候选解的方式和候选解产生的概率分布组成。候选解一般按照某一概率密度函数对解空间进行随机采样获得,而概率分布可以为均匀分布、正态分布、指数分布等。1.3状态转移概率(Metropolis准则)状态转移概率是指从一个状态转换成另一个状态的概率,模拟退火算法中一般采用Metropolis准则,具体如下:其与当前温度参数T有关,随温度的下降而减小。1.4冷却进度表冷却进度表是指从某一高温状态T向低温状态冷却时的降温函数,设时刻的温度为T(t),则经典模拟退火算法的降温方式为:而快速模拟退火算法的降温方式为:另外还有几种常用的降温函数与此相仿。1.5初始温度一般来说,初始温度越大,获得高质量解的几率越大,但是花费的时间也会随之增加,因此,初温的确定应该同时考虑计算效率与优化质量,常用的方法包括:(1)均匀抽样一组状态,以各状态目标值的方差为初温。(2)随机产生一组状态,确定亮亮状态间的最大目标值差,然后根据差值,利用一定的函数确定初温,如:其中Pr为初始接受概率。(3)根据经验公式给出1.6循环终止准则内循环终止准则:(1)检验目标函数的均值是否稳定(2)连续若干步的目标值变化较小(3)按一定的步数进行抽样外循环终止准则(1)设置终止温度(2)设置外循环迭代次数(3)算法搜索到的最优值连续若干步保持不变(4)检验系统熵是否稳定Python实现过程:下面便通过python求解开头提到的问题,首先定义函数,然后通过pyplot看看函数在[0,100]上的大致图像:from__future__importdivisionimportnumpyasnpimportmatplotlib.pyplotaspltimportmath#defineaimfunctiondefaimFunction(x):y=x**3-60*x**2-4*x+6returnyx=[i/10foriinrange(1000)]y=[0foriinrange(1000)]foriinrange(1000):y[i]=aimFunction(x[i])plt.plot(x,y)可以看到最小值大概在40左右,通过求导计算得到最小值为40.033。接下来便构造SA模型:定义初温、低温阈值并通过随机得到初始x,同时定义时刻t。通过均匀分布构造邻域函数,同时设定内循环次数为50次,降温函数使用代码实现如下:T=1000#initiatetemperatureTmin=10#minimumvalueofterperaturex=np.random.uniform(low=0,high=100)#initiatexk=50#timesofinternalcirculationy=0#initiateresultt=0#timewhileT=Tmin:foriinrange(k):#calculateyy=aimFunction(x)#generateanewxintheneighboorhoodofxbytransformfunctionxNew=x+np.random.uniform(low=-0.055,high=0.055)*Tif(0=xNewandxNew=100):yNew=aimFunction(xNew)ifyNew-y0:x=xNewelse:#metropolisprinciplep=math.exp(-(yNew-y)/T)r=np.random.uniform(low=0,high=1)ifrp:x=xNewt+=1printtT=1000/(1+t)printx,aimFunction(x)经过循环输出x与y,结果如下:多次运行:可以看到SA算法很好的逼近了最优解。
本文标题:模拟退火算法介绍
链接地址:https://www.777doc.com/doc-4677246 .html