A Dynamic Competitive Swarm Optimizer Based-on Entropy for Large Scale Optimization

0、论文背景

本文在CSO基础上,本文提出了一种新的动态竞争群优化器(DCSO)算法。它利用种群熵将种群动态地划分为两个子群。适应度较差的组向较好的组学习(PSO),较好的组向自己学习(CSO)。在执行过程的早期阶段,由于种群熵较高,适应度较好的子群规模较小。这样,新的算法就类似于PSO了。然后,在执行过程的后期,由于种群熵较低,适应度较好的子群规模较大。该算法转化为总CSO

Zhang W X, Chen W N, Zhang J. A dynamic competitive swarm optimizer based-on entropy for large scale optimization[C]//2016 Eighth International Conference on Advanced Computational Intelligence (ICACI). IEEE, 2016: 365-371.

1、PSO与CSO 

有关PSO和CSO在之前博客里面有提到过:PSOCSO

PSO目前存在的现状:在许多情况下,优化问题中维数的增长会显著增加局部最优问题的数量,从而导致PSO的过早收敛

CSO目前存在的现状:CSO在程序实现的简单性,在不可分离函数上比CC方法具有更好的性能(CSO探索能力比PSO强)。然而,CSO面临着收敛缓慢的问题。CSO的收敛缓慢的一个重要原因是,在每一代中,只有在竞争中失败的粒子的一半可以被更新,其余的获胜粒子保持不变

2、种群熵

有关熵之前的博客里面有提到过:

所有粒子的适应度值组成的集合R(y值)中存在n个子区间:

A_{1} \cup A_{2} \cup \ldots \cup A_{n}=R, A_{1} \cap A_{2} \ldots \cap A n=\phi

适应度值落入每个子空间的个数为:

s1,s2,...,sn

因此种群的种群熵为:

\begin{array}{c} E=-\sum_{i=1}^{n} p_{i} \log \left(p_{i}\right) \\ p_{i}=S_{i} / \sum_{i=1}^{n} S_{i} \end{array}

为了使E最大值为1,条件:p_{1}=p_{2} \ldots=p_{n}=1 / n

E=-\sum_{i=1}^{n} p_{i} \log _{n}\left(p_{i}\right)

E(种群熵)越大,越接近于1,说明种群分布越均匀,说明当前状态下收敛速度快,种群多样性高,应该加快收敛。

3、DCSO

算法流程图:

初始化:在此过程中,速度v初始化为0。

种群划分:按适应度值对粒子进行排序。然后使用以下规则来调整两个子组的大小。

 m_{b}=\left\{\begin{array}{cc} -(m / d) * P E(t)+m / d & P E(t)>1-d \\ m & P E(t) \leq 1-d \end{array}\right.

m_{w}=m-m_{b}

pw种群更新:

\begin{aligned} V_{\mathrm{i}}(t+1) &=r_{1} \cdot V_{i}(t)+r_{2} \cdot\left(X_{j}(t)-X_{i}(t)\right) \\ &+\varphi \cdot r_{3}\left(\bar{X}(t)-X_{i}(t)\right) \\ X_{i}(t+1) &=X_{i}(t)+V_{i}(t+1) \end{aligned}

pb种群更新:

\begin{array}{l} V_{l}(t+1)=r_{1} \cdot V_{l}(t)+r_{2} \cdot\left(X_{w}(t)-X_{l}(t)\right) \\ X_{l}(t+1)=X_{l}(t)+V_{l}(t+1) \end{array}

4、论文中实验以及结果

4.1 DCSO和CSO参数设置

实验的函数是CEC2008。

CSO:

 如果粒子群的大小(m)太小,粒子往往收敛得非常快,从而导致过早收敛。相反,如果蜂群规模太大,那么每一代都需要进行大量的适应度评估(FEs),这可能是不切实际的,也会浪费时间。

从结果中可以看出,不可分离函数(f2、f3和f7)比可分离函数(f1、f4、f5和f6)需要更小的φ。原因可能是可分离的函数更容易优化,因此,一个更大的φ会工作得更好,因为它会导致更快的收敛

DCSO:

 在d较大的情况下,较好的子群的大小增大较慢,在搜索空间得到良好的探索之前,粒子的收敛速度非常快,从而导致过早收敛。相反,如果因子d太小,则较好的子群的规模就会迅速增加,这将使得收敛速度与CSO一样慢

 

 f1和f3更容易优化,因此,更小的d会工作得更好,因为它会导致更快的收敛。

当收敛速度较快时,熵通常超过0.8。更有趣的是,当f5进入过早收敛时种群熵会急剧下降。

4.2 对比试验结果

 可以看出:DCSO收敛速度比CSO快,收敛效果比CSO好。

 

5、个人简单复现以及实验

CSO:

clc;clear;clearvars;
addpath('CEC2008\');
global initial_flag

% num_vari维度,max_evalutions最大评估次数,num_initial初始化点的个数,evalutions已经评估个数
num_vari = 100;
%max_evalutions = 5000 * num_vari;
max_evalutions = 500 * num_vari;
num_initial = num_vari;

% 搜索区间:f1[-100,100],f2[-100, 100],f3[-100,100],f4[-5,5],f5[-600,600],f6[-32,32],f7[-1,1],每一维搜索区间一样
upper_bound = [100,100,100,5,600,32,1];
lower_bound = [-100,-100,-100,-5,-600,-32,-1];

for func_num = 1:7

    % 使initial_flag==0满足此条件,换一个函数initial_flag重置为0
    initial_flag = 0;
    evalutions = 0;
    varphi = 0; %100维0,500维0.1和0.05,1000维0.15和0.1

    % 生成num_initial个种群,并获得其评估值
    sample_x = lhsdesign(num_initial, num_vari).*(upper_bound(func_num) - lower_bound(func_num)) + lower_bound(func_num).*ones(num_initial, num_vari);
    sample_y = benchmark_func(sample_x,func_num);
    evalutions = evalutions + size(sample_y,1);
    v = zeros(num_initial,num_vari);  %v初始化为0
    fmin = min(sample_y);
    arr_fmin = [];
    arr_fmin = [arr_fmin;fmin];

    while evalutions <= max_evalutions

        pb = sample_x;
        pby = sample_y;
        pbv = v;
        mean_x = mean(sample_x);

        next_samplex = [];
        next_sampley = [];
        next_v = [];

        % 更新pb
        while ~isempty(pb)
            k1 = randi(size(pb, 1));    %随机抽取两个点
            k2 = randi(size(pb, 1));
            while k2 == k1
                k2 = randi(size(pb, 1));
            end
            if pby(k1,1) < pby(k2,1)
                add = k1;
                update = k2;
            else
                add = k2;
                update = k1;
            end
            next_samplex = [next_samplex;pb(add,:)]; %add直接加入
            next_sampley = [next_sampley;pby(add,:)];
            next_v = [next_v;pbv(add,:)];
            pbv(update,:) = rand(1, num_vari) .* pbv(update,:) + rand(1, num_vari) .* (pb(add,:) - pb(update,:)) + varphi .* rand(1, num_vari) .* (mean_x - pb(update,:));    %update需要更新
            xl = pb(update,:) + pbv(update,:);
            xl(xl > upper_bound(func_num)) = upper_bound(func_num);
            xl(xl < lower_bound(func_num)) = lower_bound(func_num);% 范围检查
            if evalutions <= max_evalutions
                yl = benchmark_func(xl,func_num);
                evalutions = evalutions + 1;
                if yl < fmin
                    fmin = yl;
                end
                arr_fmin = [arr_fmin;fmin];
                fprintf("func_num:%d evalutions:%d fmin: %.4f\n", func_num, evalutions, fmin);
                next_samplex = [next_samplex;xl];   %加到下一次迭代中
                next_sampley = [next_sampley;yl];
                next_v = [next_v;pbv(update,:)];
            else
                break;
            end

            % 从pb中去掉k1和k2,从后面删除,防止后面删除的数索引发生变化
            if k1 > k2
                first = k1;
                second = k2;
            else
                first = k2;
                second = k1;
            end
            pb(first, :) = [];
            pby(first, :) = [];
            pbv(first, :) = [];
            pb(second, :) = [];
            pby(second, :) = [];
            pbv(second, :) = [];
        end

        % 更新sample_x,v和sample_y
        sample_x = next_samplex;
        sample_y = next_sampley;
        v = next_v;
    end
    plot(arr_fmin);
end

第四个函数:

第六个函数: 

DCSO:

clc;clear;clearvars;
addpath('CEC2008\');
global initial_flag

% num_vari维度,max_evalutions最大评估次数,num_initial初始化点的个数,evalutions已经评估个数
num_vari = 100;
%max_evalutions = 5000 * num_vari;
max_evalutions = 500 * num_vari;
num_initial = num_vari;

% 搜索区间:f1[-100,100],f2[-100, 100],f3[-100,100],f4[-5,5],f5[-600,600],f6[-32,32],f7[-1,1],每一维搜索区间一样
upper_bound = [100,100,100,5,600,32,1];
lower_bound = [-100,-100,-100,-5,-600,-32,-1];

for func_num = 1:7

    % 使initial_flag==0满足此条件,换一个函数initial_flag重置为0
    initial_flag = 0;
    evalutions = 0;
    varphi = 0; %100维0,500维0.1和0.05,1000维0.15和0.1

    % 生成num_initial个种群,并获得其评估值
    sample_x = lhsdesign(num_initial, num_vari).*(upper_bound(func_num) - lower_bound(func_num)) + lower_bound(func_num).*ones(num_initial, num_vari);
    sample_y = benchmark_func(sample_x,func_num);
    evalutions = evalutions + size(sample_y,1);
    v = zeros(num_initial,num_vari);  %v初始化为0
    fmin = min(sample_y);
    arr_fmin = [];
    arr_fmin = [arr_fmin;fmin];

    while evalutions <= max_evalutions

        % 根据种群熵来划分pb和pw,种群熵的计算与MATLAB中entropy计算熵类似
        n_bin = num_initial;    %n_bin表示区间数
        res = rescale(sample_y);    % rescale将数组的条目缩放到区间 [0,1]
        p = imhist(res,n_bin);  % rescale将数组的条目缩放到区间 [0,1]
        p(p==0) = [];   % 除去p中的0
        p = p ./ numel(sample_y);% 正则化p使得sum(p)为1,numel计算数组中元素的数目

        % 为了E最大为1,所以用logn(p),而不是log2(p)
        n_nozero = size(p,1);
        E = -sum(p.*(log(p)./log(n_nozero)));
        
        % 划分pb和pw
        [sample_y,ind]= sort(sample_y); %按升序对 A 的元素进行排序
        sample_x = sample_x(ind,:);
        v = v(ind,:);
        mean_x = mean(sample_x);
        d = 0.25;   %100维0.25,500维0.35,1000维0.45
        if E > 1 - d
            mb = -(num_initial / d) * E + num_initial / d;
        else
            mb = num_initial;
        end
        mb = ceil(mb);
        mw = num_initial - mb;
        pb = sample_x(1:mb,:);  %越小越好
        pby = sample_y(1:mb,:);
        pbv = v(1:mb,:);
        pw = sample_x((mb + 1):num_initial,:);
        pwv = v((mb + 1):num_initial,:);

        next_samplex = [];
        next_sampley = [];
        next_v = [];
        % 更新pw
        for i = 1:size(pw,1)
            if size(pb,1) == 0  %pb有为空的问题
                xj = sample_x(1,:);   %当前最小值
            else
                xj = pb(randi(size(pb,1)),:);
            end
            pwv(i,:) = rand(1, num_vari) .* pwv(i,:) + rand(1, num_vari) .* (xj - pw(i,:)) + varphi .* rand(1, num_vari) .* (mean_x - pw(i,:));
            xi = pw(i,:) + pwv(i,:);
            xi(xi > upper_bound(func_num)) = upper_bound(func_num);
            xi(xi < lower_bound(func_num)) = lower_bound(func_num);% 范围检查
            if evalutions <= max_evalutions
                yi = benchmark_func(xi,func_num);
                if yi < fmin
                    fmin = yi;
                end
                arr_fmin = [arr_fmin;fmin];
                fprintf("func_num:%d evalutions:%d fmin: %.4f\n", func_num, evalutions, fmin);
                evalutions = evalutions + 1;
                next_samplex = [next_samplex;xi];   %加到下一次迭代中
                next_sampley = [next_sampley;yi];
                next_v = [next_v;pwv(i,:)];
            else
                break;
            end
        end

        % 更新pb
        while ~isempty(pb)
            if size(pb,1) == 1
                next_samplex = [next_samplex;pb];
                next_sampley = [next_sampley;pby];
                next_v = [next_v;pbv];
                pb = [];
                pby = [];
                pbv = [];
            else
                k1 = randi(size(pb, 1));    %随机抽取两个点
                k2 = randi(size(pb, 1));
                while k2 == k1
                    k2 = randi(size(pb, 1));
                end
                if pby(k1,1) < pby(k2,1)
                    add = k1;
                    update = k2;
                else
                    add = k2;
                    update = k1;
                end
                next_samplex = [next_samplex;pb(add,:)]; %add直接加入
                next_sampley = [next_sampley;pby(add,:)];
                next_v = [next_v;pbv(add,:)];
                pbv(update,:) = rand(1, num_vari) .* pbv(update,:) + rand(1, num_vari) .* (pb(add,:) - pb(update,:));    %update需要更新
                xl = pb(update,:) + pbv(update,:);
                xl(xl > upper_bound(func_num)) = upper_bound(func_num);
                xl(xl < lower_bound(func_num)) = lower_bound(func_num);% 范围检查
                if evalutions <= max_evalutions
                    yl = benchmark_func(xl,func_num);
                    evalutions = evalutions + 1;
                    if yl < fmin
                        fmin = yl;
                    end
                    arr_fmin = [arr_fmin;fmin];
                    fprintf("func_num:%d evalutions:%d fmin: %.4f\n", func_num, evalutions, fmin);
                    next_samplex = [next_samplex;xl];   %加到下一次迭代中
                    next_sampley = [next_sampley;yl];
                    next_v = [next_v;pbv(update,:)];
                else
                    break;
                end

                % 从pb中去掉k1和k2,从后面删除,防止后面删除的数索引发生变化
                if k1 > k2
                    first = k1;
                    second = k2;
                else
                    first = k2;
                    second = k1;
                end
                pb(first, :) = [];
                pby(first, :) = [];
                pbv(first, :) = [];
                pb(second, :) = [];
                pby(second, :) = [];
                pbv(second, :) = [];
            end
        end
        
        % 更新sample_x,v和sample_y
        if size(next_samplex,1) ~= num_initial   %代表程序结束
            break;
        else
            sample_x = next_samplex;
            sample_y = next_sampley;
            v = next_v;
        end
    end
    plot(arr_fmin);
end

第四个函数:

第六个函数:

 

 可以看出:DCSO收敛速度比CSO快,收敛效果比CSO好。

如有错误,恳请批评指教!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

身影王座

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

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

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

打赏作者

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

抵扣说明:

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

余额充值