差分进化算法

差分进化算法

  1. 参数:

    • 种群大小:N

    • 染色体长度:D(待求参数向量的长度)

    • 迭代次数: G m G_m Gm 或者 停止进化条件

    • 变异算子: F 0 F_0 F0

      • 决定差分过程中的变异大小

      • 一般取[0,2]

      • 为了避免早熟,可以增加具有自适应变异的算子,具体如下:
        λ = e 1 − G m G m + 1 − G F = F 0 ⋅ 2 λ \displaystyle\lambda=e^{1-\frac{G_m}{G_m+1-G}} \\ F=F_0\cdot2^\lambda λ=e1Gm+1GGmF=F02λ
        通过该种方式,变异算子可以随着迭代次数的增加,实现由 F 0 ⟹ 0 F_0\Longrightarrow 0 F00的转变

    • 交叉(遗传)算子:CR (表示某一个体的某一基因遗传给下一代的概率) 介于[0,1]

    • 寻优区间:[ x j,i L x_{\text{j,i}}^L xj,iL, x j,i U x_{\text{j,i}}^U xj,iU] 限制每一个体每一染色体的大小

    • x(g):当前进化代数下的个体合集;

      v(g):当前进化代数下产生的等待遗传的所有染色体合集;

      u(g):当前代数下v(g)与x(g)按照交叉算子的限制相互结合形成的新个体。

    • (i , j):第i个个体的第j个染色体;

  2. 算法流程

    1. 初始化种群
      x j,i ( 0 ) = x j,i L + r a n d ( 0 , 1 ) ⋅ ( x j,i U − x j,i L ) x_{\text{j,i}}(0)=x_{\text{j,i}}^L+rand(0,1)\cdot(x_{\text{j,i}}^U-x_{\text{j,i}}^L) xj,i(0)=xj,iL+rand(0,1)(xj,iUxj,iL)

    2. 变异

      常见的差分策略为随机选取中区中两个不同的个体,将其向量差缩放后形成变异中间个体v(g)
      v i ( g + 1 ) = x r1 ( g ) + F ⋅ ( x r2 ( g ) − x r3 ( g ) ) v_\text{i}(g+1)=x_{\text{r1}}(g)+F\cdot(x_{\text{r2}}(g)-x_{\text{r3}}(g)) vi(g+1)=xr1(g)+F(xr2(g)xr3(g))
      ⟹ 边 界 判 断 : \Longrightarrow 边界判断:

      • x ′ = { x j,i L     ,     x ′ < x j,i L   ; x j,i U     ,     x ′ > x j,i U   ; x ′       ,     e l s e   ; x'=\left\{\begin{array}{l}x_{\text{j,i}}^L\ \ \ ,\ \ \ x'<x_{\text{j,i}}^L\ ;\\x_{\text{j,i}}^U\ \ \ ,\ \ \ x'>x_{\text{j,i}}^U\ ;\\x'\ \ \ \ \ ,\ \ \ else\ ;\end{array}\right. x=xj,iL   ,   x<xj,iL ;xj,iU   ,   x>xj,iU ;x     ,   else ;
      • x ′ = { x j,i L + r a n d ( 0 , 1 ) ⋅ ( x j,i U − x j,i L )    ,    i f   x ′ < x    o r    x ′ > x   ; x ′       ,     e l s e x'=\left\{\begin{array}{l}x_{\text{j,i}}^L+rand(0,1)\cdot(x_{\text{j,i}}^U-x_{\text{j,i}}^L)\ \ ,\ \ if\ x'<x\ \ or\ \ x'>x\ ;\\x'\ \ \ \ \ ,\ \ \ else\end{array}\right. x={xj,iL+rand(0,1)(xj,iUxj,iL)  ,  if x<x  or  x>x ;x     ,   else
    3. 交叉

      对第 g g g代种群 { x i ( g ) } \{x_\text{i}(g)\} {xi(g)}及其变异的中间体 { v i ( g + 1 ) } \{v_\text{i}(g+1)\} {vi(g+1)}进行个体间的交叉操作;
      u j,i = { v j,i ( g + 1 )     ,     i f    r a n d ( 0 , 1 ) ⩽ C R    o r    j = r a n d i ( [ 1 , D ] , 1 , 1 ) x j,i ( g )            ,     e l s e u_{\text{j,i}}= \left\{ \begin{array}{l} v_{\text{j,i}}(g+1)\ \ \ ,\ \ \ if\ \ rand(0,1)\leqslant CR\ \ or\ \ j=randi([1,D],1,1)\newline x_{\text{j,i}}(g)\ \ \ \ \ \ \ \ \ \ ,\ \ \ else \end{array} \right. uj,i={vj,i(g+1)   ,   if  rand(0,1)CR  or  j=randi([1,D],1,1)xj,i(g)          ,   else
      在交叉过程中, j = r a n d i ( [ 1 , D ] , 1 , 1 ) j=randi([1,D],1,1) j=randi([1,D],1,1)是为了确保每一个变异中间体一定有一个变异染色体遗传下去;其他的交叉过程,则是通过交叉概率CR来选取变异中间体的该染色体是否遗传给下一代
      在这里插入图片描述

    4. 选择

      设置一目标函数:
      f ( X ) = ∑ i = 1 n x i 2   ; X = { x 1 , x 2 , x 3 , ⋯   , x n } f(X)=\sum_{i=1}^n x_i^2\ ;\\ X = \{x_1,x_2,x_3,\cdots,x_n\} f(X)=i=1nxi2 ;X={x1,x2,x3,,xn}
      DE采用采用贪婪算法来选择进入下一代种群的个体:
      x i ( g + 1 ) = { u i ( g + 1 )     ,     i f    f ( u i ( g + 1 ) ) ⩽ f ( x i ( g ) )   ; x i ( g )            ,     e l s e x_\text{i}(g+1)= \left\{ \begin{array}{l} u_\text{i}(g+1)\ \ \ ,\ \ \ if\ \ f(u_\text{i}(g+1))\leqslant f(x_\text{i}(g))\ ; \\ x_\text{i}(g)\ \ \ \ \ \ \ \ \ \ ,\ \ \ else \end{array} \right. xi(g+1)={ui(g+1)   ,   if  f(ui(g+1))f(xi(g)) ;xi(g)          ,   else

  3. 流程总结

在这里插入图片描述

  1. 代码示例
    以下代码式差分进化算法具体实现,这里的优化模型为:
    目标函数: f ( X ) = ∑ i = 1 10 x i 2 \displaystyle f(X)=\sum_{i=1}^{10}x_i^2 f(X)=i=110xi2 X = { x 1 , x 2 , x 3 , ⋯   , x 10 } X=\{x_1,x_2,x_3,\cdots,x_{10}\} X={x1,x2,x3,,x10};

    决策变量: X X X ;

    限制条件: f o r    x i   ∈   [ − 20 , 20 ] for\ \ x_i\ \in\ [-20,20] for  xi  [20,20] ;

clear
close all
clc
N = 1000; % 种群数量
D = 10; % 决策变量维度
G_Max = 3000; % 迭代次数
F0 = 2; % 变异算子初值
CR = 0.4; % 交叉概率
X_Min = -20; % 决策变量区间
X_Max = 20;

WaitbarInter = G_Max / 100; % 为了生成进度条的一个数字



% 种群初始化
X = rand(N, D) * (X_Max - X_Min) + X_Min;
X_Fitness = Fitness(X,N);
V = zeros(N, D);
U = zeros(N, D);
U_Fitness = Fitness(U,N);
Best_X = X(1, :);
MinFitness_List = zeros(1, G_Max + 1); % 存放每一次迭代的目标函数值
MinFitness_List(1) = min(X_Fitness);
Fitness_List = zeros(1, G_Max + 1);
Fitness_List(1) = MinFitness_List(1);

tic
h = waitbar(0, ['已完成:0%   运算中...用时:', num2str(toc)]);

for g = 1:G_Max
    % 变异算子迭代
    lambda = exp(1 - G_Max / (G_Max + 1 - g));
    F = F0 * 2^lambda;
    % 差分变异操作
    for i = 1:N
        % 产生不同的r1,r2,r3
        r1 = randi([1, N], 1, 1);
        r2 = randi([1, N], 1, 1);
        r3 = randi([1, N], 1, 1);

        while (r1 == i)
            r1 = randi([1, N], 1, 1);
        end

        while (r2 == r1) || (r2 == i)
            r2 = randi([1, N], 1, 1);
        end

        while (r3 == i) || (r3 == r1) || (r3 == r2)
            r3 = randi([1, N], 1, 1);
        end

        V(i, :) = X(r1, :) + F * (X(r2, :) - X(r3, :));
    end

    % % 交叉操作1
    % % 该交叉操作是一次性对整个种群进行交叉,而不是针对单个个体
    % r = randi([1,D],1,1);
    % for d = 1:D
    %     if(rand<=CR)||(d==r)
    %         U(:,d) = V(:,d);
    %     else
    %         U(:,d) = X(:,d);
    %     end
    % end

    % 交叉操作2
    % 该交叉操作是对单个个体进行交叉,而不是一次性针对整个种群进行
    for n = 1:N
        r = randi([1, D], 1, 1);

        for d = 1:D

            if (rand <= CR) || (d == r)
                U(n, d) = V(n, d);
            else
                U(n, d) = X(n, d);
            end

        end

    end

    % 边界处理
    U = BoundaryLimit(U, X_Min, X_Max);
    % 自然选择

    U_Fitness = Fitness(U, N);
    Fitness_List(g + 1) = min(U_Fitness);
    for n = 1:N

        if X_Fitness(n) > U_Fitness(n)
            X(n, :) = U(n, :);
            X_Fitness(n) = U_Fitness(n);
        end

    end

    [MinFitness_List(g + 1), index_Min] = min(X_Fitness);
    Best_X = X(index_Min, :);
    
    if mod(g, WaitbarInter) == 0
        waitbar(g / G_Max, h, ['已完成:', num2str(g / G_Max * 100), ...
        '%   运算中...用时:', num2str(toc),'/',num2str(toc/(g / G_Max))]);
    end

end
close(h)

display(['The best solution obtained by DE is : ', num2str(Best_X)]);
display(['The best optimal value of the objective funciton found by DE is : ', num2str(MinFitness_List(end))]);
figure
semilogy(MinFitness_List,'linewidth',1.2)
hold on
semilogy(Fitness_List,'linewidth',1.2)
legend(['最小适应度变化'],['适应度变化'])
title('Convergence Curve')
xlabel('Iteration');
ylabel('Best score obtained so far');
axis tight
grid on
box on

% 目标函数
function result = Fitness(X, N)
    result = zeros(N, 1);

    for i = 1:N
        result(i) = sum(X(i, :).^2);
    end

end

% 边界限制函数
function result = BoundaryLimit(X, Min, Max)

    for i_temp = 1:length(X(:, 1))

        for j_temp = 1:length(X(1, :))

            if X(i_temp, j_temp) > Max
                X(i_temp, j_temp) = Max;
            end

            if X(i_temp, j_temp) < Min
                X(i_temp, j_temp) = Min;
            end

        end

    end

    result = X;
end
toc
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RivenRussell

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值