2025年AIR SCI1区TOP,具有新变异策略和外部存档机制mLSHADE-SPACMA+数值优化与点云配准,深度解析+性能实测


1.摘要

数值优化和点云配准是人工智能领域中的两个关键研究课题。差分进化算法是一种有效的解决方案,而 LSHADE-SPACMA(CEC2017冠军算法)是一个具有竞争力的差分进化变体。然而LSHADE-SPACMA 在应对这类问题时,其局部开发能力有时仍显不足。本文提出了一种改进LSHADE-SPACMA算法(mLSHADE-SPACMA),用于解决数值优化和点云配准问题。mLSHADE-SPACMA算法提出了一种精确的淘汰与生成机制,用来增强算法的局部开发能力;引入了一种基于改进半参数自适应策略和基于排序的选择压力的变异策略,用来提升算法的进化方向性;提出了一种基于精英个体的外部存档机制,该机制保证了外部种群的多样性,并可加快算法的收敛速度。

2.差分进化算法DE

差分进化(Differential Evolution,DE)是一种经典的基于种群的全局优化算法,适用于各类复杂的数值优化问题(Storn & Price, 1997),该算法通过模拟生物进化过程中的变异、交叉与选择机制,在连续空间中迭代搜索最优解。

变异机制通过种群中个体间的向量差分构造新解,常见5种变异策略:
v i = { x r 1 + F ⋅ ( x r 2 − x r 3 ) DE/rand/1 x best + F ⋅ ( x r 1 − x r 2 ) DE/best/1 x i + F ⋅ ( x r 1 − x i ) + F ⋅ ( x r 2 − x r 3 ) DE/current-to-best/1 x i + F ⋅ ( x r 1 − x r 2 ) + F ⋅ ( x r 3 − x r 4 ) DE/best/2 x r 1 + F ⋅ ( x r 2 − x r 3 ) + F ⋅ ( x r 4 − x r 5 ) DE/rand/2 v_i = \left\{ \begin{array}{ll} x_{r1} + F \cdot (x_{r2} - x_{r3}) & \text{DE/rand/1} \\ x_{\text{best}} + F \cdot (x_{r1} - x_{r2}) & \text{DE/best/1} \\ x_i + F \cdot (x_{r1} - x_i) + F \cdot (x_{r2} - x_{r3}) & \text{DE/current-to-best/1} \\ x_i + F \cdot (x_{r1} - x_{r2}) + F \cdot (x_{r3} - x_{r4}) & \text{DE/best/2} \\ x_{r1} + F \cdot (x_{r2} - x_{r3}) + F \cdot (x_{r4} - x_{r5}) & \text{DE/rand/2} \end{array} \right. vi= xr1+F(xr2xr3)xbest+F(xr1xr2)xi+F(xr1xi)+F(xr2xr3)xi+F(xr1xr2)+F(xr3xr4)xr1+F(xr2xr3)+F(xr4xr5)DE/rand/1DE/best/1DE/current-to-best/1DE/best/2DE/rand/2

交叉机制将突变个体与原始个体组合生成新的候选解:
u i j = { v i j , if rand < C r  or  j = j rand x i j , otherwise u_i^j = \left\{ \begin{array}{ll} v_i^j, & \text{if } \text{rand} < Cr \text{ or } j = j_{\text{rand}} \\ x_i^j, & \text{otherwise} \end{array} \right. uij={vij,xij,if rand<Cr or j=jrandotherwise

选择机制通过适应度函数)对新产生的后代进行评价。后代中表现出较高适应性的个体,与亲代中最优秀的个体一起被选择形成下一代种群:
x i = { u i , if  f ( u i ) ≤ f ( x i ) x i , otherwise x_i = \left\{ \begin{array}{ll} u_i, & \text{if } f(u_i) \leq f(x_i) \\ x_i, & \text{otherwise} \end{array} \right. xi={ui,xi,if f(ui)f(xi)otherwise

3.LSHADE-SPACMA

半参数自适应策略

参数配置在差分进化算法中具有决定性作用。研究表明,采用自适应参数策略可以显著提升算法性能,而算法效果的优劣与问题特性高度相关的参数设置密切相关(Das 等,2016)。不同的优化问题往往需要量身定制的参数组合,以实现更优的收敛速度与解质量。LSHADE-SPA 算法引入了一种半参数自适应机制,专门用于调整关键参数 F i F_i Fi C R i CR_i CRi,其中对 F i F_i Fi计算方式进行修改,评估次数前一半此策略:
F i = 0.45 + 0.1 ⋅ r a n d , F E s < max ⁡ F E s / 2 F_i=0.45+0.1\cdot rand,FEs<\max FEs/2 Fi=0.45+0.1rand,FEs<maxFEs/2

LSHADE-SPACMA框架

为提升优化效率,Mohamed 等(2017)提出了一种混合进化框架,将 LSHADE-SPA 与改进的 CMA-ES(协方差矩阵自适应进化策略) 相结合。该框架在 CMA-ES 中引入了交叉操作,以增强算法的全局探索能力。交叉过程在 CMA-ES 步骤后执行,并通过特定公式生成子代个体,从而提升解空间的多样性。

算法以一个统一种群 P P P为基础,其中每个个体可以通过 LSHADE 或 CMA-ES 生成新个体。算法选择是基于一个类别概率变量(FCP)进行的,该变量的取值随机选择自一个记忆槽 MFCP。随着进化的进行,MFCP 会根据各子算法的实际表现动态更新,从而逐步增加对表现更优算法的资源分配比例。记忆槽的更新仅在成功生成新个体的情况下才会触发,用来确保更新机制的有效性与稳定性。

M F C P , g + 1 = ( 1 − c ) ⋅ M F C P , g + c ⋅ Δ A l g 1 M_{FCP,g+1}=(1-c)\cdot M_{FCP,g}+c\cdot\Delta_{Alg1} MFCP,g+1=(1c)MFCP,g+cΔAlg1

在该更新机制中,变量向量 c c c用于调节每次更新的幅度。不同变异算子的改进率通过变量 Δ A l g 1 \Delta\mathrm{Alg}_{1} ΔAlg1,该变量衡量算法在相邻两代之间的性能提升情况:
Δ A l g 1 = m i n ( 0.8 , m a x ( 0.2 , ω A l g 1 / ( ω A l g 1 + ω A l g 2 ) ) ) \Delta_{Alg1}=min\left(0.8,max\left(0.2,\omega_{Alg1}/(\omega_{Alg1}+\omega_{Alg2})\right)\right) ΔAlg1=min(0.8,max(0.2,ωAlg1/(ωAlg1+ωAlg2)))

ω A l g 1 \omega\mathrm{Alg}_{1} ωAlg1表示算法 Δ A l g 1 \Delta\mathrm{Alg}_{1} ΔAlg1新旧适应度值之差的累积,作为评价每个个体在该算法下性能变化的指标:
ω A l g 1 = ∑ i = 1 n f ( x i ) − f ( u i ) \omega_{Alg1}=\sum_{i=1}^nf\left(\boldsymbol{x}_i\right)-f\left(\boldsymbol{u}_i\right) ωAlg1=i=1nf(xi)f(ui)

PS:这里 Δ A l g 1 \Delta\mathrm{Alg}_{1} ΔAlg1可以看作反馈驱动的控制策略,类似RL中奖励信号。

4.mLSHADE-SPACMA

尽管 LSHADE-SPACMA 在多种优化任务中表现出色,但在面对复杂或多样化问题时仍存在一定的性能瓶颈。主要问题包括:种群信息利用不充分导致局部搜索能力不足,半参数自适应策略缺乏敏感性分析限制了算法的适应性,以及变异策略引导性较弱和外部存档机制存在随机性风险,可能误删优质个体,从而影响种群多样性与进化质量。mLSHADE-SPACMA引入更精确的个体淘汰与生成机制,提升局部开发能力;设计增强引导性的变异策略,优化搜索方向;优化外部存档更新机制,在保证多样性的同时加快收敛进程。

精确的淘汰与生成机制

淘汰种群中适应度最差的个体以及利用精英个体引导进化,已被广泛应用于提升算法性能,但这些方法多数缺乏精确性。在 mLSHADE-SPACMA 中,论文提出了一种精确的淘汰与生成机制,以确保解的高质量,该机制仅在评估过程的前半阶段启用:
P E m = c e i l ( ρ ⋅ N P ) , F E s < max ⁡ F s / 2 PE_m=ceil\left(\rho\cdot NP\right),FEs<\max Fs/2 PEm=ceil(ρNP),FEs<maxFs/2

其中, P E m PE_m PEm表示需要淘汰的个体数量, ρ \rho ρ表示需要淘汰的个体占整个种群的百分比。

通过以下生成机制生成等量的新个体:
x i = x best1 + rand ⋅ ( x best1 − x best2 ) , i ∈ { 1 , 2 , … , P E m } , F E s < M a x F E s / 2 x_i = x_{\text{best1}} + \text{rand} \cdot (x_{\text{best1}} - x_{\text{best2}}), \quad i \in \{1, 2, \ldots, P_{Em}\}, \quad FEs < MaxFEs / 2 xi=xbest1+rand(xbest1xbest2),i{1,2,,PEm},FEs<MaxFEs/2

其中, x b e s t 1 , x b e s t 2 x_{best1},x_{best2} xbest1,xbest2分别表示当前种群中排名第一和第二的优秀个体,该设计不仅使新生成的个体能够继承最强个体的特征,同时通过引入随机扰动因子增强了种群的多样性。

精确的淘汰与生成机制

精确的淘汰与生成机制可视化

改进半参数自适应策略与RSP变异策略

本文提出了一种新的异策略,用来在保障种群多样性的同时,优化个体的进化方向:
F i = 0.5 + 0.1 ⋅ rand , F E s < M a x F E s / 2 F_i = 0.5 + 0.1 \cdot \text{rand}, \quad FEs < MaxFEs / 2 Fi=0.5+0.1rand,FEs<MaxFEs/2

为提升 LSHADE-SPACMA 的局部开发能力,本文引入了 LSHADE-RSP 中的 RSP(Ranking-based Selective Pressure)策略,并在此基础上设计了新的变异机制:
v i = x i + F i ⋅ ( x pbest − x i ) + F i ⋅ ( x pr1 − x r 2 ) v_i = x_i + F_i \cdot (x_{\text{pbest}} - x_i) + F_i \cdot (x_{\text{pr1}} - x_{r2}) vi=xi+Fi(xpbestxi)+Fi(xpr1xr2)

精英存档机制

mLSHADE-SPACMA引入了一种精英存档机制,以确保外部存档中仅保留最优个体,用来优化算法性能,该机制旨在在整个优化过程中,同时保持存档的高质量与多样性,并避免低质量解的持续存在。

mLSHADE-SPACMA伪代码

5.结果展示



6.参考文献

[1] Fu S, Ma C, Li K, et al. Modified LSHADE-SPACMA with new mutation strategy and external archive mechanism for numerical optimization and point cloud registration[J]. Artificial Intelligence Review, 2025, 58(3): 72.

7.代码获取

%  Source codes demo version 1.0 using matlab2023b 
% 
%  Author and programmer: Shengwei Fu  e-Mail: shengwei_fu@163.com 
%                                                                                                     
%  Paper : Modified LSHADE-SPACMA with new mutation strategy and external archive mechanism for numerical optimization and point cloud registration
% 
%  Journal : Artificial Intelligence Review                                                                                                                                                                                                                                      
%_______________________________________________________________________________________________


%%%%%%%%%%%%%%%%%%%
%% This package is a MATLAB/Octave source code of LSHADE-SPACMA which is an improved version of LSHADE.
%% Please see the following paper:
%% * Ali W. Mohamed, Anas A. Hadi, Anas M. Fattouh, and Kamal M. Jambi: L-SHADE with Semi Parameter Adaptation Approach for Solving CEC 2017 Benchmark Problems, Proc. IEEE Congress on Evolutionary Computation (CEC-2017), Spain, June, 2017

%% About L-SHADE, please see following papers:
%% Ryoji Tanabe and Alex Fukunaga: Improving the Search Performance of SHADE Using Linear Population Size Reduction,  Proc. IEEE Congress on Evolutionary Computation (CEC-2014), Beijing, July, 2014.
%% J. Zhang, A.C. Sanderson: JADE: Adaptive differential evolution with optional external archive,?IEEE Trans Evol Comput, vol. 13, no. 5, pp. 945?58, 2009

%% Some code parts were used from:
%% Noor H. Awad, Mostafa Z. Ali, Ponnuthurai N. Suganthan and Robert G. Reynolds: An Ensemble Sinusoidal Parameter Adaptation incorporated with L-SHADE for Solving CEC2014 Benchmark Problems, Proc. IEEE Congress on Evolutionary Computation (CEC-2016), Canada, July, 2016
function [bsf_fit_var,bsf_solution,Conv] = mLSHADE_SPACMA(max_nfes,lb,ub,problem_size,fhd,func)

% clc;
% clear all;
% 
% format long;
% format compact;
Conv = zeros(1,max_nfes);
L_Rate= 0.80;
k1=3;
val_2_reach = 10^(-8);
% fhd=@cec17_func;
% num_prbs = 30;
% runs =51;
% RecordFEsFactor = ...
%     [0.01, 0.02, 0.03, 0.05, 0.1, 0.2, 0.3, 0.4, ...
%     0.5, 0.6, 0.7, 0.8, 0.9, 1.0];
% progress = numel(RecordFEsFactor);

% for problem_size = [10 30 50 100]
    
    % max_nfes = 10000 * problem_size;
    rand('seed', sum(100 * clock));
    % lu = [-100 * ones(1, problem_size); 100 * ones(1, problem_size)];
    lu = [lb * ones(1, problem_size); ub * ones(1, problem_size)];
    % fprintf('Running LSHADE-SPACMA algorithm\n')
    
    % for func = 1:30
        optimum = func * 100.0;
        
        %% Record the best results
        outcome = [];
        
        % fprintf('\n-------------------------------------------------------\n')
        % fprintf('Function = %d, Dimension size = %d\n', func, problem_size)
        
        % allerrorvals = zeros(progress, runs);
        
        % for run_id = 1 : runs
            nfes = 0;
            run_funcvals = [];
           
            %%  parameter settings for L-SHADE
            p_best_rate = 0.11;    
            arc_rate = 1.4; 
            memory_size = 5; 
            pop_size = 18*problem_size;
            max_pop_size = pop_size;
            min_pop_size = 4.0;
            
            %%  parameter settings for Hybridization
            First_calss_percentage=0.5;
            
            %% Initialize the main population
            popold = repmat(lu(1, :), pop_size, 1) + rand(pop_size, problem_size) .* (repmat(lu(2, :) - lu(1, :), pop_size, 1));
            pop = popold; % the old population becomes the current population
            
            fitness = feval(fhd,pop',func);
            fitness = fitness';

            bsf_fit_var = 1e+30;
            bsf_index = 0;
            bsf_solution = zeros(1, problem_size);
            
            %%%%%%%%%%%%%%%%%%%%%%%% for out
            for i = 1 : pop_size
                nfes = nfes + 1;
                if (fitness(i) < bsf_fit_var && isreal(pop(i, :)) && sum(isnan(pop(i, :)))==0 && min(pop(i, :))>=-100 && max(pop(i, :))<=100)
                    bsf_fit_var = fitness(i);
                    bsf_solution = pop(i, :);
                    bsf_index = i;
                end
                
                if nfes > max_nfes;
                    break; 
                end
            end
            %%%%%%%%%%%%%%%%%%%%%%%% for out
            
            run_funcvals = [run_funcvals;ones(pop_size,1)*bsf_fit_var];

            
            memory_sf = 0.5 .* ones(memory_size, 1);
            memory_cr = 0.5 .* ones(memory_size, 1);
            memory_pos = 1;
            
            archive.NP = arc_rate * pop_size; % the maximum size of the archive
            archive.pop = zeros(0, problem_size); % the solutions stored in te archive
            archive.funvalues = zeros(0, 1); % the function value of the archived solutions
            
            memory_1st_class_percentage = First_calss_percentage.* ones(memory_size, 1); % Class#1 probability for Hybridization 
            
            %% Initialize CMAES parameters
            sigma = 0.5;          % coordinate wise standard deviation (step size)
            xmean = rand(problem_size,1);    % objective variables initial point
            mu = pop_size/2;               % number of parents/points for recombination
            weights = log(mu+1/2)-log(1:mu)'; % muXone array for weighted recombination
            mu = floor(mu);
            weights = weights/sum(weights);     % normalize recombination weights array
            mueff=sum(weights)^2/sum(weights.^2); % variance-effectiveness of sum w_i x_i
            
            % Strategy parameter setting: Adaptation
            cc = (4 + mueff/problem_size) / (problem_size+4 + 2*mueff/problem_size); % time constant for cumulation for C
            cs = (mueff+2) / (problem_size+mueff+5);  % t-const for cumulation for sigma control
            c1 = 2 / ((problem_size+1.3)^2+mueff);    % learning rate for rank-one update of C
            cmu = min(1-c1, 2 * (mueff-2+1/mueff) / ((problem_size+2)^2+mueff));  % and for rank-mu update
            damps = 1 + 2*max(0, sqrt((mueff-1)/(problem_size+1))-1) + cs; % damping for sigma usually close to 1

            % Initialize dynamic (internal) strategy parameters and constants
            pc = zeros(problem_size,1);
            ps = zeros(problem_size,1);   % evolution paths for C and sigma
            B = eye(problem_size,problem_size);                       % B defines the coordinate system
            D = ones(problem_size,1);                      % diagonal D defines the scaling
            C = B * diag(D.^2) * B';            % covariance matrix C
            invsqrtC = B * diag(D.^-1) * B';    % C^-1/2
            eigeneval = 0;                      % track update of B and D
            chiN=problem_size^0.5*(1-1/(4*problem_size)+1/(21*problem_size^2));  % expectation of
            
            
            %% main loop
            Hybridization_flag=1; % Indicator flag if we need to Activate CMAES Hybridization
            Conv(1,1:nfes) = min(bsf_fit_var);
            while nfes < max_nfes
 
                pop = popold; % the old population becomes the current population
                [temp_fit, sorted_index] = sort(fitness, 'ascend');
                
                if nfes < max_nfes/2
                    num = floor(0.99*pop_size);              
                    sorted_index1 = sorted_index(num:end);
                    pop(sorted_index1,:) = repmat(pop(sorted_index(1)), pop_size-num+1, 1) + rand(pop_size-num+1, problem_size) .* (repmat(pop(sorted_index(1)) - pop(sorted_index(2)), pop_size-num+1, 1));
                end
                pop = boundConstraint(pop, popold, lb, ub);

                mem_rand_index = ceil(memory_size * rand(pop_size, 1));
                mu_sf = memory_sf(mem_rand_index);
                mu_cr = memory_cr(mem_rand_index);
                mem_rand_ratio = rand(pop_size, 1);
                
                %% for generating crossover rate
                cr = normrnd(mu_cr, 0.1);
                term_pos = find(mu_cr == -1);
                cr(term_pos) = 0;
                cr = min(cr, 1);
                cr = max(cr, 0);

                %% for generating scaling factor
                if(nfes <= 0.5*max_nfes)
                    sf=0.5+.1*rand(pop_size, 1);
                    pos = find(sf <= 0);
                    
                    while ~ isempty(pos)
                        sf(pos)=0.5+0.1*rand(length(pos), 1);
                        pos = find(sf <= 0);
                    end
                else
                    sf = mu_sf + 0.1 * tan(pi * (rand(pop_size, 1) - 0.5));
                    
                    pos = find(sf <= 0);
                    
                    while ~ isempty(pos)
                        sf(pos) = mu_sf(pos) + 0.1 * tan(pi * (rand(length(pos), 1) - 0.5));
                        pos = find(sf <= 0);
                    end
                end
                sf = min(sf, 1);
                
                %% for generating Hybridization Class probability
                Class_Select_Index=(memory_1st_class_percentage(mem_rand_index)>=mem_rand_ratio);
                if(Hybridization_flag==0)
                    Class_Select_Index=or(Class_Select_Index,~Class_Select_Index);%All will be in class#1
                end
                
                %%
                r0 = [1 : pop_size];
                popAll = [pop; archive.pop];
                [r1, r2] = gnR1R2(pop_size, size(popAll, 1), r0);
                
                pNP = max(round(p_best_rate * pop_size), 2); %% choose at least two best solutions
                randindex = ceil(rand(1, pop_size) .* pNP); %% select from [1, 2, 3, ..., pNP]
                randindex = max(1, randindex); %% to avoid the problem that rand = 0 and thus ceil(rand) = 0
                pbest = pop(sorted_index(randindex), :); %% randomly choose one of the top 100p% solutions
                
                Ri1=1:pop_size;
                Rank1=k1*(pop_size-Ri1)+1;
                Pr1=Rank1./sum(Rank1);
                pop1 = [];
                r11 =randsample(pop_size,pop_size,true,Pr1); 
                for j = 1:pop_size 
                    jj = r11(j) ;
                    pop1(j,:) = pop(sorted_index(jj), :);
                end

                vi=[];
                temp=[];
                if(sum(Class_Select_Index)~=0)
                    % vi(Class_Select_Index,:) = pop(Class_Select_Index,:) + sf(Class_Select_Index, ones(1, problem_size)) .* (pbest(Class_Select_Index,:) - pop(Class_Select_Index,:) + pop(r1(Class_Select_Index), :) - popAll(r2(Class_Select_Index), :));
                    vi(Class_Select_Index,:) = pop(Class_Select_Index,:) + sf(Class_Select_Index, ones(1, problem_size)) .* (pbest(Class_Select_Index,:) - pop(Class_Select_Index,:) + pop1((Class_Select_Index), :) - popAll(r2(Class_Select_Index), :));
                end
                
                if(sum(~Class_Select_Index)~=0)
                    for k=1:sum(~Class_Select_Index)
                        temp(:,k) = xmean + sigma * B * (D .* randn(problem_size,1)); % m + sig * Normal(0,C)
                    end
                    vi(~Class_Select_Index,:) = temp';
                end
                
                if(~isreal(vi))
                    Hybridization_flag=0;
                    continue;
                end

                
                % vi = boundConstraint(vi, pop, lu);
                vi = boundConstraint(vi, pop, lb, ub);

                
                mask = rand(pop_size, problem_size) > cr(:, ones(1, problem_size)); % mask is used to indicate which elements of ui comes from the parent
                rows = (1 : pop_size)'; cols = floor(rand(pop_size, 1) * problem_size)+1; % choose one position where the element of ui doesn't come from the parent
                jrand = sub2ind([pop_size problem_size], rows, cols); mask(jrand) = false;
                ui = vi; ui(mask) = pop(mask);

                children_fitness = feval(fhd, ui', func);
                children_fitness = children_fitness';
                
                nfes1=nfes;
                %%%%%%%%%%%%%%%%%%%%%%%% for out
                for i = 1 : pop_size
                    nfes = nfes + 1;
                    if (children_fitness(i) < bsf_fit_var && isreal(ui(i, :)) && sum(isnan(ui(i, :)))==0 && min(ui(i, :))>=-100 && max(ui(i, :))<=100)
                        bsf_fit_var = children_fitness(i);
                        bsf_solution = ui(i, :);
                        bsf_index = i;
                    end
                    
                    if nfes > max_nfes;
                        break;
                    end
                end
                Conv(1,nfes1:nfes) = bsf_fit_var;
                %%%%%%%%%%%%%%%%%%%%%%%% for out
                
                run_funcvals = [run_funcvals;ones(pop_size,1)*bsf_fit_var];
                
                dif = abs(fitness - children_fitness);
                
                
                %% I == 1: the parent is better; I == 2: the offspring is better
                Child_is_better_index = (fitness > children_fitness);
                goodCR = cr(Child_is_better_index == 1);
                goodF = sf(Child_is_better_index == 1);
                dif_val = dif(Child_is_better_index == 1);
                dif_val_Class_1 = dif(and(Child_is_better_index,Class_Select_Index) == 1);
                dif_val_Class_2 = dif(and(Child_is_better_index,~Class_Select_Index) == 1);
                
                archive = updateArchive(archive, popold(Child_is_better_index == 1, :), fitness(Child_is_better_index == 1));
                
                [fitness, Child_is_better_index] = min([fitness, children_fitness], [], 2);

                popold = pop;
                popold(Child_is_better_index == 2, :) = ui(Child_is_better_index == 2, :);
                
                num_success_params = numel(goodCR);
                
                if num_success_params > 0
                    sum_dif = sum(dif_val);
                    dif_val = dif_val / sum_dif;
                    
                    %% for updating the memory of scaling factor
                    memory_sf(memory_pos) = (dif_val' * (goodF .^ 2)) / (dif_val' * goodF);
                    
                    %% for updating the memory of crossover rate
                    if max(goodCR) == 0 || memory_cr(memory_pos)  == -1
                        memory_cr(memory_pos)  = -1;
                    else
                        memory_cr(memory_pos) = (dif_val' * (goodCR .^ 2)) / (dif_val' * goodCR);
                    end
                    
                    if (Hybridization_flag==1)% if the Hybridization is activated
                        memory_1st_class_percentage(memory_pos) = memory_1st_class_percentage(memory_pos)*L_Rate+ (1-L_Rate)*(sum(dif_val_Class_1) / (sum(dif_val_Class_1) + sum(dif_val_Class_2)));
                        memory_1st_class_percentage(memory_pos)=min(memory_1st_class_percentage(memory_pos),0.8);
                        memory_1st_class_percentage(memory_pos)=max(memory_1st_class_percentage(memory_pos),0.2);
                    end
                    
                    memory_pos = memory_pos + 1;
                    if memory_pos > memory_size;  memory_pos = 1; end
                end
                
                %% for resizing the population size
                plan_pop_size = round((((min_pop_size - max_pop_size) / max_nfes) * nfes) + max_pop_size);
                
                if pop_size > plan_pop_size
                    reduction_ind_num = pop_size - plan_pop_size;
                    if pop_size - reduction_ind_num <  min_pop_size; reduction_ind_num = pop_size - min_pop_size;end
                    
                    pop_size = pop_size - reduction_ind_num;
                    for r = 1 : reduction_ind_num
                        [valBest, indBest] = sort(fitness, 'ascend');
                        worst_ind = indBest(end);
                        popold(worst_ind,:) = [];
                        pop(worst_ind,:) = [];
                        fitness(worst_ind,:) = [];
                        Child_is_better_index(worst_ind,:) = [];
                    end
                    
                    archive.NP = round(arc_rate * pop_size);
                    
                    if size(archive.pop, 1) > archive.NP
                        % rndpos = randperm(size(archive.pop, 1));
                        % rndpos = rndpos(1 : archive.NP);
                        % archive.pop = archive.pop(rndpos, :);

                         [~, sortIdx] = sort(archive.funvalues);
                         bestIdx = sortIdx(1:archive.NP);
                         archive.pop = popAll(bestIdx, :);
                         archive.funvalues = archive.funvalues(bestIdx, :);  

                    end
                    
                    %% update CMA parameters
                    mu = pop_size/2;               % number of parents/points for recombination 
                    weights = log(mu+1/2)-log(1:mu)'; % muXone array for weighted recombination
                    mu = floor(mu);
                    weights = weights/sum(weights);     % normalize recombination weights array
                    mueff=sum(weights)^2/sum(weights.^2); % variance-effectiveness of sum w_i x_i
                end
               
                %% CMAES Adaptation
                if(Hybridization_flag==1)
                    % Sort by fitness and compute weighted mean into xmean
                    [~, popindex] = sort(fitness);  % minimization
                    xold = xmean;
                    xmean = popold(popindex(1:mu),:)' * weights;  % recombination, new mean value
                    
                    % Cumulation: Update evolution paths
                    ps = (1-cs) * ps ...
                        + sqrt(cs*(2-cs)*mueff) * invsqrtC * (xmean-xold) / sigma;
                    hsig = sum(ps.^2)/(1-(1-cs)^(2*nfes/pop_size))/problem_size < 2 + 4/(problem_size+1);
                    pc = (1-cc) * pc ...
                        + hsig * sqrt(cc*(2-cc)*mueff) * (xmean-xold) / sigma;
                    
                    % Adapt covariance matrix C
                    artmp = (1/sigma) * (popold(popindex(1:mu),:)' - repmat(xold,1,mu));  % mu difference vectors
                    C = (1-c1-cmu) * C ...                   % regard old matrix
                        + c1 * (pc * pc' ...                % plus rank one update
                        + (1-hsig) * cc*(2-cc) * C) ... % minor correction if hsig==0
                        + cmu * artmp * diag(weights) * artmp'; % plus rank mu update
                    
                    % Adapt step size sigma
                    sigma = sigma * exp((cs/damps)*(norm(ps)/chiN - 1));
                    
                    % Update B and D from C
                    if nfes - eigeneval > pop_size/(c1+cmu)/problem_size/10  % to achieve O(problem_size^2)
                        eigeneval = nfes;
                        C = triu(C) + triu(C,1)'; % enforce symmetry
                        if(sum(sum(isnan(C)))>0 || sum(sum(~isfinite(C)))>0 || ~isreal(C))
                            Hybridization_flag=0;
                            continue;
                        end
                        [B,D] = eig(C);           % eigen decomposition, B==normalized eigenvectors
                        D = sqrt(diag(D));        % D contains standard deviations now
                        invsqrtC = B * diag(D.^-1) * B';
                    end
                    
                end
                
            end %%%%%%%%nfes
            
            %% Violation Checking
            if(max(bsf_solution)>100)
                fprintf('%d th run, Above Max\n', run_id)
            end
            
            if(min(bsf_solution)<-100)
                fprintf('%d th run, Below Min\n', run_id)
            end
            
            if(~isreal(bsf_solution))
                fprintf('%d th run, Complix\n', run_id)
            end
             
            bsf_error_val = abs(bsf_fit_var - optimum);
            if bsf_error_val < val_2_reach
                bsf_error_val = 0;
            end
            
            if(sum(isnan(bsf_solution))>0)
                fprintf('%d th run, NaN\n', run_id)
            end
            
            % fprintf('%d th run, best-so-far error value = %1.8e\n', run_id , bsf_error_val)
            outcome = [outcome bsf_error_val];
            Conv = Conv(1,1:max_nfes); 
            Conv(1,max_nfes) = bsf_fit_var;
            %% From Noor Code ( print files )
            % errorVals= [];
            % for w = 1 : progress
            %     bestold = run_funcvals(RecordFEsFactor(w) * max_nfes) - optimum;
            %     if abs(bestold)>1e-8
            %         errorVals(w)= abs(bestold);
            %     else
            %         bestold=0;
            %         errorVals(w)= bestold;
            %     end
            % end
            % allerrorvals(:, run_id) = errorVals;
            
        % end %% end 1 run
        
        % fprintf('\n')
        % fprintf('min error value = %1.8e, max = %1.8e, median = %1.8e, mean = %1.8e, std = %1.8e\n', min(outcome), max(outcome), median(outcome), mean(outcome), std(outcome))
        % 
        % 
        % file_name=sprintf('Results\\LSHADE_SPACMA_CEC2017_Problem#%s_problemSize#%s',int2str(func),int2str(problem_size));
        % save(file_name,'outcome', 'allerrorvals');
        % 
        % 
        % file_name=sprintf('Results\\LSHADE_SPACMA_%s_%s.txt',int2str(func),int2str(problem_size));
        % save(file_name, 'allerrorvals', '-ascii');
        
    % end %% end 1 function run
    
% end
end









function [r1, r2] = gnR1R2(NP1, NP2, r0)

% gnA1A2 generate two column vectors r1 and r2 of size NP1 & NP2, respectively
%    r1's elements are choosen from {1, 2, ..., NP1} & r1(i) ~= r0(i)
%    r2's elements are choosen from {1, 2, ..., NP2} & r2(i) ~= r1(i) & r2(i) ~= r0(i)
%
% Call:
%    [r1 r2 ...] = gnA1A2(NP1)   % r0 is set to be (1:NP1)'
%    [r1 r2 ...] = gnA1A2(NP1, r0) % r0 should be of length NP1
%
% Version: 2.1  Date: 2008/07/01
% Written by Jingqiao Zhang (jingqiao@gmail.com)

NP0 = length(r0);

r1 = floor(rand(1, NP0) * NP1) + 1;
%for i = 1 : inf
for i = 1 : 99999999
    pos = (r1 == r0);
    if sum(pos) == 0
        break;
    else % regenerate r1 if it is equal to r0
        r1(pos) = floor(rand(1, sum(pos)) * NP1) + 1;
    end
    if i > 1000, % this has never happened so far
        error('Can not genrate r1 in 1000 iterations');
    end
end

r2 = floor(rand(1, NP0) * NP2) + 1;
%for i = 1 : inf
for i = 1 : 99999999
    pos = ((r2 == r1) | (r2 == r0));
    if sum(pos)==0
        break;
    else % regenerate r2 if it is equal to r0 or r1
        r2(pos) = floor(rand(1, sum(pos)) * NP2) + 1;
    end
    if i > 1000, % this has never happened so far
        error('Can not genrate r2 in 1000 iterations');
    end
end
end

function archive = updateArchive(archive, pop, funvalue)
% Update the archive with input solutions
%   Step 1: Add new solution to the archive
%   Step 2: Remove duplicate elements
%   Step 3: If necessary, randomly remove some solutions to maintain the archive size
%
% Version: 1.1   Date: 2008/04/02
% Written by Jingqiao Zhang (jingqiao@gmail.com)

if archive.NP == 0, return; end

if size(pop, 1) ~= size(funvalue,1), error('check it'); end

% Method 2: Remove duplicate elements
popAll = [archive.pop; pop ];
funvalues = [archive.funvalues; funvalue ];
[dummy IX]= unique(popAll, 'rows');
if length(IX) < size(popAll, 1) % There exist some duplicate solutions
  popAll = popAll(IX, :);
  funvalues = funvalues(IX, :);
end

if size(popAll, 1) <= archive.NP   % add all new individuals
  archive.pop = popAll;
  archive.funvalues = funvalues;
else                % randomly remove some solutions
  % rndpos = randperm(size(popAll, 1)); % equivelent to "randperm";
  % rndpos = rndpos(1 : archive.NP);
  % 
  % archive.pop = popAll  (rndpos, :);
  % archive.funvalues = funvalues(rndpos, :);

[~, sortIdx] = sort(funvalues);

% Select the best NP solutions
bestIdx = sortIdx(1:archive.NP);

% Update archive
archive.pop = popAll(bestIdx, :);
archive.funvalues = funvalues(bestIdx, :);

end
end



function vi = boundConstraint (vi, pop, lb,ub)

% if the boundary constraint is violated, set the value to be the middle
% of the previous value and the bound
%
% Version: 1.1   Date: 11/20/2007
% Written by Jingqiao Zhang, jingqiao@gmail.com

[NP, D] = size(pop);  % the population size and the problem's dimension

%% check the lower bound
% xl = repmat(lb, NP, 1);
% pos = vi < xl;
% vi(pos) = (pop(pos) + xl(pos)) / 2;

for i = 1:NP
    for j = 1:D
        if vi(i,j) < lb
            vi(i,j) = (pop(i,j)+lb)/2;
        end
    end
end

%% check the upper bound
% xu = repmat(ub, NP, 1);
% pos = vi > xu;
% vi(pos) = (pop(pos) + xu(pos)) / 2;

for i = 1:NP
    for j = 1:D
        if vi(i,j) > ub
            vi(i,j) = (pop(i,j)+ub)/2;
        end
    end
end
end

8.读者交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小O的算法实验室

谢谢大佬的肯定!

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

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

打赏作者

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

抵扣说明:

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

余额充值