人工鱼群算法
在一片水域中,鱼往往能自行或尾随其他鱼找到营养物质多的地方,因而鱼生存数目最多的地方一般就是本水域中营养物质最多的地方,人工鱼群算法就是根据这一特点,通过构造人工鱼来模仿鱼群的觅食、聚群及追尾行为,从而实现寻优。
中文名 人工鱼群算法 典型行为觅食行为 特 点 具有较快的收敛速度 停止条件 均方差小于允许的误差。
算法描述
在一片水域中,鱼往往能自行或尾随其他鱼找到营养物质多的地方,因而鱼生存数目最多的地方一般就是本水域中营养物质最多的地方,人工鱼群算法就是根据这一特点,通过构造人工鱼来模仿鱼群的觅食、聚群及追尾行为,从而实现寻优,以下是鱼的几种典型行为:
1)觅食行为:一般情况下鱼在水中随机地自由游动,当发现食物时,则会向食物逐渐增多的方向快速游去。
2)聚群行为:鱼在游动过程中为了保证自身的生存和躲避危害会自然地聚集成群,鱼聚群时所遵守的规则有三条:分隔规则:尽量避免与临近伙伴过于拥挤;对准规则:尽量与临近伙伴的平均方向一致;内聚规则:尽量朝临近伙伴的中心移动。
3)追尾行为:当鱼群中的一条或几条鱼发现食物时,其临近的伙伴会尾随其快速到达食物点。
4)随机行为:单独的鱼在水中通常都是随机游动的,这是为了更大范围地寻找食物点或身边的伙伴。
特点
1)具有较快的收敛速度,可以用于解决有实时性要求的问题;
2)对于一些精度要求不高的场合,可以用它快速的得到一个可行解;
3)不需要问题的严格机理模型,甚至不需要问题的精确描述,这使得它的应用范围得以延伸。
停止条件
1) 判断连续多次所得的均方差小于允许的误差;
2)判断某个区域的人工鱼群的数目达到某个比率;
3)连续多次所获取的值均不能超过已找到的极值。
4)迭代次数达到预设次数
一维函数寻优MATLAB代码:
①main.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
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\n',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 |
②dist.m
1 2 3 4 5 6 7 8 |
%计算第i条鱼与所有鱼的位置,包括本身。 function D=dist(Xi,X) col=size(X,2); D=zeros(1,col); for j=1:col D(j)=norm(Xi-X(:,j)); end |
③AF_swarm.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
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_prey.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
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); |
⑤AF_init.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
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 |
⑥AF_foodconsistence
1 2 3 4 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 |
⑦AF_follow.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
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 |
⑧AF_dist
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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 |
效果
参考文献
Feng Shi. MATLAB 智能算法-30个案例分析[J]. 2015.
请问如果想要改成求解最小值应该这么做?
加负号