一.什么是差分进化算法?
背景:
差分进化算法(Differential Evolution,DE)是一种新兴的进化计算算法,来源于1995年Storn等人为了求解切比雪夫多项式而提出。主要用于求解实数优化问题。
用途:
差分进化算法是一种随机的并行直接搜索算法,可以对非线性、可微、连续空间函数进行最小化,以其易用性、稳健性和强大的全局寻优能力在多个领域取得成功。
基本实现步骤:
首先在问题范围随机初始化种群操作,接着进行变异操作,交叉操作,选择操作后产生下一代种群,重复后面三个步骤,直到满足了停止条件(找到最优解或者达到迭代次数)。如以下流程图所示:
优点:
和其他进化算法相比,在非凸,多峰,非线性,连续不可微函数优化问题上表现出极强的稳定性,收敛速度快,在求解多维函数优化问题上有优势,容易实现。
缺陷:
算法后期收敛速度慢,容易陷入局部最优。过多次迭代才能搜索到全局最优。变异策略,缩放因子和交叉因子对算法的性能有着重要影响。
改进方向:
收敛速度上,不同问题使用不同变异策略/控制参数上等等。
二.DE的具体步骤
1.种群初始化
1.1个体:
是指种群中的单个元素,简单理解可以看做一个解向量。每个种群可以包含多个个体。
1.2种群:
来自遗传算法(GA)中的名词,是指用DE求解问题时,初始给定的多个解的集合。遗传算法的求解过程是从这个子集开始的。
1.3种群初始化步骤:
首先在问题的解空间中随机并且均匀地产生NP个个体,每个个体都是m维决策变量。 例如第0代种群有NP个个体,表示为:
第0代种群中第i个个体,每个个体有m维,表示为:
...... 由此可知,第t代种群的第i个个体表示为:
例如表格所示第0代种群各个个体:
初始化步骤:在m维空间中随机产生满足约束条件的NP个个体,所以第i个个体的第j维分量的取值为:
下标i=1,2,3,...,m ;下标j=1,2,3,...,NP
2.变异操作
种群变异操作有多种方法,这里采用DE/Rand/1方法进行详细介绍。当种群正进行第t次的迭代时,从当前的种群中随机的选取三个个体 ,而且需要使选取的三个个体下标与变异个体Vi下标互不相等,r1,r2,r3是从[1,NP]中随机选取互不相等的整数,即 。变异公式如下:
其中参数F为缩放因子,考虑到两个随机个体(如r1, r2和r3)之间的差分或方向信息。
是差分向量,差分向量越小,表示扰动值就越小,所以在算法的初始阶段,各个个体随机选取,彼此之间相差较大,所以扰动较大,差分向量大,生成变异个体的可变范围大,算法在一个较大的范围进行搜索;当算法的后期,各个个体之间都在最优个体周围,扰动值小,差分向量小,生成变异个体的可变范围小,算法在较小范围搜索。
变异方法表示DE/q/p,其中q表示被变异个体的选择方式,p 表示差分向量的个数。 其他的变异方法有:
DE/rand/1:
DE/best/1:
DE/current to best/1 :
DE/best/2:
DE/rand/2:
需要注意的是,Vi的各个维度范围可能会超出搜索范围,所以需要判断解的有效性,变异后个体每个维度是否都在各维度的上下边界之中,如果没有则重新生成那个维度的值,这里有三种重新生成方法:
第一种方法:当变异个体的某维度数值大于其最大范围或者小于最小范围时,利用下面公式重新赋值:
第二种方法:如果变异个体的某维度数值大于其最大范围,则重新赋值为最大值;如果小于最小范围时,则重新赋值为最小值,即将其保留在相应的边界内。
第三种方法:当变异个体的某维度数值大于其最大范围或者小于最小范围时,利用下面公式重新赋值:
3. 交叉操作
交叉操作可以增加种群的多样性,试验向量U的赋值公式为:
j是维度,属于1到m的正整数,jrand是在区间[1,m]随机选取的整数 是随机获取[0,1]之间的数;Cr为交叉概率,属于[0,1]范围。 此交叉式保证了试验向量Ui至少要从变异向量Vi中获得一个值(当j=jrand时),这样可以保证Ui与Vi和xi都不完全相同,从而保证种群多样性,避免种群个体之间的无效交叉。
4.选择操作
DE使用贪婪选择方法来执行选择操作,体现了大自然界物竞天择,优胜劣汰的思想。根据适应值从Xi(t)和试验向量Ui(t+1)中一对一地贪婪选择出更好的个体成为下一代的向量xi(t+1)。例如,对于最小优化问题,根据目标函数f选择Ui(t+1)或Xi(t)作为Xi(t+1):
5.小结
DE算符的搜索性能取决于算法全局探索和局部开发能力的平衡,而这在很大程度上依赖于算法的控制参数的选取,包括种群规模NP、缩放因子F和交叉概率Cr等。 种群规模NP:一般介于5m与10m之间,但不能少于4,否则变异算子无法进行; 缩放因子F:一般在[0,2]之间选择,通常取0.5; 交叉概率Cr:般在[0,1]之间选择,比较好的选择应在0.3左右。 Cr取值偏大,收敛速度会加快,但易过早收敛。 伪代码如下:
三.应用------在Matlab用DE实现求解多元函数最值
实现代码:
matlab
clear;
clc;
N=200;%N种群数
T=500;%T迭代次数
m=30;%m维度
F=0.5;%F收缩因子
Cr=0.5;%Cr交叉概率
L=-200;%下界范围
U=200;%上界范围
t=1;%迭代次数初始化
%种群初始化操作
initgroup=rand(N,m)*(U-L)+L;
%计算种群初代适应值
for i =1:N
fx(i)=sum(initgroup(i,:).^2);
end
%计算初代种群中N个个体的最优解
trace(t)=min(fx);
%迭代
for t=1:T
%第一代N个个体循环
for p=1:N
%取四个1到N的随机排列的数组成的向量返回给num;
num=randperm(N,4);
if num(1)==p
num(1)=num(4);
elseif num(2)==p
num(2)=num(4);
elseif num(3)==p
num(3)=num(4); %遵循num(1)不等于num(2)不等于num(3)不等于个体号p
end
%变异操作
v(p,:)=initgroup(num(1),:)+F*(initgroup(num(2),:)-initgroup(num(3),:));
%判断变异后的变异向量v中的每一维度是否越界
for j=1:m%维度m
if v(p,j)<L
x1=2*L-v(p,j);
v(p,j)=min(U,x1);
elseif v(p,j)>U
x2=2*U-v(p,j);
v(p,j)=max(L,x2);
end
end
%另一种对越界的变异向量v重新赋值的方法
% for j = 1:m
% if v(p,j)<L||v(p,j)>U
% v(p,j)=rand*(U-L)+L;
% end
% end
%交叉操作
rRand=randi([1,m],1,1); %从1到m中随机取一行一列个数=随机取一个
for r=1:m %维度j循环
if (rand<=Cr || r==rRand)
u(p,r)=v(p,r);
else
u(p,r)=initgroup(p,r);
end
end
%计算u个体的适应值
fu(p)=sum(u(p,:).^2);
end
%N个变异完成
%选择操作
% 选择父代和试验向量适应值好的作为下一代
for e=1:N
if fu(e)<=fx(e)
initgroup(e,:)=u(e,:);
end
end
%种群更新完成,重新计算f(x)适应值
for i=1:N
fx(i)=sum(initgroup(i,:).^2);
end
%记录每一代种群最优适应值
trace(t)=min(fx);
end
figure(1);
plot(trace);
xlabel('进化代数');
ylabel('适应值');
1.种群经过迭代500次的运行后,每一代的最优适应值如图所示:
由此分析可得,如果迭代次数足够,所得的最优适应值将无限趋近于问题函数的最小值0。
2.种群初始化时各个体的适应值如下图所示:
3.当迭代到180代时,种群中各个体的适应值如下图所示:
4.当迭代到280代时,种群中各个体的适应值如下图所示:
5.当迭代到380代时,种群中各个体的适应值如下图所示:
6.当迭代到480代时,种群中各个体的适应值: