差分进化算法 是一种随机的启发式搜索算法,具有较强的鲁棒性和全局寻优能力。
1.算法过程
1.1 初始化
差分进化算法利用NP个个体,每个个体维度为D的实数值参数向量,将它们作为每一代种群,每个个体表示为:

其中i表示个体在种群是的位置,G表示迭代次数,NP为种群大小。一般情况下种群规模越大,多样性越好,寻优能力就越好,但计算强度也越大。通常,NP一般选择在
之间。
假设所有随机初始化种群均符合均匀概率分布。如果参数变量
,可以得到

其中
.
1.2. 变异操作
对以上每个目标向量,标准差分进化算法的变异向量是由下式得到的

其中随机选择种群中的个体位号
是各不相同的,并且它们也不是第i个个体,所以NP最少需要4个个体,变异算子
是一个实常数,用于控制偏差变量的缩放程度。一般情况,
通常作为初始变异算子,如果算法过早收敛,则需要增大F或种群规模。
1.3. 交叉操作
为了增加干扰参数向量的多样性,引入交叉操作,则试验向量可以表示为

通过以下式子获取试验向量元素值:

其中,randb(j)表示随机产生[0,1]之间的随机数(随机生成第j个元素被选择为v的概率),
为一个随机选择的序列,主要用于保证
至少从v获得1个元素,cr表示交叉算子,取值为[0,1]。它控制着一个试验向量参数来自随机选择的变异向量而不是原来向量的概率,所以cr越大表明交叉概率越大,一般情况选择0.1,但较大cr会加速算法收敛,需要根据情况调节。
1.4 选择操作
生成的试验向量
是否会成为下一代种群中的个体还需要进一步选择。差分进化算法主要利用贪婪准则进行选择,即将该试验向量与当前种群中的目标向量
进行比较,哪一个向量得到的目标函数值,则该向量便会添加到下一代种群之中,也就是说下一代的种群中的个体比当前种群的对应个体得到的目标函数值更好或者至少一样好。(注意:在选择中,试验向量只与当前种群中的一个个体进行比较,而不是与所有个体相比。)
1.5 边界条件处理
在处理有边界约束的问题时,必须保证产生的新个体的所有元素值都位于问题的可行域,所以在差分进化中,对于不符合边界约束的个体用在可行域中随机产生的参数向量代替,即:

另外,也有其它处理方法,比如进行边界吸引处理(将超过边界约束的个体值设置为临近边界的值)
1.6 算法流程图示

2. 自适应差分进化算法
以上基本的差分进化算法 在搜索过程中变异算子取实常数,而在实际中变异算子较难确定,变异算子太大会导致算法效率低下,所求得的全局最优解精度低,变异算子太小会导致种群多样性变低,容易出现“早熟”现象。因此需要进一步设计具有自适应性的变异算子,根据算法搜索进展情况,自适应变异算子可以设计为

其中,
表示变异算子,
表示最大进化次数,
表示当前迭代次数。在算法开始时,自适应变异算子为
,值 比较大,可以在初期迭代时保持个体的多样性,随着算法进么,变异算子逐渐变小,保留优良个体,增加搜索到全局最优解的概率。
3. 算法实例
3.1 实例1
实例要求:计算函数
的最小值,其中
,个体维度
。
算法实现
%%%%%%%%%%%%%%%%%差分进化算法求函数极值%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
NP=100; %个体数目
D=10; %变量的维数
G=200; %最大进化代数
F0=0.4; %初始变异算子
CR=0.1; %交叉算子
x_max=20; %上限
x_min=-20; %下限
yz=10^-6; %阈值
%%%%%%%%%%%%%%%%%%%%%%%%%赋初值%%%%%%%%%%%%%%%%%%%%%%%%
x=zeros(D,NP); %初始种群
v=zeros(D,NP); %变异种群
u=zeros(D,NP); %选择种群
x=rand(D,NP)*(x_max-x_min)+x_min; %初始种群
%%%%%%%%%%%%%%%%%%%%计算目标函数%%%%%%%%%%%%%%%%%%%%
for m=1:NP
Ob(m)=sum(x(:,m).^2);
end
optimal_obj(1)=min(Ob);
%%%%%%%%%%%%%%%%%%%%%%%差分进化循环%%%%%%%%%%%%%%%%%%%%%
for gen=1:G
%%%%%%%%%%%%%%%%%%%%%%变异操作%%%%%%%%%%%%%%%%%%%%%%
rho=exp(1-G/(G+1-gen)); %自适应变异算子
F=F0*2^(rho);
%%%%%%%%%%%%%%%%%r1,r2,r3和m互不相同%%%%%%%%%%%%%%%%
for m=1:NP
t1=randi([1,NP],1,1);
t2=randi([1,NP],1,1);
t3=randi([1,NP],1,1);
while (t1==m)
t1=randi([1,NP],1,1);
end
while 1
if t1==m
t1=randi([1,NP],1,1);
elseif t1==t2||t2==m
t2=randi([1,NP],1,1);
elseif t3==m||t3==t1|t3==t2
t3=randi([1,NP],1,1);
else
break;
end
end
v(:,m)=x(:,t1)+F*(x(:,t2)-x(:,t3));
end
%%%%%%%%%%%%%%%%%%%%%%交叉操作%%%%%%%%%%%%%%%%%%%%%%%
r=randi([1,D],1,1);
for n=1:D
cr=rand(1);
if (cr<=CR)||(n==r)
u(n,:)=v(n,:);
else
u(n,:)=x(n,:);
end
end
%%%%%%%%%%%%%%%%%%%边界条件的处理%%%%%%%%%%%%%%%%%%%%%
for n=1:D
for m=1:NP
if (u(n,m)<x_min)||(u(n,m)>x_max)
u(n,m)=rand*(x_max-x_min)+x_min;
end
% if u(n,m)<x_min
% u(n,m)=x_min+0.1;
% end
% if u(n,m)>x_max
% u(n,m)=x_max-0.1;
% end
end
end
%%%%%%%%%%%%%%%%%%%%%%选择操作%%%%%%%%%%%%%%%%%%%%%%%
for m=1:NP
Ob1(m)=sum(u(:,m).^2);
end
for m=1:NP
if Ob1(m)<Ob(m)
x(:,m)=u(:,m);
end
end
for m=1:NP
Ob(m)=sum(x(:,m).^2);
end
optimal_obj(gen+1)=min(Ob);
if min(Ob(m))<yz
break
end
end
[SortOb,Index]=sort(Ob);
x=x(:,Index);
X=x(:,1); %最优变量
Y=min(Ob); %最优值
%%%%%%%%%%%%%%%%%%%%%%%%%画图%%%%%%%%%%%%%%%%%%%%%%%%%%
figure
plot(optimal_obj);
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
收敛结果

3.2 实例2
实例要求:求函数
,x和y的取值范围为[-4,4],该函数的图形如下图

可以看到该函数有多个极小值。但可以利用差分优化进行求解,具体实现如下:
%%%%%%%%%%%%%%%%%差分进化算法求函数极值%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
NP=100; %个体数目
D=2; %变量的维数
G=200; %最大进化代数
F0=0.4; %初始变异算子
CR=0.1; %交叉算子
x_max=4; %上限
x_min=-4; %下限
yz=10^-6; %阈值
%%%%%%%%%%%%%%%%%%%%%%%%%赋初值%%%%%%%%%%%%%%%%%%%%%%%%
x=zeros(D,NP); %初始种群
v=zeros(D,NP); %变异种群
u=zeros(D,NP); %选择种群
x=rand(D,NP)*(x_max-x_min)+x_min; %初始种群
%%%%%%%%%%%%%%%%%%%%计算目标函数%%%%%%%%%%%%%%%%%%%%
for m=1:NP
Ob(m)=3*cos(x(1)*x(2))+x(1)^2+x(2)^2;
end
optimal_obj(1)=min(Ob);
%%%%%%%%%%%%%%%%%%%%%%%差分进化循环%%%%%%%%%%%%%%%%%%%%%
for gen=1:G
%%%%%%%%%%%%%%%%%%%%%%变异操作%%%%%%%%%%%%%%%%%%%%%%
rho=exp(1-G/(G+1-gen)); %自适应变异算子
F=F0*2^(rho);
%%%%%%%%%%%%%%%%%r1,r2,r3和m互不相同%%%%%%%%%%%%%%%%
for m=1:NP
t1=randi([1,NP],1,1);
t2=randi([1,NP],1,1);
t3=randi([1,NP],1,1);
while (t1==m)
t1=randi([1,NP],1,1);
end
while 1
if t1==m
t1=randi([1,NP],1,1);
elseif t1==t2||t2==m
t2=randi([1,NP],1,1);
elseif t3==m||t3==t1|t3==t2
t3=randi([1,NP],1,1);
else
break;
end
end
v(:,m)=x(:,t1)+F*(x(:,t2)-x(:,t3));
end
%%%%%%%%%%%%%%%%%%%%%%交叉操作%%%%%%%%%%%%%%%%%%%%%%%
r=randi([1,D],1,1);
for n=1:D
cr=rand(1);
if (cr<=CR)||(n==r)
u(n,:)=v(n,:);
else
u(n,:)=x(n,:);
end
end
%%%%%%%%%%%%%%%%%%%边界条件的处理%%%%%%%%%%%%%%%%%%%%%
for n=1:D
for m=1:NP
% if (u(n,m)<x_min)||(u(n,m)>x_max)
% u(n,m)=rand*(x_max-x_min)+x_min;
% end
if u(n,m)<x_min
u(n,m)=x_min+0.1;
end
if u(n,m)>x_max
u(n,m)=x_max-0.1;
end
end
end
%%%%%%%%%%%%%%%%%%%%%%选择操作%%%%%%%%%%%%%%%%%%%%%%%
for m=1:NP
Ob1(m)=3*cos(u(1)*x(2))+u(1)^2+u(2)^2;
end
for m=1:NP
if Ob1(m)<Ob(m)
x(:,m)=u(:,m);
end
end
for m=1:NP
Ob(m)=3*cos(x(1)*x(2))+x(1)^2+x(2)^2;
end
optimal_obj(gen+1)=min(Ob);
if min(Ob(m))<yz
break
end
end
[SortOb,Index]=sort(Ob);
x=x(:,Index);
X=x(:,1); %最优变量
Y=min(Ob); %最优值
%%%%%%%%%%%%%%%%%%%%%%%%%画图%%%%%%%%%%%%%%%%%%%%%%%%%%
disp(X);
plot(optimal_obj);
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
实验结果

最优值x= 0.0822, y=0.0313.
4. 拓展
在实验中发现多次实验的结果有所偏差,如何有效解决结果在每次运行后的偏差需要进一步学习和研究,有大神知道的话可以留言。


