基础差分进化算法

       最近老师给我们布置的第一个任务就是差分进化算法,乍一听有点蒙,静下心来一看还是很懵。所以我写这个博客来一步一步理清思路,所以本文侧重算法实现的过程,理论的东西再慢慢研究。

       差分进化算法(Differential Evolution Algorithm,DE)是一种高效的全局优化算法。它也是基于群体的启发式搜索算法,群中的每个个体对应一个解向量。差分进化算法的流程则与遗传算法类似,都包括变异、杂交和选择操作。个人感觉遗传算法更复杂。接下来一部分来自百度百科:(感谢度娘!!!)


基本原理

 DE算法通过采用浮点矢量进行编码生成种群个体。在DE算法寻优的过程中,首先,从父代个体间选择两个个体进行向量做差生成差分矢量;其次,选择另外一个个体与差分矢量求和生成实验个体;然后,对父代个体与相应的实验个体进行交叉操作,生成新的子代个体;最后在父代个体和子代个体之间进行选择操作,将符合要求的个体保存到下一代群体中去。

进化流程

其具体进化流程如下:

(1)确定差分进化算法控制参数,确定适应度函数。差分进化算法控制参数包括:种群大小NP、缩放因子F与杂交概率CR。

(2)随机产生初始种群。

(3)对初始种群进行评价,即计算初始种群中每个个体的适应度值。

(4)判断是否达到终止条件或进化代数达到最大。若是,则终止进化,将得到最佳个体作为最优解输出;若否,继续。

(5)进行变异和交叉操作,得到中间种群。

(6)在原种群和中间种群中选择个体,得到新一代种群。

(7)进化代数g=g+1,转步骤(4).

扫描二维码关注公众号,回复: 9101897 查看本文章

控制参数

DE算法主要的控制参数包括:种群规模(NP)、缩放因子(F)和交叉概率(CR)。

NP主要反映算法中种群信息量的大小,NP值越大种群信息包含的越丰富,但是带来的后果就是计算量变大,不利于求解。反之,使种群多样性受到限制,不利于算法求得全局最优解,甚至会导致搜索停滞。

CR主要反映的是在交叉的过程中,子代与父代、中间变异体之间交换信息量的大小程度。CR的值越大,信息量交换的程度越大。反之,如果CR的值偏小,将会使种群的多样性快速减小,不利于全局寻优。

相对于CR,F对算法性能的影响更大,F主要影响算法的全局寻优能力。F越小,算法对局部的搜索能力更好,F越大算法越能跳出局部极小点,但是收敛速度会变慢。此外,F还影响种群的多样性。


Matlab程序部分:

1.简单操作

首先说一下在matlab中写程序的步骤:首先自己新建一个文件夹,然后打开matlab,如下图,把工作目录切换到刚刚建立的文件夹所在的目录。

之后在命令窗口敲下 edit ,进入脚本编辑环境如下。

接下来就开始写了。

2测试函数.

 这里用的是Rastrigr函数。 

f(x) = \sum_{1}^{n} [x_{i}^2 - 10cos(2\pi x_{i}^2) +10]    

|x| <5.12

图像就是下面那个样子:

接下来进入算法的matlab程序:

1种群初始化


%基本参数以及种群的初始化
Gm = 1000; %最大迭代次数  
F0 = 0.5;  %F0是变异率
Np = 100;  %种群规模
CR = 0.9;  %交叉概率
G= 1;      %初始化代数
D = 10;    %解向量的维数
Gmin = zeros(1,Gm);    %各代的最优值
best_x = zeros(Gm,D);  %各代的最优解
value = zeros(1,Np);
 
%产生初始种群
xmin = -5.12; %解的下界
xmax = 5.12;  %解的上界

X0 = (xmax-xmin)*rand(Np,D) + xmin;  %产生Np行D列矩阵(范围0-1),也就是生成一个初试解的矩阵。
%% 这里每一个列向量就是所谓的一个个体。所以这里有Np个个体。

注意下这里的X0,这是一个Np行D列的一个矩阵,每一行对应一个初始解向量(D维),也就是一个个体。

rand函数产生一个0-1范围的矩阵。

2变异操作


XG_next_1= zeros(Np,D);   %保存变异操作的结果
XG_next_2 = zeros(Np,D);  %保存交叉操作的结果
XG_next = zeros(Np,D);    %保存选择操作的结果

%%变异操作 
    for i = 1:Np            
        %产生j,k,p三个不同的数
        a = 1;
        b = Np;
        dx = randperm(b-a+1) + a- 1;%这里要了解randperm函数 ,这里就是打乱原种群个体的顺序  
        j = dx(1);
        k = dx(2);
        p = dx(3);
        %要保证与i不同
        if j == i
            j  = dx(4);
            else if k == i
                 k = dx(4);
                else if p == i
                    p = dx(4);
                    end
                end
         end
        
        %变异算子
        suanzi = exp(1-Gm/(Gm + 1-G));   
        F = F0*2.^suanzi;
        %变异的个体来自三个随机父代
        %这里是一个向量运算,XG(p,:),这个表示整个p 行的行向量,也就是第p个个体。其他两个同理。 
        也就是向量之间的加减运算。
        son = XG(p,:) + F*(XG(j,:) - XG(k,:));       
        for j = 1: D
            if son(1,j) >xmin  & son(1,j) < xmax %防止变异超出边界
                XG_next_1(i,j) = son(1,j);
            else
                XG_next_1(i,j) = (xmax - xmin)*rand(1) + xmin;
            end
        end
    end

变异操作有两点要求:

1. DE通过差分策略实现个体变异。常见的差分策略是随机选取种群中两个不同的个体,将其向量差缩放后与待变异的个体结合

所以上边的 dx 就是随机打乱顺序后的个体。F为缩放因子。

2. 变异生成的新个体中的每个值都要在自变量范围内,否则,就要用初始化种群时的方法重新生成一个。

3.交叉操作

for i = 1: Np
        randx = randperm(D);% [1,2,3,...D]的随机序列   
        for j = 1: D
            
            if rand > CR & randx(1) ~= j % CR = 0.9 %交叉因子小于0-1之间的随机数,且j不等于当 
                                                    %前的随机序列
                XG_next_2(i,j) = XG(i,j);           %赋予原始值 
            else
                XG_next_2(i,j) = XG_next_1(i,j);    %赋予变异后的值
            end
        end
end

这里的关键就是一个判断:第g代交叉的结果有两种情况,如果CR 大于等于rand(0,1),或者j 等于 1到D 之间的一个随机数,则 第g代交叉的结果为对应的变异结果 即XG_next_2(i,j) = XG_next_1(i,j);  否者就等于原始值  XG_next_2(i,j) = XG(i,j);

4.选择操作

for i = 1:Np                        %选出,也就是从初始值和交叉后的个体中选。
                                    %带入测试函数,选取结果小的,进行结果计算
        if f(XG_next_2(i,:)) < f(XG(i,:))
            
            XG_next(i,:) = XG_next_2(i,:); 
        else
            XG_next(i,:) = XG(i,:);
        end
end
    
%找出最小值
for i = 1:Np             
    value(i) = f(XG_next(i,:));   %将选出的每个个体带入测试函数,计算结果 为1*100的行向量
end
[value_min,pos_min] = min(value); %从中选出最小值,value_min为最小值,pos_min为最小值所在的位置
    
%第G代中的目标函数的最小值
Gmin(G) = value_min;   %因为要进行迭代,将这一代的最小值保存在Gmin(这是个1*GM的向量)中。  
%保存最优的个体
best_x(G,:) = XG_next(pos_min,:);   
    
XG = XG_next;    
trace(G,1) = G;     %画图像用,相当于x轴
trace(G,2) = value_min; %画图像用,相当于y轴
G = G + 1;         %进入下一代

5 打印信息画图

[value_min,pos_min] = min(Gmin);
  best_value = value_min
  best_vector =  best_x(pos_min,:)  
  fprintf('DE所耗的时间为:%f \n',cputime - t0);
  %画出代数跟最优函数值之间的关系图  
  plot(trace(:,1),trace(:,2));

这是经行1000代的图。

这是5000代的。

这是10000代的结果,收敛到0。


写完发现还是有点乱,哎。。。。.完整代码可以在这里下载

https://download.csdn.net/download/qq_33728095/10750890

发布了19 篇原创文章 · 获赞 52 · 访问量 7923

猜你喜欢

转载自blog.csdn.net/qq_33728095/article/details/83477244