关于单目标群智能算法的一些思考

      关于计算机算法发展至今,已有很多不同的分类,目前运用最多是泛化群智能优化算法。譬如:粒子群优化算法(PSO)、鲸鱼优化算法(WOA)、灰狼优化算法(GWO)、蜻蜓优化算法(DA)、宇宙优化算法(MVO)、飞蛾扑火优化算法(MFO)、蚱蜢优化算法等。

      关于这些算法的具体讲解,我们都可以在不同的学习网站上浏览到,如:CSDN、知乎等。对于具体算法的讲解,我这里不做赘述,想在这里叙述一下这些算法的共同规律,以便帮助同学对这部分内容有更好的理解。

   群智能优化算法的共同点:

 1、随机初始化

function X=initialization(SearchAgents_no,dim,ub,lb)%SearchAgents_no为种群数量;dim为解决问题的维度;ub变量上界;lb变量下界

Boundary_no= size(ub,2); % numnber of boundaries

% If the boundaries of all variables are equal and user enter a signle
% number for both ub and lb
if Boundary_no==1
    X=rand(SearchAgents_no,dim).*(ub-lb)+lb;
end

% If each variable has a different lb and ub
if Boundary_no>1
    for i=1:dim
        ub_i=ub(i);
        lb_i=lb(i);
        X(:,i)=rand(SearchAgents_no,1).*(ub_i-lb_i)+lb_i;
    end
end

对于一个我们要解决的问题,首先要清楚解决问题的维度,可以粗浅理解为几个X,例如我们有两个X(X1,X2),则我们要解决的问题的维度即为2,在源代码中,我们要规定变量X的范围,不同的X可以有不同的范围,当然根据实际问题,所有变量(X1,X2,......,Xn)的范围也可一致。在上面代码中所呈现的就是lb与ub,在上面的代码中,群数量被规定为SearchAgents_no,一般原始算法中的种群数量为30,则随机初始化过程的结果,可以理解为30行,n列(解决问题的维度为n)的矩阵。

在设置过程中,还有一个重要的参数---最大迭代次数,即为Max_iteration。算法的终止条件有两个,一个为收敛精度(在一定时间内,收敛下降度没有超过设置阈值,其实就是已经差不多最优了,没有必要继续进行下去了。);另一个就是最大迭代次数,一般算法中均以此作为最后的迭代终止条件。具体的数值可以根据相应的参考文献,参照设置。

对于一个具体问题,问题的维度(dim),变量的上下边界,种群数量可以根据实际情况设置,在原始代码提出的时候,会有一系列的测试函数来进行验证。、

[lb,ub,dim,fobj]=Get_Functions_details(Function_name);

上面的代码即为从测试函数中提取维度、变量上下边界,和目标函数。关于目标函数,在下面的内容中具体阐述。

2、算法的具体过程

在算法进入迭代循环之前,也就是不断寻优过程之前,会对之前随机化初始矩阵进行适应度计算,如果种群数量为30,则有30个适应度值,通过比较它们的大小,将最小(或最大,一般为最小)作为初始的最佳适应度值,进入后续的迭代寻优中进行计算。

for i=1:size(Positions,1)
    Fitness(1,i)=fobj(Positions(i,:));
end

上面的代码展示的就是,在迭代寻优之前,对所有种群进行适应度值的计算。

值得一提的是适应度值的概念,可以简单理解为每个种群(每个行向量)通过目标函数公式,计算后数值的大小。

2.1 全局探索与局部开发

全局探索和局部开发两个阶段决定着算法的搜寻质量,两者互联互通,先进行全局大范围的搜索,在进行到一定阶段后,再执行小范围(局部)的精确寻优。至于具体如何进行全局搜索和局部开发,每种算法的逻辑思路不同,可结合代码具体分析。全局探索和局部开发之间存在一个过渡,即算法执行到何时,由全局探索转向局部开发。这个过渡阶段,几乎存在于每个算法逻辑之中。这里以HHO(哈里斯鹰)算法和SSA(樽海鞘)算法为例进行介绍。

在HHO算法中,猎物的能量被用来完成这个过渡过程,它的模型如下所示:

                                                  

上式中,E 代表猎物的逃逸能量, E0 表示能量强度的初始状态。T为最大迭代次数,t为算法实际迭代次数,作为常规HHO的停止准则。

在SSA算法中,

                                                      

上式中,t代表当前迭代,T表示迭代的最大数。 参数具有重要作用,可以在探索和开发趋势之间建立一个适当的平衡。

以上就是两种算法由全局探索向局部开发阶段过渡的具体表现形式。不同的算法依据逻辑的不同,过渡形式也不尽相同。

至于说全局探索和局部开发的具体实现,各种算法就是八仙过海各显神通了。目前大多数泛化群智能算法都是依据生物的觅食或者生存/生活规律总结而来的。大家可以参考各种算法的原始论文,里面有详细解读。这里简单举例樽海鞘算法。

while l<Max_iter+1/设置的最大迭代限制
    
    c1 = 2*exp(-(4*l/Max_iter)^2); % Eq. (3.2) in the paper/全局探索和局部开发过渡
    
    for i=1:size(SalpPositions,1)
        
        SalpPositions= SalpPositions';
        
        if i<=N/2   /这里根据樽海鞘的觅食特性将种群分为两类,分别为领导者和追随者,首先进行领导者的位置更新。
            for j=1:1:dim
                c2=rand();
                c3=rand();
                %%%%%%%%%%%%% % Eq. (3.1) in the paper %%%%%%%%%%%%%%
                if c3<0.5 
                    SalpPositions(j,i)=FoodPosition(j)+c1*((ub(j)-lb(j))*c2+lb(j));
                else
                    SalpPositions(j,i)=FoodPosition(j)-c1*((ub(j)-lb(j))*c2+lb(j));
                end
                %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            end
            
        elseif i>N/2 && i<N+1   /再次进行追随者的位置更新。
            point1=SalpPositions(:,i-1);
            point2=SalpPositions(:,i);
            
            SalpPositions(:,i)=(point2+point1)/2; % % Eq. (3.4) in the paper
        end
        
        SalpPositions= SalpPositions';
    end
    
    for i=1:size(SalpPositions,1)  /更新完成后,进行边界条件的限制界定。
        
        Tp=SalpPositions(i,:)>ub';Tm=SalpPositions(i,:)<lb';SalpPositions(i,:)=(SalpPositions(i,:).*(~(Tp+Tm)))+ub'.*Tp+lb'.*Tm;
        
        SalpFitness(1,i)=fobj(SalpPositions(i,:));
        
        if SalpFitness(1,i)<FoodFitness
            FoodPosition=SalpPositions(i,:);
            FoodFitness=SalpFitness(1,i);
            
        end
    end
    
    Convergence_curve(l)=FoodFitness;/将得到的个体的适应度值进行储存,放置在收敛曲线中
    l = l + 1;/标记迭代次数,迭代累计。
end

当执行while的循环中,个体的适应度值不断进行比较。迭代完成后,得出最佳的适应度值。

到这里,算法的整个流程大体清楚,主要参数和流程如上所述。

上面有提到过目标函数问题。针对不同的实际问题,自然目标函数的设置不一样,需要自行编写相关程序。为了方便对算法性能进行测试,已有相关学者编写了标准测试函数。

function [lb,ub,dim,fobj] = Get_Functions_details(F)


switch F
    case 'F1'
        fobj = @F1;
        lb=-100;
        ub=100;
        dim=30;
        
    case 'F2'
        fobj = @F2;
        lb=-10;
        ub=10;
        dim=10;
        
    case 'F3'
        fobj = @F3;
        lb=-100;
        ub=100;
        dim=10;

end

end

% F1

function o = F1(x)
o=sum(x.^2);
end

% F2

function o = F2(x)
o=sum(abs(x))+prod(abs(x));
end

% F3

function o = F3(x)
dim=size(x,2);
o=0;
for i=1:dim
    o=o+sum(x(1:i))^2;
end
end

上面展示的是F1到F3,三个标准测试函数。可以看到在Get_Functions_details中,我们读取了函数的边界、维度、目标函数,这里的目标函数运用了@的技巧,具体的函数形式也以 function o = F(x) 的形式给出。

大概的算法流程基本如此,有需要一些算法程序,或者不懂的可以私信讨论,一起学习。

猜你喜欢

转载自blog.csdn.net/weixin_46062179/article/details/120669957