模拟退火算法
模拟退火算法 (Simulated Annealing Algorithm)是1983年发明的一种通用概率演算法, 用于在一个较大的搜寻空间内寻找问题的最优解.
模拟退火算法是一种基于概率的算法, 源于固体退火原理. 将固体充分加温, 再让其自然冷却, 加温时, 组成固体的粒子的无规则运动随升温而加剧, 内能增加, 而冷却时无规则运动趋于减弱, 渐趋有序. 在每个温度例子均达到平衡态, 最后在降低至室温时回到基态, 内能减为最小.
根据 Metropolis 准则, 粒子在温度 时趋于平衡的概率为 . 其中, 为温度 时的内能, 为粒子内能改变量, 为 常数.
模拟退火算法的伪代码如下:
/*
* E(y):在状态y时的评价函数值
* Y(i):表示当前状态
* Y(i+1):表示新状态
* r: 控制降温的快慢
* T: 系统的温度. 系统初始应处于高温的状态
* T_min :温度下限: 若温度T达到T_min,则停止搜索
*/
while( T > T_min )
{
dE = E( Y(i+1) ) - E( 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 ; //降温退火 ,0<r<1 。r越大,降温越慢;r越小,降温越快
/*
* 若r过大,则搜索到全局最优解的可能会较高,但搜索的过程也就较长。若r过小,则搜索的过程会很快,但最终可能会达到一个局部最优值
*/
i ++ ;
}
可见, 模拟退火算法新解的产生和接受可分为以下四个步骤;
- 由产生函数从当前解产生一个位于解空间内的新解.
- 计算原解和所得新解所对应的的目标函数差.
- 依据给定的接受准则判断新解是否被接受.
- 若确定接受新解, 则用新解代替当前解. 若新解被判定应当丢弃, 则在原当前解的基础上继续下一轮试验.
模拟退火算法和初始值无关, 算法所求得的解和初始解状态 (也就是算法迭代的起点) 无关. 模拟退火算法具有渐进收敛性, 已经在理论上被证明是一种以概率 收敛于全局最优解的全局优化算法, 具有并行性.
下面简要介绍 基于杂交的混合粒子群算法:
基于杂交的混合粒子群算法结构如下:
- 随即设定各个粒子的速度和位置.
- 评价每个粒子的适应度, 将其位置和适应值储存于粒子的个体极值 中, 将所有 中最优适应值的个体位置和适应值保存于全局极值 中.
- 确定初始温度.
- 根据以下函数计算当前温度下每个粒子
的适应值:
- 从全部
中确定全局最优的替代值
, 并根据下列公式更新各粒子的位置和速度:
- 计算粒子目标值并更新 和 , 并进行降温(退火)操作.
- 当算法达到停止条件时终止搜索, 并输出结果.
注:初始温度的设定和退温的方式对算法表现有一定影响. 一般地, 采用以下的初始温度和退温方式:
将实现自适应权重的优化函数命名为 PSO_lambda
,在 MATLAB 中编写实现上述功能的代码:
%实现自适应权重的粒子群优化算法
function [xm,fv] = PSO_lambda(fitness,N,c1,c2,lambda,M,D)
format long;
% 初始化群体个体数目
% c1: 学习因子1
% c2: 学习因子2
% lambda:退火常数惯性权重
% M: 最大迭代次数
% D: 搜索空间维度
%% 初始化种群个体
for i = 1:N
for j = 1:D
x(i,j) = randn; %初始化位置
v(i,j) = randn; %初始化速度
end
end
%%先计算每个粒子的适应度, 再初始化 pi 和 pg
for i = 1:N
p(i) = fitness(x(i,:));
y(i,:) = x(i,:);
end
pg = x(N,:);
for i = 1:(N-1)
if fitness(x(i,:)) < fitness(pg)
pg = x(i,:);
end
end
%% 主循环:依公式依次迭代
T = fitness(pg)/log(0.2);
for t = 1:M
groupFit = fitness(pg);
for i = 1:N
Tfit(i) = exp(-(p(i) - groupFit)/T);
end
SumTfit = sum(Tfit);
Tfit = Tfit / SumTfit;
pBet = rand();
for i = 1:N
ComFit(i) = sum(Tfit(1:i));
if pBet <= ComFit(i)
pg_plus = x(i,:);
break;
end
end
C = c1 + c2;
ksi = 2/abs(2 - C - sqrt(C^2 - 4*C));
for i = 1:N
v(i,:) = ksi * (v(i,:) + c1*rand*(y(i,:)-x(i,:)) + c2*rand*(pg_plus-x(i,:)));
x(i,:) = x(i.:) + v(i,:);
if fitness(x(i,:)) < p(i)
p(i) = fitness(x(i,:));
y(i,:) = x(i,:);
end
if p(i) < fitness(pg)
pg = y(i,:);
end
end
T = T*lambda;
Pbest(t) = fitness(pg);
end
xm =pg';
fv = fitness(pg);
[例]
使用基于模拟退火算法的混合粒子群算法, 求解函数:
的最小值, 其中
且要求设定:
- 粒子数为50
- 学习因子均为2
- 退火常数取值0.5
- 迭代步数设为100
[解]
建立函数代码如下:
function y = lambdaFunc(x)
y = 0;
for i = 1:5
y = y + (i + 2)/((x(i)-1)^2 + 0.5);
end
y = 1/(y + 0.7);
在MATLAB控制台窗口输入命令:
>> [xm,fv] = PSO_lambda(@lambdaFunc,50,2,2,0.5,100,5)
执行后得到结果:
xm =
0.904255302545747
-0.790580328308983
0.753913871240779
0.648556757842084
0.823886401649663
fv =
0.025383214023931
>>