一、模拟退火算法基本思想
模拟退火算法的基本原理是模拟固体退火过程中总是从能量高的状态向着能量最低的平衡态转换的思想来寻找最优解,其通过一个冷却温度表来控制这个过程,同时在每一个温度下设计解的随机游走并以一定概率接收差的解,而且随着能量的降低,接收差的解的概率也显著降低,从而使得在高能量状态具有逃离局部最优解,在低能量状态具有收敛全局最优解的能力。
固体退火过程与优化问题求解的对应如下
能量高,粒子热运动活跃 | 高温 | 目标函数大,解随机游动最大 | ||
固体退火 | 系统趋于平衡态,能量达到最小 | ↓ | 解随机游动,趋向目标函数最小 | 问题寻优 |
能量最低,粒子热运动最弱,系统稳定 | 低温 | 目标函数最小,解随机游动最小 |
二、模拟退火新解接收模型
模拟退火算法中以一定概率接收差解的数学模型基于Metropolis准则,其描述如下。
假设固体中当前所有粒子的状态用状态i表示,该状态的能量为Ei,现给固体中粒子施加随机扰动得到一个新的状态j,该状态能量为Ej,则固体从状态i转变到状态j的接收概率为:
其中b为波兹曼常数,T为温度。
Metropolis准则说明,若新状态的能量变小,则接收,若新状态能量变大,则以一定概率接收,即以一定概率接收差的状态。
若能量变化量相同,则温度越高,系统接收差的状态概率越大,反映出系统越活跃,反之,温度越低,系统越稳定。
若温度相同,则能量改变量越大,系统接收差的状态概率越小。若温度无限大,则系统以近似1概率接收一切状态。
若温度为0,则系统不接受任何差的状态。
采用Metropolis准则的模拟退火过程和物理退火过程的对应如下。
模拟退火 | 物理退火 |
解 | 粒子的状态 |
最优解 | 能量最低的粒子状态 |
目标或评价函数 | 能量 |
初态(初温、初始解) | 退火初始状态 |
邻近解 | 转换状态 |
Metropolis采样过程 | 等温过程 |
控制参数下降 | 温度降低,冷却 |
四、算法运行的三个关键问题
1、温度下降方式
(1)指数衰减方式:T(t+1)=ɑT(t), ɑ取0.8-0.99
2、新解产生方式
(1) 选择当前解的一个邻域,以一定的概率分布(如均匀、正态、指数分布等)随机采样来产生新解;
(2) 在当前解的基础上进行随机扰动;
(3) 采用对解编码的方式(类似遗传算法)通过对变换后的解进行处理来获得新解。
3、算法中的参数设置
算法种的参数包括初始温度、内部蒙特卡罗循环迭代次数、内循环和外循环的终止条件等。
五、模拟退火算法的MATLAB实现
以求解在区间[-6,6]上的最小值为例,基于模拟退火算法的MALTAB代码如下
clear
clc
close all
%%
num = 1; %变量个数
bound = [-6,6]; %变量范围
temperature = 1000; %初始温度
alpha = 0.99; %温度衰减系数
iter = 100; %内部蒙特卡罗循环迭代次数
stop_t = 0.001; %停止迭代温度
%%
%随机生成初始粒子温度并计算能量
position = zeros(num,1);
for n = 1:num
position(n,1) = (bound(n,2)-bound(n,1))*rand + bound(n,1);
end
counter = 1;
energy(counter,1) = energysolver(position);
%%
while temperature > stop_t %外循环
for n = 1:iter %内循环
enegy1 = energysolver(position);
temp_pos = disturb(position,bound);
enegy2 = energysolver(temp_pos);
%确定是否接收新解
delta_e = enegy2 - enegy1;
if delta_e < 0
position = temp_pos;
else
if exp(-delta_e/temperature) > rand
%以一定概率接收差解
position = temp_pos;
end
end
end
counter = counter + 1;
energy(counter,1) = energysolver(position);
temperature=alpha*temperature;
end
其中,energysolver函数和disturb函数如下
function [energy] = energysolver(position)
energy = position^2*sin(position) + 2*cos(position);
end
function [new_pos] = disturb(position,bound)
delta1 = (bound(:,1) - position(:,1))/2;
delta2 = (bound(:,2) - position(:,1))/2;
len = size(position,1);
new_pos = (position(:,1) + delta1) + rand(len,1).*(delta2-delta1);
end
最终算法求出的最优位置为5.0385,最小能量为-23.4078。即函数在5.0385处取得最小值-23.4078。
注:本文参考国防科大王丹老师的数学建模课程的教学课件。