经典优化算法之飞蛾扑火(MFO),原理公式详解,附matlab代码

飞蛾扑火优化算法(Moth-Flame Optimization,MFO)是一种新型元启发式优化算法,该算法是受飞蛾围绕火焰飞行启发而提出的,具有搜索速度快、寻优能力强的特点。该成果于2015年发表在知名SCI期刊Knowledge-Based Systems上。目前谷歌学术上查询被引3575次。

9fd9881fa558a757a504a1cb74c32b1b.png

MFO算法通过飞蛾选择火焰、飞蛾围绕火焰飞行、飞蛾扑焰行为,三个主要操作模拟了飞蛾围绕火焰飞行行为,最后选取最优解。

算法原理

(1)飞蛾选择火焰

飞蛾个体表示着优化问题的候选解,飞蛾在优化空间的位置代表求解优化问题的变量,通过在优化空间中改变位置向量来向全局最佳点靠拢,火焰便是飞蛾到当前迭代次数所找到的最佳位置,矩阵M表示飞蛾的位置,数学模型如下式表示:  其中n代表飞蛾的个数;d代表控制变量的数量(维度);矩阵OM存储飞蛾的适应度值,n代表飞蛾的个数,数学模型如下式表示:  MFO算法中要求每只飞蛾仅利用与之对应的唯一火焰更新其自身位置,从而避免算法陷入局部极值情况,大大增强了算法的全局搜索能力。因此,搜索空间中飞蛾位置与火焰位置是相同维度的变量矩阵矩阵F表示火焰的位置,火焰的适应度值存储在矩阵OF中,数学模型如下式表示:   其中n代表飞蛾的个数;d代表控制变量的数量(维度)。

(2)飞蛾围绕火焰飞行

飞蛾实际上是在搜索空间内移动的搜索个体,每一只飞蛾个体环绕在一个火焰的周围,一旦搜索到更好的解,便更新为下一代中火焰的位置。

MFO算法是近似于优化问题中全局最佳的三元组:  

I是产生一个随机的飞蛾种群和相应的适应度值的函数,其系统模型如下:  P是使飞蛾在搜索空间里移动的主函数。P接受矩阵M,并返回更新后的M。

(3)飞蛾扑焰行为

自然界中具有趋光特性的飞蛾  会朝着距离自身最近的亮光(火焰)  移动。飞蛾扑焰的移动轨迹为选取了对数螺线曲线,算法的对数螺旋曲线定义如下: 这里简单插一嘴:现在很多改进算法都有用到螺旋搜索的思想。可以看到最早的这种螺旋搜索的思想还是来自于飞蛾扑火这种经典算法!不得不感叹一下!

其中:  为飞蛾更新后的位置;Di表示的是第i个飞蛾的位置与第j个火焰的位置之间的距离;b是常量,该常量与螺旋形状相关;t是随机生成的数字,取值区间为[-1,1],当t=-1时飞蛾离火焰最远,当t =1时飞蛾离火焰最近。  

其中:  为飞蛾  与火焰  的距离。

结果展示

以为CEC2005函数集为例,进行结果展示:

b3810145f6c0b4cc3baf5e4e51741923.png

2f924b4917a520d721a1284e439b489b.png

66e73da84f78515f83d28276d2f97ff7.png

0d840d24ec7416fbe7e3470b76e53d5b.png

62d6d9c1ad8e414357e38b9bfef2c053.png

 MATLAB核心代码

%% 淘个代码 %%
% 微信公众号搜索:淘个代码,获取更多代码
% 飞蛾扑火优化算法(MFO)
function [Best_flame_score,Best_flame_pos,Convergence_curve]=MFO(N,Max_iteration,lb,ub,dim,fobj,handles,value)


display('MFO is optimizing your problem');


%Initialize the positions of moths
Moth_pos=initialization(N,dim,ub,lb);


Convergence_curve=zeros(1,Max_iteration);


Iteration=1;


% Main loop
while Iteration<Max_iteration+1
    
    % Number of flames Eq. (3.14) in the paper
    Flame_no=round(N-Iteration*((N-1)/Max_iteration));
    
    for i=1:size(Moth_pos,1)
        
        % Check if moths go out of the search spaceand bring it back
        Flag4ub=Moth_pos(i,:)>ub;
        Flag4lb=Moth_pos(i,:)<lb;
        Moth_pos(i,:)=(Moth_pos(i,:).*(~(Flag4ub+Flag4lb)))+ub.*Flag4ub+lb.*Flag4lb;  
        
        % Calculate the fitness of moths
        Moth_fitness(1,i)=fobj(Moth_pos(i,:));
        All_fitness(1,i)=Moth_fitness(1,i);
        
    end
       
    if Iteration==1
        % Sort the first population of moths
        [fitness_sorted I]=sort(Moth_fitness);
        sorted_population=Moth_pos(I,:);
        
        % Update the flames
        best_flames=sorted_population;
        best_flame_fitness=fitness_sorted;
    else
        
        % Sort the moths
        double_population=[previous_population;best_flames];
        double_fitness=[previous_fitness best_flame_fitness];
        
        [double_fitness_sorted I]=sort(double_fitness);
        double_sorted_population=double_population(I,:);
        
        fitness_sorted=double_fitness_sorted(1:N);
        sorted_population=double_sorted_population(1:N,:);
        
        % Update the flames
        best_flames=sorted_population;
        best_flame_fitness=fitness_sorted;
    end
    
    % Update the position best flame obtained so far
    Best_flame_score=fitness_sorted(1);
    Best_flame_pos=sorted_population(1,:);
      
    previous_population=Moth_pos;
    previous_fitness=Moth_fitness;
    
    % a linearly dicreases from -1 to -2 to calculate t in Eq. (3.12)
    a=-1+Iteration*((-1)/Max_iteration);
    
    for i=1:size(Moth_pos,1)
        
        for j=1:size(Moth_pos,2)
            if i<=Flame_no % Update the position of the moth with respect to its corresponsing flame
                
                % D in Eq. (3.13)
                distance_to_flame=abs(sorted_population(i,j)-Moth_pos(i,j));
                b=1;
                t=(a-1)*rand+1;
                
                % Eq. (3.12)
                Moth_pos(i,j)=distance_to_flame*exp(b.*t).*cos(t.*2*pi)+sorted_population(i,j);
            end
            
            if i>Flame_no % Upaate the position of the moth with respct to one flame
                
                % Eq. (3.13)
                distance_to_flame=abs(sorted_population(i,j)-Moth_pos(i,j));
                b=1;
                t=(a-1)*rand+1;
                
                % Eq. (3.12)
                Moth_pos(i,j)=distance_to_flame*exp(b.*t).*cos(t.*2*pi)+sorted_population(Flame_no,j);
            end
            
        end
        
    end
    
    Convergence_curve(Iteration)=Best_flame_score;
    
     if Iteration>2
        line([Iteration-1 Iteration], [Convergence_curve(Iteration-1) Convergence_curve(Iteration)],'Color','b')
        xlabel('Iteration');
        ylabel('Best score obtained so far');        
        drawnow
    end
 
    
    set(handles.itertext,'String', ['The current iteration is ', num2str(Iteration)])
    set(handles.optimumtext,'String', ['The current optimal value is ', num2str(Best_flame_score)])
    if value==1
        hold on
        scatter(Iteration*ones(1,N),All_fitness,'.','k')
    end
    
    Iteration=Iteration+1; 
end

参考文献

[1] Mirjalili S. Moth-flame optimization algorithm: A novel nature-inspired heuristic paradigm[J]. Knowledge-based systems, 2015, 89: 228-249.

完整代码获取方式:后台回复关键字:

TGDM880

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是MATLAB实现的MFO算法代码: ```matlab function [bestFit, bestInd] = MFO(func, dim, lb, ub, maxIter) % 参数说明: % func:优化函数 % dim:优化问题的维度 % lb:每个维度的下界 % ub:每个维度的上界 % maxIter:最大迭代次数 % MFO算法参数设置 N = 20; % 飞蛾数量 a = 0.2; % 吸引度系数 b = 1; % 距离衰减系数 tmax = maxIter; % 最大迭代次数 % 初始化飞蛾位置和适应度值 X = zeros(N,dim); F = zeros(N,1); for i = 1:N X(i,:) = lb + (ub-lb).*rand(1,dim); % 随机初始化位置 F(i) = func(X(i,:)); % 计算适应度值 end % 记录最佳适应度值和最佳位置 [bestFit, bestInd] = min(F); bestX = X(bestInd,:); % 迭代搜索 for t = 1:tmax % 计算飞蛾之间的距离 D = pdist2(X,X); D(D==0) = Inf; % 计算每个飞蛾的吸引度 A = zeros(N,1); for i = 1:N for j = 1:N A(i) = A(i) + (F(j)<F(i))*exp(-b*D(i,j)); end end A = a*A/sum(A); % 更新飞蛾位置 for i = 1:N % 计算移动方向 dir = zeros(1,dim); for j = 1:N if j ~= i dir = dir + A(j)*(X(j,:)-X(i,:))/D(i,j); end end % 更新位置 X(i,:) = X(i,:) + dir; % 边界处理 X(i,X(i,:)<lb) = lb(X(i,:)<lb); X(i,X(i,:)>ub) = ub(X(i,:)>ub); % 计算适应度值 F(i) = func(X(i,:)); % 更新最佳位置和最佳适应度值 if F(i) < bestFit bestFit = F(i); bestX = X(i,:); end end % 显示迭代信息 disp(['Iteration ' num2str(t) ': Best Fit = ' num2str(bestFit)]); end % 返回最佳适应度值和最佳位置 bestFit = -bestFit; % 将最小值转换为最大值 bestInd = -1; end ``` 使用时,只需要传入优化函数、维度、下界、上界和最大迭代次数等参数即可,如下所示: ```matlab % 优化函数 func = @(x) sum(x.^2); % 优化问题的维度 dim = 10; % 每个维度的下界和上界 lb = -10*ones(1,dim); ub = 10*ones(1,dim); % 最大迭代次数 maxIter = 100; % 调用MFO函数进行优化 [bestFit, bestInd] = MFO(func, dim, lb, ub, maxIter); % 显示最佳适应度值和最佳位置 disp(['Best Fit = ' num2str(bestFit)]); disp(['Best Ind = ' num2str(bestInd)]); ``` 注意,这里的优化函数必须是一个能够计算出某个位置的适应度值的函数。在这里,我使用了一个简单的函数 $f(x)=\sum_{i=1}^n x_i^2$ 作为优化函数进行测试。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

今天吃饺子

不想刀我的可以选择爱我

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

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

打赏作者

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

抵扣说明:

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

余额充值