赞
踩
本文用经典人工蜂群算法框架模板,对matlab新手友好,快速上手看懂matlab代码,快速应用实践,源代码在文末给出。
人工蜂群算法(Artificial Bee Colony Algorithm,ABC)是一种启发式算法,受到蜜蜂觅食行为的启发而提出的一种优化算法。它模拟了蜜蜂在寻找花朵采集花粉的过程中的行为,通过不断地调整蜜蜂的搜索策略来寻找最优解。
人工蜂群算法的基本思想是将候选解空间中的点看作花朵,并将搜索过程看作蜜蜂在不同花朵之间搜索的过程。在算法的执行过程中,蜜蜂分为三类:雇佣蜜蜂、观察蜜蜂和侦查蜜蜂。
雇佣蜜蜂:雇佣蜜蜂负责在当前位置附近的解空间中搜索,并评估候选解的质量。它们根据花粉量的多少(即解的适应度)来选择候选解,并将信息传递给其他蜜蜂。
观察蜜蜂:观察蜜蜂根据雇佣蜜蜂的信息进行选择,并尝试在当前位置附近进行搜索。它们通过观察雇佣蜜蜂找到的解来确定自己的搜索方向。
侦查蜜蜂:侦查蜜蜂负责在整个解空间中进行全局搜索,以寻找可能的新解。它们以一定的概率选择随机位置进行探索,并在搜索过程中更新最优解。
通过不断地雇佣、观察和侦查过程,人工蜂群算法能够在解空间中搜索到较优解。该算法具有较好的全局搜索能力和较快的收敛速度,适用于解决各种复杂的优化问题,如函数优化、参数优化等。
本编程将观察蜂于侦察蜂统一,称为侦察蜂,将雇佣蜜蜂称为采蜜蜂。
编程思想为:采蜜蜂进行随机采蜜,侦察蜂根据采蜜蜂的适应度大小进行跟随,适应度越高证明蜜源越好,越接近正确解,侦察蜂在采蜜蜂周围进行随机侦察,侦察到更好的蜜源后(也就是适应度越好的个体),那么将采蜜蜂更新到此位置,进而吸引更多的侦察蜂侦察,实现快速收敛。
- %---------------------------------- 程序正文 -------------------------------
- function ABC
- %---------------------------------- 参数设置 -------------------------------
- NP1=20; %种群规模
- NP2=20; %种群规模
- D=10; %变量个数
- MinX=-D^2; %范围下限
- MaxX=D^2; %范围上限
- Limit=50; %次数阈值
- Search=zeros(1,NP1); %采蜜搜次
- Error=1.0; %限定精度
- Max_N=1000; %限定代数
- flagc=[0,Max_N]; %收敛标志
- %---------------------- 粒子位置初始化 ----------------------
- for i=1:1:D
- X(:,i)=MinX+(MaxX-MinX)*rand(NP1+NP2,1);
- end
- %----------------------- 计算函数值 -------------------------
- F=fun(X);
- %---------------------------- 子函数1:目标函数 ----------------------------
- function F=fun(X)
- [M,N]=size(X);
- for i=1:1:M
- for j=1:1:N
- x(j)=X(i,j);
- end
- F(i)=N*(N+4)*(N-1)/6+sum((x-1).^2)-sum(x(2:N).*x(1:N-1));
- end
- %----------------------- 建采蜜蜂群 -------------------------
- [Bestf,Indexf]=sort(F,2);
- for i=1:1:NP1
- X1(i,:)=X(Indexf(i),:);
- F1(i)=F(Indexf(i));
- end
- CX1=X1;CF1=F1;
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
NP1和NP2分别为采蜜蜂和侦察蜂。D为变量个数
X矩阵为D列,NP1+NP2行的矩阵,也就是40行,10列的矩阵。每一行代表一个蜜蜂个体,元素范围为(-100,100)
fun(x)为子函数,子函数中,M,N分别代表为X的行数和列数,这里的子函数也是目标函数,具体的数学函数如下,最终算法目标也就是求这个数学函数值小于1的解。
如上述代码所示,sort(F,2)表示按F的第二维度进行排序,也就是按列排序,也就是对F的每一行进行排序,由于F只有1行,那么也可以去掉这个参数,F一行的第i个参数也就是第i个蜜蜂的适应度,这里的排序就相当于按照每个蜜蜂的适应度进行排序,然后根据for循环挑选出NP1个蜜蜂作为采蜜蜂,CX1,CF1表示复制一份值。
- %--------------------- 程序主循环开始 ----------------------
- for gen=1:1:Max_N
- time(gen)=gen;
- %----------------- 作采蜜蜂群搜索 ----------------------
- for i=1:1:NP1
- flag1=ceil(rand*NP1);
- while(flag1==i)
- flag1=ceil(rand*NP1);
- end
- flag2=ceil(rand*D);
- X1(i,flag2)=X1(i,flag2)+rands(1)*(X1(i,flag2)-X1(flag1,flag2));
- end
- %----------------- 计算采蜜函数值 ----------------------
- F1=fun(X1);
- %----------------- 采蜜蜂贪婪搜索 ----------------------
- for i=1:1:NP1
- if F1(i)>=CF1(i)
- Search(i)=Search(i)+1;
- X1(i,:)=CX1(i,:);
- F1(i)=CF1(i);
- else
- Search(i)=0;
- end
- end
- %----------------- 跟踪蜂选择概率 ----------------------
- temp=(1./(1+F1))/sum(1./(1+F1));
- %P=cumsum((1./(1+F1))/sum(1./(1+F1)));
- for i=1:1:NP1
- P(i)=sum(temp(1:i));
- end
- %----------------- 跟踪蜂蜜源搜索 ----------------------
- for i=1:1:NP2
- %------------- 跟踪蜂选择蜜源 ----------------------
- rnd=rand;
- for flag=1:1:NP1
- if rnd<P(flag)
- Genzong(i)=flag;
- break;
- end
- end
- X2(i,:)=X1(flag,:);
- %------------- 跟踪蜂搜索蜜源 ----------------------
- flag1=ceil(rand*NP1);
- while(flag1==flag)
- flag1=ceil(rand*NP1);
- end
- flag2=ceil(rand*D);
- X2(i,flag2)=X1(flag,flag2)+rands(1)*(X1(flag,flag2)-X1(flag1,flag2));
- end
- %----------------- 计算跟踪函数值 ----------------------
- F2=fun(X2);
- %----------------- 跟踪蜂蜜源计数 ----------------------
- for i=1:1:NP2
- if F2(i)>=F1(Genzong(i))
- Search(Genzong(i))=Search(Genzong(i))+1;
- else
- Search(Genzong(i))=0;
- X1(Genzong(i),:)=X2(i,:);
- F1(Genzong(i))=F2(i);
- end
- end
- %----------------- 检验采蜜蜂蜜源 ----------------------
- for i=1:1:NP1
- if Search(i)>Limit
- Search(i)=0;
- if i~=Indexf(1)
- X1(i,:)=MinX+(MaxX-MinX)*rand(1,D);
- F1=fun(X1);
- end
- end
- end
- %----------------- 迭代更新 ---------------------------
- CF1=F1;CX1=X1;
- %----------------- 求最优解 ---------------------------
- [Bestf,Indexf]=sort(F1,2); %对NP1个函数值排序
- gBestf=Bestf(1);
- gX=X1(Indexf(1),:);
- %----------------------------- 记录结果 --------------------------------
- result(gen)=gBestf;
- if mod(gen,10)==0
- disp(sprintf('代数:%d -------- 结果:%f',gen,gBestf));
- plot(time,result,'r');axis([1,Max_N,0,10000]);
- xlabel('迭代步数');ylabel('优化结果');drawnow;pause(0.1);
- end
- if gBestf<Error break;end
- end
- %disp(' ');
- disp(sprintf('迭代步数:%d -------- 优化结果:%f',gen,gBestf));
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
最外层循环表示迭代次数,表示进行Max_N次迭代,time记录迭代到第几次,做采蜜蜂群搜索代码中,ceil表示向上取整,表示[1,NP1]范围的随机整数。while循环内表示此整数不能等于当前迭代次数,也就是防止下一段代码中X1的参数未被修改。
F1 = fun(X1)表示计算采蜜蜂群的适应度并存储在F1矩阵中。
当更新后F1的适应度比之前差,那么把对应的个体记录到search中,并把没更新之前的值赋值给X1和F1。
这个选择方法是轮盘赌选择,具体原理和流程见主页遗传算法中。这里Genzong数组里记录了每个跟踪蜂跟踪第几个采蜜蜂,X2矩阵中存储跟踪蜂选择的采蜜蜂个体。蜜源越大也就是适应度越好,跟踪蜂越多。
flag1表示[1,NP1]的随机值,与上面的采蜜蜂搜索蜜源相似,做随机搜索,随机改变10个变量中的一个,循环结束使用F2进行跟踪蜂适应度计算。
这个for循环中,遍历每个跟踪蜂的适应度,如果跟踪蜂的适应度比它跟踪的采蜜蜂的适应度差,那么将对应采蜜蜂的search中的值+1,也就是search越大,这个采蜜蜂的适应度越好,如果跟踪蜂的适应度好,将跟踪蜂的值赋值给它跟踪的采蜜蜂,并更新采蜜蜂的对应适应度的值。
这个代码是防止陷入局部最优解的过程,当search超过limit时,表示此采蜜蜂周围没有比他更好的蜜源了,将search设置为0,如果这个采蜜蜂还不是全局最优解,那么将这个采蜜蜂重新分配一个随机蜜源,这就是避免陷入局部最优的过程,如果这个蜜蜂是全局最优解,那么不分配随机蜜源,继续让跟踪蜂寻找。
迭代更新的CF1记录上一次的采蜜蜂的适应度,CX1记录上一次采蜜蜂的值,计算最优解将适应度排序,寻找最佳的采蜜蜂。
- %---------------------------------- 程序说明 -------------------------------
-
- % 该程序实现了基本蜂群算法
-
- %---------------------------------- 程序正文 -------------------------------
- function ABC
- %---------------------------------- 参数设置 -------------------------------
- NP1=20; %种群规模
- NP2=20; %种群规模
- D=10; %变量个数
- MinX=-D^2; %范围下限
- MaxX=D^2; %范围上限
- Limit=50; %次数阈值
- Search=zeros(1,NP1); %采蜜搜次
- Error=1.0; %限定精度
- Max_N=1000; %限定代数
- flagc=[0,Max_N]; %收敛标志
- %---------------------- 粒子位置初始化 ----------------------
- for i=1:1:D
- X(:,i)=MinX+(MaxX-MinX)*rand(NP1+NP2,1);
- end
- %X=MinX+(MaxX-MinX)*rand(NP1+NP2,D);
- disp(X);
- %----------------------- 计算函数值 -------------------------
- F=fun(X);
- %----------------------- 建采蜜蜂群 -------------------------
- [Bestf,Indexf]=sort(F,2);
- for i=1:1:NP1
- X1(i,:)=X(Indexf(i),:);
- F1(i)=F(Indexf(i));
- end
- CX1=X1;CF1=F1;
- %--------------------- 程序主循环开始 ----------------------
- for gen=1:1:Max_N
- time(gen)=gen;
- %----------------- 作采蜜蜂群搜索 ----------------------
- for i=1:1:NP1
- flag1=ceil(rand*NP1);
- while(flag1==i)
- flag1=ceil(rand*NP1);
- end
- flag2=ceil(rand*D);
- X1(i,flag2)=X1(i,flag2)+rands(1)*(X1(i,flag2)-X1(flag1,flag2));
- end
- %----------------- 计算采蜜函数值 ----------------------
- F1=fun(X1);
- %----------------- 采蜜蜂贪婪搜索 ----------------------
- for i=1:1:NP1
- if F1(i)>=CF1(i)
- Search(i)=Search(i)+1;
- X1(i,:)=CX1(i,:);
- F1(i)=CF1(i);
- else
- Search(i)=0;
- end
- end
- %----------------- 跟踪蜂选择概率 ----------------------
- temp=(1./(2+F1))/sum(1./(2+F1));
- %P=cumsum((1./(1+F1))/sum(1./(1+F1)));
- for i=1:1:NP1
- P(i)=sum(temp(1:i));
- end
- %----------------- 跟踪蜂蜜源搜索 ----------------------
- for i=1:1:NP2
- %------------- 跟踪蜂选择蜜源 ----------------------
- rnd=rand;
- for flag=1:1:NP1
- if rnd<P(flag)
- Genzong(i)=flag;
- break;
- end
- end
- X2(i,:)=X1(flag,:);
- %------------- 跟踪蜂搜索蜜源 ----------------------
- flag1=ceil(rand*NP1);
- while(flag1==flag)
- flag1=ceil(rand*NP1);
- end
- flag2=ceil(rand*D);
- X2(i,flag2)=X1(flag,flag2)+rands(1)*(X1(flag,flag2)-X1(flag1,flag2));
- end
- %----------------- 计算跟踪函数值 ----------------------
- F2=fun(X2);
- %----------------- 跟踪蜂蜜源计数 ----------------------
- for i=1:1:NP2
- if F2(i)>=F1(Genzong(i))
- Search(Genzong(i))=Search(Genzong(i))+1;
- else
- Search(Genzong(i))=0;
- X1(Genzong(i),:)=X2(i,:);
- F1(Genzong(i))=F2(i);
- end
- end
- %----------------- 检验采蜜蜂蜜源 ----------------------
- for i=1:1:NP1
- if Search(i)>Limit
- Search(i)=0;
- if i~=Indexf(1)
- X1(i,:)=MinX+(MaxX-MinX)*rand(1,D);
- disp("reSearch");
- F1=fun(X1);
- end
- end
- end
- %----------------- 迭代更新 ---------------------------
- CF1=F1;CX1=X1;
- %----------------- 求最优解 ---------------------------
- [Bestf,Indexf]=sort(F1,2); %对NP1个函数值排序
- gBestf=Bestf(1);
- gX=X1(Indexf(1),:);
- %----------------------------- 记录结果 --------------------------------
- result(gen)=gBestf;
- if mod(gen,10)==0
- disp(sprintf('代数:%d -------- 结果:%f',gen,gBestf));
- plot(time,result,'r');axis([1,Max_N,0,10000]);
- xlabel('迭代步数');ylabel('优化结果');drawnow;pause(0.1);
- end
- if gBestf<Error break;end
- end
- %disp(' ');
- disp(sprintf('迭代步数:%d -------- 优化结果:%f',gen,gBestf));
- disp(X1(Indexf(1),:));
- %---------------------------- 子函数1:目标函数 ----------------------------
- function F=fun(X)
- [M,N]=size(X);
- for i=1:1:M
- for j=1:1:N
- x(j)=X(i,j);
- end
- F(i)=N*(N+4)*(N-1)/6+sum((x-1).^2)-sum(x(2:N).*x(1:N-1));
- end
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。