变异系数法matlab程序,差分进化算法原理及matlab代码实现

差分进化算法介绍:

在自然界中,遗传,变异,选择的作用,使得生物体优胜略汰,不断由低级向高级进化,人们发现适者生存这一规律可以模式化,从而构成一些列优化算法。差分进化算法就是从这种模式中产生的一种智能优化算法。差分进化算法是基于群体只能理论的优化算法,与进化算法相比,保留了基于种群的全局搜索策略,采用实数编码,基于差分的简单变异操作操作和“一对一”的竞争生存策略。降低了操作的复杂性,差分进化算法特有的记忆能力使其可以动态的跟踪当前的搜索情况,以调整其搜索策略,具有较强的收敛能力和稳健性,且不需要借助问题的特侦信息。

算法流程:

1. 初始化:(与遗传算法类似)

种群中的个体可以表示为:(种群大小为NP)

8a81223680e72d7a8417c04ffc4537f4.png

其中: i=1,2,....NP

初始种群一般在给定的约束边界内随机生成

2. 变异

对于种群中每个个体

73d1961a20c5ed8eaae34e1e187b50c1.png,差分进化算法的变异向量按照下面的方式产生:

3812ca9b718aa2d6fcabb77aba9b2db3.png

其中:

ffab3228f74aedf386395214cef190b5.png在种群中随机选择且

d8f6eea76ead0468dd6601e77b9ccb84.png,参数

7970004fa118f65c2d9b28d365d08e42.png,用于控制偏差的放大作用。

除此之外,偏差向量还可以由其他的方式产生:表示方法:DE/x/y/z,  x当前被变异的向量是随机的还是最优的,y差向量的个数,z交叉程序的操作方法(bin)

DE/best/1/bin:

6593f2a64debf4703df32934cb85817e.png

DE/rand-to-best/1/bin:

6c608656c3d21faef195faeb19853720.png

DE/best/2/bin:

87c22878a6ea7f9ab24dc6467e76afc5.png

DE/rand/2/bin:

92885761ba0cb956c3d6d7119c565d5d.png

3. 交叉

13aeed1bcd439e8dadfc8dae2c82801f.png

这里的交叉和遗传算法的交叉操作有所区别,这里的交叉操作是针对整个种群的某一维度,而遗传算法中的交叉是针对种群中的每一个个体。

4.选择:

差分进化算法按照贪婪准则,从实验种群u中选择个体作为下一代种群x中的个体,具体的选择方式是:

5f5e83cdb72414e07be7a37f1381ce6b.png

其中:fit(x)为x的适应度。

5. 边界条件处理:

对于这一类的算法,通常会对种群中的个体执行一些列的操作(如交叉,变异),这会导种群中个体的范围(即决策变量的范围)超出给定的范围,所以需要对上述操作后所得到种群进行边界条件检查和处理,对于边界之外的个体一般有两种处理方法:

1. 边界吸收:

假设x的范围是x_max, x_min,  x'是经过变异或者交叉操作后所得的新的个体:则新个体的边界检查和处理规则为:

9238e1094a0ef1eaa72572318615fd6a.png

2. 重新随机生成新的个体:

2c57271928bff59cd53f2c3c7d31b3c7.png

基本差分进化算法的流程:

b497acfdc56130729f0a106434a163b3.png

算法中的参数:

1. 种群大小NP

2. 变异算子F ,

一般取[0,2],决定偏差向量的放大比例。F过小,造成算法早熟,F过大,导致算法的收敛性变差

3.交叉算子CR

4. 进化代数G

5.终止条件

matlab代码实现:

测试函数为:

c31d201c246008363408d0b0b7e55d56.png

取n=10,决策变量的范围为[-20,20]

close all;

clear all;

clc;

NP=50;

D=10; % 染色体长度

G=200;

F0=0.4;

CR=0.1;

a=-20; % 寻优区间

b=20;

yz=10^-6;

x=zeros(NP,D); % 初始种群

v=zeros(NP,D); % 变异种群

u=zeros(NP,D); % 选择种群

% 种群怫初值

x=rand(NP,D)*(b-a)+a;

% 计算目标参数

for i=1:1:NP

ob(i)=sum(x(i,:).^2);

end

trace(1)=min(ob);

% 差分进化循环

for gen=1:G

% 变异操作

for m=1:NP

r1=randi([1,NP],1,1);

while(r1==m)

r1=randi([1,NP],1,1);

end

r2=randi([1,NP],1,1);

while(r2==r1)||(r2==m)

r2=randi([1,NP],1,1);

end

r3=randi([1,NP],1,1);

while(r3==m)||(r3==r2)||(r3==r1)

r3=randi([1,NP],1,1);

end

% 产生不同的r1,r2,r3

v(m,:)=x(r1,:)+F0*(x(r2,:)-x(r3,:));

end

% 交叉操作

r=randi([1,D],1,1); % 这个变异是针对整个种群的变异,不正对单个个体

for n=1:D

cr=rand;

if (cr<=CR)||(n==r)

u(:,n)=v(:,n);

else

u(:,n)=x(:,n);

end

end

% 边界条件处理

for m=1:NP

for n=1:D

if u(m,n)b

u(m,n)=b;

end

end

end

% 自然选择

% 计算新的适应度

for m=1:NP

ob_1(m)=sum(u(m,:).^2);

end

for m=1:NP

if ob_1(m)

寻优结果:

2ed0517f87028f4165975bd31a66661a.png

差分进化算法的该改进:

自适应差分进化算法:

差分进化算法的变异系数F的确定:在实际的应用中,若果F取为常数,F过大,则会导致算法的收敛速度变慢,求得的全局最优解精度降低,F过小,会导致种群的多样性降低,出现早熟,所以可以将参数F设置为一个随着迭代次数变化的值,在迭代初期的时候,F较大,可以保持种群的多样性,随着迭代次数的增加,F减小,能够保存优良的种群信息,避免破坏最优解。

自适应算子如下所示:

016e4abedfcf9cf27db53a63cf62d7b0.png

其中Gm表示最大迭代次数,G表示当前迭代次数

变异系数F表示为:

18d433bc28d53d39ecfdddfba97d532d.png

改进的差分进化算法:

clear all;

close all;

clc;

NP=40; % 种群大小

G=100; % 迭代次数

D=2; % 决策变量个数

F0=0.3; % 初始的变异系数

CR=0.5*(1+rand());

X_min=-100;

X_max=100;

% 偏差向量的生成方式

DE_vector = 4;

% DE_vector=1,2,3,4,0

% DE_vector=0 表示DE/best/1/bin

% DE_vector=1 表示DE/best/1/bin

% DE_vector=2 表示DE/rand-to-best/1/bin

% DE_vector=3 表示DE/best/2/bin

% DE_vector=4 表示DE/rand/2/bin

mode = 'Schaffer'; % 测试函数

% mode = 'self_define';

if strcmp(mode, 'Schaffer')

figure(1)

x = -4:0.1:4;

y = -4:0.1:4;

[X,Y] = meshgrid(x,y);

% Z = 3*cos(X.*Y)+X+Y.^2;

Z = 0.5-((sin(sqrt(X.^2+Y.^2)).^2)-0.5)./(1+0.001.*(X.^2+Y.^2)).^2;

surf(X,Y,Z);

title('Schaffer Function');

xlabel('X-轴');

ylabel('Y-轴');

zlabel('Z-轴');

figure(2);

contour(X, Y, Z, 8);

title('Schaffer函数等高线');

xlabel('X-轴');

ylabel('Y-轴');

end

if strcmp(mode, 'self_define')

figure(1);

x = -4:0.1:4;

y = -4:0.1:4;

[X,Y] = meshgrid(x,y);

% Z = 100.*(Y-X.^2).^2+(1-X).^2;

Z = (cos(X.^2+Y.^2)-0.1)./(1+0.3*(X.^2+Y.^2).^2)+3;

surf(X,Y,Z);

%title('Rosen Brock valley Function');

title('Self define Function');

xlabel('X-轴');

ylabel('Y-轴');

zlabel('Z-轴');

end

% 种群初始化

x=zeros(NP,D);

v=zeros(NP,D);

u=zeros(NP,D);

x=X_min + (X_max-X_min)*rand(NP,D);

for gen=1:1:G

for i=1:1:NP

ob(i) = func(x(i,:), mode);

end

[fitness_max, index] = max(ob);

lamb(gen) = exp(1-(G/(G+1-gen)));

F = F0*2^lamb(gen);

% 变异

if(DE_vector==0)

for m=1:NP

r1=randi([1,NP],1,1);

while (r1==m)

r1=randi([1,NP],1,1);

end

r2=randi([1,NP],1,1);

while(r2==r1)||(r2==m)

r2=randi([1,NP],1,1);

end

r3=randi([1,NP],1,1);

while (r3==m)||(r3==r2)||(r3==r1)

r3=randi([1,NP],1,1);

end

v(m,:)=x(r1,:)+F*(x(r2,:)-x(r3,:)); % DE/best/1bin

end

elseif(DE_vector==1)

for m=1:NP

r1=randi([1,NP],1,1);

while (r1==m)

r1=randi([1,NP],1,1);

end

r2=randi([1,NP],1,1);

while(r2==r1)||(r2==m)

r2=randi([1,NP],1,1);

end

v(m,:)=x(index,:)+x(r1,:)+F*(x(r1,:)-x(r2,:));

end

elseif(DE_vector==2)

lambda = 0.35;

for m=1:NP

r1=randi([1,NP],1,1);

while (r1==m)

r1=randi([1,NP],1,1);

end

r2=randi([1,NP],1,1);

while(r2==r1)||(r2==m)

r2=randi([1,NP],1,1);

end

v(m,:)=x(m,:)+lambda*(x(index,:)-x(m,:))+F*(x(r1,:)-x(r2,:));

end

elseif(DE_vector==3)

for m=1:NP

r1=randi([1,NP],1,1);

while (r1==m)

r1=randi([1,NP],1,1);

end

r2=randi([1,NP],1,1);

while(r2==r1)||(r2==m)

r2=randi([1,NP],1,1);

end

r3=randi([1,NP],1,1);

while (r3==m)||(r3==r2)||(r3==r1)

r3=randi([1,NP],1,1);

end

r4=randi([1,NP],1,1);

while (r4==m)||(r4==r3)||(r4==r2)||(r4==r1)

r4=randi([1,NP],1,1);

end

v(m,:)=x(index,:)+F*(x(r1,:)-x(r2,:)+x(r3,:)-x(r4,:));

end

else

for m=1:NP

r1=randi([1,NP],1,1);

while (r1==m)

r1=randi([1,NP],1,1);

end

r2=randi([1,NP],1,1);

while(r2==r1)||(r2==m)

r2=randi([1,NP],1,1);

end

r3=randi([1,NP],1,1);

while (r3==m)||(r3==r2)||(r3==r1)

r3=randi([1,NP],1,1);

end

r4=randi([1,NP],1,1);

while (r4==m)||(r4==r3)||(r4==r2)||(r4==r1)

r4=randi([1,NP],1,1);

end

r5=randi([1,NP],1,1);

while (r5==m)||(r5==4)||(r5==r3)||(r5==r2)||(r5==r1)

r5=randi([1,NP],1,1);

end

v(m,:)=x(r5,:)+F*(x(r1,:)-x(r2,:)+x(r3,:)-x(r4,:));

end

end

% 交叉操作

r=randi([1,D],1,1);

for i=1:D

cr=rand;

if (cr<=CR)||(i==r)

u(:,i)=v(:,i);

else

u(:,i)=x(:,i);

end

end

% 边界条件处理

for m=1:NP

for n=1:D

if u(m,n)X_max

u(m,n)=X_max;

end

end

end

% 自然选择

for i=1:NP

ob_1(i)=func(u(i,:), mode);

end

for i=1:NP

if ob_1(i)>ob(i)

x(i,:)=u(i,:);

else

x(i,:)=x(i,:);

end

end

trace(gen+1)=fitness_max;

end

figure(3);

% plot(trace);

title('差分进化算法');

xlabel('迭代次数');

ylabel('目标函数值');

plot(trace);

function f=func(buf, md)

if strcmp(md, 'Schaffer')

f=0.5-((sin(sqrt(buf(1).^2+buf(2).^2)).^2)-0.5)./(1+0.001.*(buf(1).^2+buf(2).^2)).^2;

end

if strcmp(md,'self_define')

% f = 100*(buf(2)-buf(1).^2).^2+(1-buf(1)).^2;

f = (cos(buf(1).^2+buf(2).^2)-0.1)./(1+0.3*(buf(1).^2+buf(2).^2).^2)+3;

end

end

测试函数:

29c2965faed9fd668ed2443e29d12fd7.png

适应度进化曲线:

dfa2ad963816d7ecdd3991040a811067.png

源代码中只是添加了典型的测试函数,参数只是粗略设置一下。对于其他的测试函数。可以在原代码中添加,并且修改源代码中的一些参数来得到算法最好的性能。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值