0.起因
一切还要从一只蝙蝠说起。抱歉扯远了,寒假在家闲来无事,总结一下一路以来的学习,从差分进化算法开始填坑,也造福一下之后在演化计算道路上学习的学弟学妹们。DE主要是解决非线性不可微的连续函数,之后的算法也都是如此,通过跑CEC测试函数集来检验是不是一个能抓到耗子的好猫。
1.DE步骤
-
首先要说明一下,DE是一种利用 NP 个 D 维度 参数向量的并行搜索方法,以 NP=100,D=30举例,可以理解为有一群体,共有100个个体,每个个体是30维的,进行搜索。故这个群体就可以用一个100*30维的二维数组进行存储;
-
每个个体可表示为:X(i,g) ,i=1,2,3…NP ; g为代数(generation);
-
我们都知道DE是根据贪婪来选择个体的,也即:若新解优于旧解时,就接受。它通过将两个个体每个维度的向量差,乘以一个加权系数加在第三个个体上来形成新个体,这也就是差分的关键,也就是算法的Mutation步骤。在下面细讲。
1.1 初始化
随机生成一个群体,群体大小为NP,每个个体D维。对第i个个体的第j维度取值如下:
- xi,gj=xmin+rand(0,1)*(xmaxj-xminj)
1.2 变异
对每一个xi,g,生成变异个体vi,g+1:
- vi,g+1j = xr1,g + F * ( xr2,g - xr3,g )
其中,r1,r2,r3 是1~NP的随机数,且 r1 != r2 != r3 !=i ; F > 0 ;
xr2,g-xr3,g就是差分向量,F为缩放因子。
下图展示了通过一步步求取差分进行迭代从而达到最小值的过程。
1.3 交叉
交叉主要是为了增加种群的多样性,避免种群个体“近亲繁殖”,陷入局部最优,记交叉个体为ui,g:
-
u
i
,
g
=
{
v
i
,
g
rand<cr
x
i
,
g
else
u~i,g~= \begin{cases}v~i,g~ & \text{rand<cr}\\x~i,g~ & \text{else} \end{cases}
u i,g ={v i,g x i,g rand<crelse其中 cr 为交叉概率,cr越大,交叉概率越高。
1.4选择
贪婪地选取,若新个体好就替换旧个体,否则还保留旧个体。
- x i , g + 1 = { u i , g f(u i(g)) < f(x i(g)) x i , g else x~i,g+1~= \begin{cases}u~i,g~ & \text{f(u~i(g)) < f(x~i(g))}\\x~i,g~ & \text{else} \end{cases} x i,g+1 ={u i,g x i,g f(u i(g)) < f(x i(g))else
Just show me the code:
P.S 目标函数简单的设置为:x^2,求最小值
NP=100; %种群规模
D=10; %个体维度
Max_Gm=1000;
x_min=-100;
x_max=100;
uF = 0.4; %变异的控制参数
uCR = 0.1; %交叉的控制参数
x=zeros(NP,D); %初始个体
v=zeros(NP,D); %变异个体
u=zeros(NP,D); %交叉个体
%初始化
for i=1:NP
for j=1:D
x(i,j)=x_min+rand()*(x_max-x_min);
end
end
% 计算目标参数
for t=1:NP
f(t)=sum(x(t,:).^2); %f为1*NP的矩阵,用来存储每一个个体的适应值
end
best(1)=min(f); %best用来存储每一代的最优值
for Gm=1:Max_Gm
%变异
for m=1:NP
r1=randi(NP);
while(r1==m)
r1=randi(NP);
end
r2=randi(NP);
while(r1==r2||r2==m)
r2=randi(NP);
end
r3=randi(NP);
while(r1==r3||r2==r3||r3==m)
r3=randi(NP);
end
v(m,:)=x(r1,:)+uF*(x(r2,:)-x(r3,:));
end
%交叉(针对整个种群)
for n=1:D
if(rand()<=uCR || n==randi(D))
u(:,n)=v(:,n);
end
if(rand()>uCR && n~=randi(D))
u(:,n)=x(:,n);
end
end
%越界处理
for h=1:NP
for k=1:D
if(x(h,k)<x_min||x(h,k)>x_max)
x(h,k)=x_min+rand()*(x_max-x_min);
end
end
end
%选择
for i=1:NP
if(f(i)>=sum(u(i,:).^2))
x(i,:)=u(i,:);
else
x(i,:)=x(i,:);
end
end
%最终值
for i=1:NP
f(i)=sum(x(i,:).^2);
end
best(Gm)=min(f);
end
plot(best);
PPS写在最后:第一次使用Markdown编写博客,还没有上手,排版太丑,我尽量美化,还望大家多多包涵。