(转载)基于鱼群算法的函数寻优算法(matlab实现)

1 理论基础

1.1 人工鱼群算法概述

        人工鱼群算法是李晓磊等人于2002年提出的一类基于动物行为的群体智能优化算法。该算法是通过模拟鱼类的觅食、聚群、追尾、随机等行为在搜索域中进行寻优,是集群体智能思想的一个具体应用。生物的视觉是极其复杂的,它能快速感知大量的空间事物,这是任何仪器和程序都难以比拟的,为了实施的简便和有效,在鱼群模式中应用了如下方法实现虚拟人工鱼的视觉:

图1 人工鱼的视野和移动步长 

        
如图1所示,一条虚拟人工鱼实体的当前位置为X,它的视野范围为Visual,位置Xv为其在某时刻的视点所在的位置,如果该位置的食物浓度高于当前位置,则考虑向该位置方向前进一步,即到

达位置Xnext;如果位置Xv不比当前位置食物浓度更高,则继续巡视视野内的其他位置。巡视的次数

越多,则对视野内的状态了解越全面,从而对周围的环境有一个全方面立体的认知,这有助于做出相应的判断和决策。当然,对于状态多或无限状态的环境也不必全部遍历,允许一定的不确定性对于摆脱局部最优,从而寻找全局最优是有帮助的。

1.2 人工鱼群算法的主要行为

        鱼类通常具有如下行为:

        觅食行为:这是生物的一种最基本的行为,也就是趋向食物的一种活动;一般可以认为这种行为是通过视觉或味觉感知水中的食物量或浓度来选择趋向的。因此,以上所述的视觉概念可以应用于该行为。

        聚群行为:这是鱼类较常见的一种现象,大量或少量的鱼都能聚集成群,这是它们在进化过程中形成的一种生存方式,可以进行集体觅食和躲避敌害。

        追尾行为:当某一条鱼或几条鱼发现食物时,它们附近的鱼会尾随其后快速游过来,进而导致更远处的鱼也尾随过来。

        随机行为:鱼在水中悠闲地自由游动,基本上是随机的,其实它们也是为了更大范围地寻觅食物或同伴。

        以上是鱼的几个典型行为,这些行为在不同时刻会相互转换,而这种转换通常是鱼通过对环境的感知来自主实现的,这些行为与鱼的觅食和生存都有着密切的关系,并且与优化问题的解决也有着密切的关系。

        行为评价是用来模拟鱼能够自主行为的一种方式。在解决优化问题中,可以选用两种简单的评价方式:一种是选择最优行为执行,也就是在当前状态下,哪一种行为向优的方向前进最大,就选择哪种行为;另一种是选择较优行为前进,也就是任选一种行为,只要能向优的方向前进即可。

1.3 问题的解决

        问题的解决是通过自治体在自主的活动过程中以某种形式表现出来的。在寻优过程中,通常会有两种方式表现出来:一种形式是通过人工鱼最终的分布情况来确定最优解的分布,通常随着寻优过程的进展,人工鱼往往会聚集在极值点的周围,而且全局最优的极值点周围通常能聚集较多的人工鱼;另一种形式是在人工鱼的个体状态之中表现出来的,即在寻优的过程中,跟踪记录最优个体的状态,就类似于遗传算法采用的方式。

        鱼群模式不同于传统的问题解决方法,它提出了一种新的优化模式——人工鱼群算法,这一模式具备分布处理、参数和初值的鲁棒性强等能力。

2 案例背景

2.1 问题描述

        案例1:

        一元函数的优化实例:

 

        案例2:

        二元函数的优化实例:

        这两个函数的图像如图2和图3所示:

2.2 解题思路及步骤

        1.变量及函数定义

        人工鱼群算法中用到的变量参数如表1所列。

表1 变量参数

         人工鱼群算法中用到的函数如表2所列。

表2 主要函数

        2.算法流程

        人工鱼群算法流程图如图4所示。

图4 人工鱼群算法流程图

        3.人工鱼群算法实现

        人工鱼群算法是一种高效的智能优化算法,主要的鱼群行为有鱼群初始化、觅食行为、聚群行为、追尾行为和随机行为。

        (1)鱼群初始化

        鱼群中的每条人工鱼均为一组实数,是在给定范围内产生的随机数组。例如,鱼群大小为N,有两个待优化的参数x,y,范围分别为[x1,x2]和[y1,y2],则要产生一个2行N列的初始鱼群,每列表示一条人工鱼的两个参数。

        (2)觅食行为

        设人工鱼当前状态为Xi,在其感知范围内随机选择一个状态Xj,如果在求极大问题中,Yi<Yj(或在求极小问题中,Yi>Yj,因极大和极小问题可以互相转换,所以以下均讨论极大问题),则向该方向前进一步;反之,再重新随机选择状态X;,判断是否满足前进条件。这样反复尝试try_number次后,如果仍不满足前进条件,则随机移动一步。觅食过程如图5所示。

图5 觅食行为过程 

        (3)聚群行为

        设人工鱼当前状态为Xi,探索当前领域内(即di,j<Visual)的伙伴数目nf及中心位置Xc,如果Yc/nf>δYi(δ为拥挤度),
表明伙伴中心有较多的食物并且不太拥挤,则朝伙伴的中心位置方向前进一步;否则执行觅食行为。聚群过程如图6所示。

图6 聚群行为过程

        (4)追尾行为

        设人工鱼当前状态为Xi,探索当前领域内(即di,j<Visual)的伙伴数目nf及伙伴中Yj为最大的伙伴Xj,如果Yj/nf > δYi,表明伙伴Xj的状态具有较高的食物浓度并且其周围不太拥挤,则朝伙伴Xj的方向前进一步;否则执行觅食行为。追尾过程如图7所示。

图7 尾行为过程

        (5)随机行为

        随机行为的实现较简单,就是在视野中随机选择一个状态,然后向该方向移动,其实,它是 觅食行为的一个缺省行为,即Xi的下一个位置Xi|next为

3MATLAB程序实现

3.1 鱼群初始化函数

        创建初始人工鱼群,函数名为AF_init:

function X=AF_init(Nfish,lb_ub)
%输入:
% Nfish 鱼群大小
% lb_ub 鱼的活动范围

%输出:
% X     产生的初始人工鱼群

% example:
% Nfish=3;
% lb_ub=[-3.0,12.1,1;4.1,5.8,1]; 
%%这里的lb_ub是2行3列的矩阵,每行中前两个数是范围的上下限,第3个数是在该范围内的数的个数
% X=Inital(Nfish,lb_ub)  
%%就是产生[-3.0,12.1]内的数1个,[4.1,5.8]内的数1个
%%两个数一组,这样的数一共Nfish个
row=size(lb_ub,1);
X=[];
for i=1:row
    lb=lb_ub(i,1);
    ub=lb_ub(i,2);
    nr=lb_ub(i,3);
    for j=1:nr
        X(end+1,:)=lb+(ub-lb)*rand(1,Nfish);
    end
end

3.2 觅食行为

        觅食行为函数AF_prey的代码:

function [Xnext,Ynext]=AF_prey(Xi,ii,visual,step,try_number,LBUB,lastY)
%觅食行为
%输入:
%Xi          当前人工鱼的位置
%ii          当前人工鱼的序号
%visual      感知范围
%step        最大移动步长
%try_number  最大尝试次数
%LBUB        各个数的上下限
%lastY       上次的各人工鱼位置的食物浓度

%输出:
%Xnext       Xi人工鱼的下一个位置  
%Ynext       Xi人工鱼的下一个位置的食物浓度

Xnext=[];
Yi=lastY(ii);
for i=1:try_number
    Xj=Xi+(2*rand(length(Xi),1)-1)*visual;
    Yj=AF_foodconsistence(Xj);
    if Yi<Yj
        Xnext=Xi+rand*step*(Xj-Xi)/norm(Xj-Xi);
        for i=1:length(Xnext)
            if  Xnext(i)>LBUB(i,2)
                Xnext(i)=LBUB(i,2);
            end
            if  Xnext(i)<LBUB(i,1)
                Xnext(i)=LBUB(i,1);
            end
        end
        Xi=Xnext;
        break;
    end
end

%随机行为
if isempty(Xnext)
    Xj=Xi+(2*rand(length(Xi),1)-1)*visual;
    Xnext=Xj;
    for i=1:length(Xnext)
        if  Xnext(i)>LBUB(i,2)
            Xnext(i)=LBUB(i,2);
        end
        if  Xnext(i)<LBUB(i,1)
            Xnext(i)=LBUB(i,1);
        end
    end
end
Ynext=AF_foodconsistence(Xnext);

3.3 聚群行为

        聚群行为函数AF_swarm的代码:

function [Xnext,Ynext]=AF_swarm(X,i,visual,step,deta,try_number,LBUB,lastY)
% 聚群行为
%输入:
%X           所有人工鱼的位置
%i           当前人工鱼的序号
%visual      感知范围
%step        最大移动步长
%deta        拥挤度
%try_number  最大尝试次数
%LBUB        各个数的上下限
%lastY       上次的各人工鱼位置的食物浓度

%输出:
%Xnext       Xi人工鱼的下一个位置  
%Ynext       Xi人工鱼的下一个位置的食物浓度
Xi=X(:,i);
D=AF_dist(Xi,X);
index=find(D>0 & D<visual);
nf=length(index);
if nf>0
    for j=1:size(X,1)
        Xc(j,1)=mean(X(j,index));
    end
    Yc=AF_foodconsistence(Xc);
    Yi=lastY(i);
    if Yc/nf>deta*Yi
        Xnext=Xi+rand*step*(Xc-Xi)/norm(Xc-Xi);
        for i=1:length(Xnext)
            if  Xnext(i)>LBUB(i,2)
                Xnext(i)=LBUB(i,2);
            end
            if  Xnext(i)<LBUB(i,1)
                Xnext(i)=LBUB(i,1);
            end
        end
        Ynext=AF_foodconsistence(Xnext);
    else
        [Xnext,Ynext]=AF_prey(Xi,i,visual,step,try_number,LBUB,lastY);
    end
else
    [Xnext,Ynext]=AF_prey(Xi,i,visual,step,try_number,LBUB,lastY);
end

        其中,函数AF_dist为

function D=AF_dist(Xi,X)
%计算第i条鱼与所有鱼的位置,包括本身。
%输入:
%Xi   第i条鱼的当前位置  
%X    所有鱼的当前位置
% 输出:
%D    第i条鱼与所有鱼的距离
col=size(X,2);
D=zeros(1,col);
for j=1:col
    D(j)=norm(Xi-X(:,j));
end

3.4追尾行为

        追尾行为函数AF_follow的代码:

function [Xnext,Ynext]=AF_follow(X,i,visual,step,deta,try_number,LBUB,lastY)
% 追尾行为
%输入:
%X           所有人工鱼的位置
%i           当前人工鱼的序号
%visual      感知范围
%step        最大移动步长
%deta        拥挤度
%try_number  最大尝试次数
%LBUB        各个数的上下限
%lastY       上次的各人工鱼位置的食物浓度

%输出:
%Xnext       Xi人工鱼的下一个位置
%Ynext       Xi人工鱼的下一个位置的食物浓度
Xi=X(:,i);
D=AF_dist(Xi,X);
index=find(D>0 & D<visual);
nf=length(index);
if nf>0
    XX=X(:,index);
    YY=lastY(index);
    [Ymax,Max_index]=max(YY);
    Xmax=XX(:,Max_index);
    Yi=lastY(i);
    if Ymax/nf>deta*Yi;
        Xnext=Xi+rand*step*(Xmax-Xi)/norm(Xmax-Xi);
        for i=1:length(Xnext)
            if  Xnext(i)>LBUB(i,2)
                Xnext(i)=LBUB(i,2);
            end
            if  Xnext(i)<LBUB(i,1)
                Xnext(i)=LBUB(i,1);
            end
        end
        Ynext=AF_foodconsistence(Xnext);
    else
        [Xnext,Ynext]=AF_prey(X(:,i),i,visual,step,try_number,LBUB,lastY);
    end
else
    [Xnext,Ynext]=AF_prey(X(:,i),i,visual,step,try_number,LBUB,lastY);
end

3.5 目标函数

        目标函数(即食物浓度函数)是用来求人工鱼当前位置的食物浓度,其实就是求给定变量值的函数值,例如计算以下函数的最大值:

        这时的食物浓度函数如下:

function [Y]=AF_foodconsistence(X)
fishnum=size(X,2);
for i=1:fishnum
     Y(1,i)=X(i)*sin(10*pi*X(i))+2;
end

        其他的问题类似,只要修改对应的函数即可。

3.6 一元函数优化

        参数选择如表3所列。

表3 
一元函数优化参数选择

        鱼群算法主函数程序代码如下:  

clc
clear all
close all
tic
figure(1);hold on
ezplot('x*sin(10*pi*x)+2',[-1,2]);
%% 参数设置
fishnum=50; %生成50只人工鱼
MAXGEN=50; %最多迭代次数
try_number=100;%最多试探次数
visual=1; %感知距离
delta=0.618; %拥挤度因子
step=0.1; %步长
%% 初始化鱼群
lb_ub=[-1,2,1];
X=AF_init(fishnum,lb_ub);
LBUB=[];
for i=1:size(lb_ub,1)
    LBUB=[LBUB;repmat(lb_ub(i,1:2),lb_ub(i,3),1)];
end
gen=1;
BestY=-1*ones(1,MAXGEN); %每步中最优的函数值
BestX=-1*ones(1,MAXGEN); %每步中最优的自变量
besty=-100; %最优函数值
Y=AF_foodconsistence(X);
while gen<=MAXGEN
    fprintf(1,'%d
',gen)
    for i=1:fishnum
          %% 聚群行为
        [Xi1,Yi1]=AF_swarm(X,i,visual,step,delta,try_number,LBUB,Y); 
         %% 追尾行为
        [Xi2,Yi2]=AF_follow(X,i,visual,step,delta,try_number,LBUB,Y); 
        if Yi1>Yi2
            X(:,i)=Xi1;
            Y(1,i)=Yi1;
        else
            X(:,i)=Xi2;
            Y(1,i)=Yi2;
        end
    end
    [Ymax,index]=max(Y);
    figure(1);
    plot(X(1,index),Ymax,'.','color',[gen/MAXGEN,0,0])
    if Ymax>besty
        besty=Ymax;
        bestx=X(:,index);
        BestY(gen)=Ymax;
        [BestX(:,gen)]=X(:,index);
    else
        BestY(gen)=BestY(gen-1);
        [BestX(:,gen)]=BestX(:,gen-1);
    end
    gen=gen+1;
end
plot(bestx(1),besty,'ro','MarkerSize',100)
xlabel('x')
ylabel('y')
title('鱼群算法迭代过程中最优坐标移动')

%% 优化过程图
figure
plot(1:MAXGEN,BestY)
xlabel('迭代次数')
ylabel('优化值')
title('鱼群算法迭代过程')
disp(['最优解X:',num2str(bestx,'%1.4f')])
disp(['最优解Y:',num2str(besty,'%1.4f')])
toc

        鱼群算法的运行结果如下,图8为鱼群算法迭代50次的最优人工鱼分布情况,图9为目标值的优化过程。

3.7 二元函数优化

        参数选择如表4所列。

表4 二元函数优化参数选择

        鱼群算法主函数程序代码如下:  

clc
clear all
close all
tic
figure(1);hold on
%% 参数设置
fishnum=100; %生成100只人工鱼
MAXGEN=50; %最多迭代次数
try_number=100;%最多试探次数
visual=1; %感知距离
delta=0.618; %拥挤度因子
step=0.1; %步长
%% 初始化鱼群
lb_ub=[-10,10,2;];
X=AF_init(fishnum,lb_ub);
LBUB=[];
for i=1:size(lb_ub,1)
    LBUB=[LBUB;repmat(lb_ub(i,1:2),lb_ub(i,3),1)];
end
gen=1;
BestY=-1*ones(1,MAXGEN); %每步中最优的函数值
BestX=-1*ones(2,MAXGEN); %每步中最优的自变量
besty=-100; %最优函数值
Y=AF_foodconsistence(X);
while gen<=MAXGEN
    fprintf(1,'%d
',gen)
    for i=1:fishnum
        %% 聚群行为
        [Xi1,Yi1]=AF_swarm(X,i,visual,step,delta,try_number,LBUB,Y); 
        
         %% 追尾行为
        [Xi2,Yi2]=AF_follow(X,i,visual,step,delta,try_number,LBUB,Y);
        if Yi1>Yi2
            X(:,i)=Xi1;
            Y(1,i)=Yi1;
        else
            X(:,i)=Xi2;
            Y(1,i)=Yi2;
        end
    end
    [Ymax,index]=max(Y);
    figure(1);
    plot(X(1,index),X(2,index),'.','color',[gen/MAXGEN,0,0])
    if Ymax>besty
        besty=Ymax;
        bestx=X(:,index);
        BestY(gen)=Ymax;
        [BestX(:,gen)]=X(:,index);
    else
        BestY(gen)=BestY(gen-1);
        [BestX(:,gen)]=BestX(:,gen-1);
    end
    gen=gen+1;
end
plot(bestx(1),bestx(2),'ro','MarkerSize',100)
xlabel('x')
ylabel('y')
title('鱼群算法迭代过程中最优坐标移动')

%% 优化过程图
figure
plot(1:MAXGEN,BestY)
xlabel('迭代次数')
ylabel('优化值')
title('鱼群算法迭代过程')
disp(['最优解X:',num2str(bestx','%1.5f')])
disp(['最优解Y:',num2str(besty,'%1.5f')])
toc

        鱼群算法的运行结果如下,图10为鱼群算法迭代50次的最优人工鱼分布情况,图11为目标值的优化过程。

        命令行
中的运行结果:

4 延伸阅读

4.1 人工鱼群算法优点

        人工鱼群算法具有以下优点:

        (1)具有克服局部极值、取得全局极值的能力。

        (2)算法中仅使用目标问题的函数值,对搜索空间有一定自适应能力。

        (3)具有对初值与参数选择不敏感、鲁棒性强、简单易实现、收敛速度快和使用灵活等特点。可以解决经典方法不能求解的带有绝对值且不可导二元函数的极值问题。

4.2 算法改进的几个方向

        1.视野的改进

        在鱼群模式所讨论的视野概念中,由于视点的选择是随机的,移动的步长也是随机的,虽然这种做法能在一定程度上扩大寻优的范围,尽可能保证寻优的全局性,但会使得算法的收敛速度减慢,有大量的计算时间浪费在随机的移动之中,可以使用自适应步长的方式进行改进。

        2.分段优化方法

        算法在优化过程初期虽然具有较快的收敛品质,但在后期却往往收敛较慢,或者无法达到要求的精度,因此,与其他算法相结合,在合适的时候与其他算法互相切换,实现各算法之间的优缺点互补,也是一种解决问题的常用方法。

        3.混合优化方法

        鱼群模式提供了一种解决问题的架构,其中可以应用传统的、相对成熟的计算方法,而面向对象的方法为其他计算方法与鱼群算法的有机融合提供了良好的基础。例如,如果问题的模型比较熟知,并且目标函数的非线性程度不是非常严重,则可以在觅食行为中使用单纯行法等传统方法来代替在视野中的随机搜索方法,这样,在提高收敛速度的同时,能适当提高收敛的精度,并且还能在一定程度上克服局部极值的问题。