MATLAB数学建模:智能优化算法-模拟退火算法

模拟退火算法

模拟退火算法 (Simulated Annealing Algorithm)是1983年发明的一种通用概率演算法, 用于在一个较大的搜寻空间内寻找问题的最优解.

模拟退火算法是一种基于概率的算法, 源于固体退火原理. 将固体充分加温, 再让其自然冷却, 加温时, 组成固体的粒子的无规则运动随升温而加剧, 内能增加, 而冷却时无规则运动趋于减弱, 渐趋有序. 在每个温度例子均达到平衡态, 最后在降低至室温时回到基态, 内能减为最小.

根据 Metropolis 准则, 粒子在温度 T T 时趋于平衡的概率为 e Δ E K T e^{\frac{-\Delta E}{KT}} . 其中, E E 为温度 T T 时的内能, Δ E \Delta E 为粒子内能改变量, k k B o l t z m a n n Boltzmann 常数.

模拟退火算法的伪代码如下:

/*
* 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 ++ ;
}

可见, 模拟退火算法新解的产生和接受可分为以下四个步骤;

  1. 由产生函数从当前解产生一个位于解空间内的新解.
  2. 计算原解和所得新解所对应的的目标函数差.
  3. 依据给定的接受准则判断新解是否被接受.
  4. 若确定接受新解, 则用新解代替当前解. 若新解被判定应当丢弃, 则在原当前解的基础上继续下一轮试验.

模拟退火算法和初始值无关, 算法所求得的解和初始解状态 (也就是算法迭代的起点) 无关. 模拟退火算法具有渐进收敛性, 已经在理论上被证明是一种以概率 1 1 收敛于全局最优解的全局优化算法, 具有并行性.

下面简要介绍 基于杂交的混合粒子群算法:

基于杂交的混合粒子群算法结构如下:

  1. 随即设定各个粒子的速度和位置.
  2. 评价每个粒子的适应度, 将其位置和适应值储存于粒子的个体极值 p b e s t p_{best} 中, 将所有 p b e s t p_{best} 中最优适应值的个体位置和适应值保存于全局极值 g b e s t g_{best} 中.
  3. 确定初始温度.
  4. 根据以下函数计算当前温度下每个粒子 p i p_{i} 的适应值:
    T F ( p i ) = e ( f ( p i ) f ( p g ) ) t i = 1 N e ( f ( p i ) f ( p g ) ) t TF(p_{i}) = \frac{e^{\frac{-(f(p_{i})-f(p_{g}))}{t}}}{\sum_{i= 1}^{N}e^{\frac{-(f(p_{i})-f(p_{g}))}{t}}}
  5. 从全部 p i p_{i} 中确定全局最优的替代值 p i p_{i}' , 并根据下列公式更新各粒子的位置和速度:
    x i , j ( t + 1 ) = x i , j ( t ) + v i , j ( t + 1 ) ,     j = 1 , 2 , , d x_{i,j}(t+1) = x_{i,j}(t) + v_{i,j}(t+1), \ \ \ j = 1,2,\cdots, d
    v i , j ( t + 1 ) = ϕ { v i , j ( t ) + c 1 r 1 [ p i , j x i , j ( t ) ] + c 2 r 2 [ p g , j x i , j ( t ) ] } v_{i,j}(t+1) = \phi\{ v_{i,j}(t) + c_{1}r_{1}[p_{i,j}-x_{i,j}(t)] + c_{2}r_{2}[p_{g,j} - x_{i,j}(t)]\}
    ϕ = 2 2 ( c 1 + c 2 ) ( c 1 + c 2 ) 2 4 ( c 1 + c 2 ) \phi = \frac{2}{2-(c_{1} + c_{2}) - \sqrt{(c_{1} + c_{2})^{2} - 4(c_{1} + c_{2})}}
  6. 计算粒子目标值并更新 p b e s t p_{best} g b e s t g_{best} , 并进行降温(退火)操作.
  7. 当算法达到停止条件时终止搜索, 并输出结果.

注:初始温度的设定和退温的方式对算法表现有一定影响. 一般地, 采用以下的初始温度和退温方式:
t 0 = f ( p g ) l n 5 t_{0} = \frac{f(p_{g})}{ln5}
t k + 1 = λ t k t_{k+1} = \lambda*t_{k}

将实现自适应权重的优化函数命名为 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);
    

[例]

使用基于模拟退火算法的混合粒子群算法, 求解函数:
f ( x ) = 1 0.7 + i = 1 5 i + 2 ( x i 1 ) 2 + 0.5 f(x) = \frac{1}{0.7 + \sum_{i=1}^{5}\frac{i+2}{(x_{i} -1)^{2} + 0.5}}
的最小值, 其中 10 x 10. -10 \leqslant x \leqslant 10. 且要求设定:

  1. 粒子数为50
  2. 学习因子均为2
  3. 退火常数取值0.5
  4. 迭代步数设为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

>> 
发布了32 篇原创文章 · 获赞 14 · 访问量 6355

猜你喜欢

转载自blog.csdn.net/u010186354/article/details/104224423