在许多实际优化问题中,存在许多局部最优解,随着优化问题规模的增大,局部最优解的数量快速增加。
寻找全局最优解可分为两类:
1.确定性方法,常用于求解有一些特殊特征的问题
2.随机搜索方法,(梯度下降法)则沿着目标函数下降的方法搜索,但是常常会陷入局部最小值,而非全局最优解。
模拟退火算法是一种通用概率算法,用来在一个大的搜寻空间内寻找问题的最优解。美国物理学家 N.Metropolis 和同仁在1953年发表研究复杂系统、计算其中能量分布的文章,他们使用蒙特卡罗模拟法计算多分子系统中分子的能量分布。现代模拟退火算法形成于20世纪80年代初,在热力学上,退火(annealing)现象指物体逐渐降温的物理现象,温度愈低,物体的能量状态会低;够低后,液体开始冷凝与结晶,在结晶状态时,系统的能量状态最低。大自然在缓慢降温(亦即,退火)时,可“找到”最低能量状态:结晶。但是,如果过程过急过快,快速降温(亦称「淬炼」,quenching)时,会导致不是最低能态的非晶形。
模拟退火算法(Simulated Annealing,简称SA)的思想最早是由Metropolis等提出的。其出发点是基于物理中固体物质的退火过程与一般的组合优化问题之间的相似性。模拟退火法是一种通用的优化算法,其物理退火过程由以下三部分组成:
1.加温过程。其目的是增强粒子的热运动,使其偏离平衡位置。当温度足够高时,固体将熔为液体,从而消除系统原先存在的非均匀状态。
2.等温过程。对于与周围环境交换热量而温度不变的封闭系统,系统状态的自发变化总是朝自由能减少的方向进行的,当自由能达到最小时,系统达到平衡状态。
3.冷却过程。使粒子热运动减弱,系统能量下降,得到晶体结构。
加温过程相当于对算法设定初值,等温过程对应算法的Metropolis抽样过程,冷却过程对应控制参数的下降。这里能量的变化就是目标函数,我们要得到的最优解就是能量最低态。其中Metropolis准则是SA算法收敛于全局最优解的关键所在,Metropolis准则以一定的概率接受恶化解,这样就使算法跳离局部最优的陷阱。
SA算法的Metropolis准则允许接受一定的恶化解,具体来讲,是以一定概率来接受非最优解。举个例子,相当于保留一些“潜力股”,使解空间里有更多的可能性。对比轮盘赌法,从概率论来讲,它是对非最优解给予概率0,即全部抛弃。
退火过程由一组初始参数,即冷却进度表控制,它的核心是尽量使系统达到准平衡,以使算法在有限的时间逼近最优解,冷却进度表包括;
1.初始值T0 冷却开始的温度
2.T的衰减函数 离散和连续的转化
3.T的终止值 Tf
4.Markov链的长度Lk:任意温度的迭代次数
算法特点
• 与遗传算法、粒子群优化算法和蚁群算法等不同,模拟退火算法不属于群优化算法,不需要初始化种群操作。• 收敛速度较慢。因为1)它初始温度一般设定得很高,而终止温度设定得低,这样才符合物体规律,认为物质处于最低能量平衡点;2)它接受恶化解,并不是全程都在收敛的过程中。这一点可以类比GA中的变异,使得它不是持续在收敛的,所以耗时更多一些。
• 温度管理(起始、终止温度)、退火速度(衰减函数)等对寻优结果均有影响。比如T的衰减速度如果太快,就会导致可能寻找不到全局最优解。
算法步骤:
1.初始化:取初始温度T0足够大,令T = T0,任取初始解S1。
2.对比GA、ACA、PSO之类的群优化算法,需要在解空间中产生多个个体,再继续寻优。而SA算法只需要一个点即可。
对当前温度T,重复第(3)~(6)步。3.对当前解S1随机扰动产生一个新解S2。
此处随机的扰动没有定义。结合实际例子做选择。
4.计算S2的增量df = f(S2) - f(S1),其中f(S1)为S1的代价函数。5.代价函数相当于之前群优化算法中讲的适应度函数。
若df < 0,则接受S2作为新的当前解,即S1 = S2;否则,计算S2的接受概率exp(-df/T), T是温度。随机产生(0,1)区间上均匀分布的随机数rand,若exp(-df/T) > rand,也接受S2作为新的当前解S1 = S2,否则保留当前解S1。这是SA算法的核心部分,即有一定概率接受非最优解。
6.如果满足终止条件Stop,则输出当前解S1为最优解,结束程序,终止条件Stop通常取为在连续若干个Metropolis链中新解S2都没有被接受时终止算法或者是设定结束温度。否则按衰减函数衰减T后返回第(2)步,即被接受的新的解一直在产生,则我们要对问题进行降温,使得非最优解被接受的可能不断降低,结果愈发收敛于最优解。
算法说明:
(1)状态表达
前面已经提到过,SA算法中优化问题的一个解模拟了(或者说可以想象为)退火过程中 固体内部的一种粒子分布情况。这里状态表达即指:实际问题的解(即状态)如何以一种合适 的数学形式被表达出来,它应当适用于 SA的求解,又能充分表达实际问题,这需要仔细地设计。可以参考遗传算法和禁忌搜索中编码的相关内容。 常见的表达方式有背包问题和指派问题的0-1编码、TSP问题和调度问题的自然数编码,还有用于连续函数优化的实数编码等。
(2)新解的产生
新解产生机制的基本要求是能够尽量遍及解空间的各个区域,这样,在某一恒定温度不断产生新解时,就可能跳出当前区域以搜索其他区域 这是模拟退火算法能够进行广域搜索的
个重要条件。
(3)收敛的一般性条件
收敛到全局最优的一般性条件是:
1初始温度足够高;
2热平衡时间足够长;
3终止温度足够低;
4降温过程足够缓慢。
但上述条件在应用中很难同时满足。
(4)参数的选择
1)控制参数T的初值T。
求解全局优化问题的随机搜索算法一般都采用大范围的粗略搜索与局部的精细搜索相结合的搜索策略。只有在初始的大范围搜索阶段找到全局最优解所在的区域,才能逐渐缩小搜索的范围,最终求出全局最优解。模拟退火算法是通过控制参数T的初值T。及其衰减变化 过程来实现大范围的粗略搜索与局部的精细搜索的。一般来说,只有足够大的 T。才能满足 算法要求(但对不同题,“足够大”的含义也不同,有的可能 T0=100 就可以有的则要1010)。在问题规模较大时,过小的T.往往导致算法难以跳出局部陷阱而达不到全局最优。但为了减少计算量T0不宜取得过大,而应与其他参数折中选取。
2)控制参数T的衰减函数
衰减函数可以有多种形式,一个常用的衰减函数是:
Tk+1=aT,(k=0,1,2,...)
其中,a是一个常数,可以取为0.5~0.99,它的取值决定了降温的过程。小的衰减量可能导致算法进程迭代次数的增加,从而使算法进程接受更多的变换,访问更 多的邻域,搜索更大范围的解空间,返回更好的最终解。 同时,由于在T, 值上已经达到准平
衡,所以在T+,时只需少量的变换就可达到准平衡。 这样就可选取较短长度的Markov 链来 减少算法时间。
3)Markov链长度
Markov 链长度的选取原则:在控制参数T的衰减函数已选定的前提下,L,应能使在控 制参数T的每一取值上达到准平衡。从经验上说,对于简单的情况,可以令L:=100n,n为问题规模。
(5)算法停止准则
对Metropolis 准则中的接受函数exp[-(Ej - Ki) / k * t]进行分析可知,在T比较大的高温情 况,指数上的分母比较大,而这是一个负指数,所以整个接受函数可能会趋于1,即比当前解x;更差的新解z,也可能被接受;因此就有可能跳出局部极小而进行广域搜索,去搜索解空间的其他区域。而随着冷却的进行,T减小到一个比较小的值时,接受函数分母小了,整体也小 了,即难以接受比当前解更差的解,也就是不太容易跳出当前的区域。如果在高温时已经进行了充分的广域搜索,找到了可能存在的最好解的区域,而在低温再进行足够的局部搜索,则可 能最终找到全局最优了。 因此,一般T,设为一个足够小的正数,比如0.01~5,但这只是一个粗糙的经验,更精细 的设置及其他的终止准则需要根据具体的问题做进一步的研究后再设定
与学习GA算法相同想来尝试使用matlab全局优化求解器,来寻找一元函数一元函数:x = [1,2]范围内 y = sin(10*pi*x) / x 的极值
首先可以数据可视化 画出函数图像 并且通过已有的算法获得在全局上的最大值和最小值
%% I. 清空环境变量
clear all
clc
%% II. 一元函数优化
x = 1:0.01:2;
y = sin(10*pi*x) ./ x;
figure
plot(x,y,'linewidth',1.5)
ylim([-1.5, 1.5])
xlabel('x')
ylabel('y')
title('y = sin(10*pi*x) / x')
hold on
%%
% 1. 标记出最大值点
[maxVal,maxIndex] = max(y);
plot(x(maxIndex), maxVal, 'r*','linewidth',2)
text(x(maxIndex), maxVal, {[' X: ' num2str(x(maxIndex))];[' Y: ' num2str(maxVal)]})
hold on
%%
% 2. 标记出最小值点
[minVal,minIndex] = min(y);
plot(x(minIndex), minVal, 'ks','linewidth',2)
text(x(minIndex), minVal, {[' X: ' num2str(x(minIndex))];[' Y: ' num2str(minVal)]})
设定目标函数:
function fitnessVal = fitness( x )
fitnessVal = sin(10*pi*x) / x;
end
使用自带的库函数simulannealbnd()求解最小值 最大值只需要将目标函数取相反数或者倒数即可:
fun = @fitness;
x0 = [1 0];
lb = [1];
ub = [2];
x = simulannealbnd(fun,x0,lb,ub)
更多关于simulannealbnd库函数可以看 https://ww2.mathworks.cn/help/gads/simulannealbnd.html?searchHighlight=simulannealbnd&s_tid=doc_srchtitle