最近学习了人工蜂群算法,做总结如下。karaboga于2005年提出,是一种基于群智能的全局优化算法。属于群智能算法的一种。整个算法分为雇佣蜂、观察蜂、侦查蜂三种操作。目标是寻找花蜜量最大的蜜源。
雇佣蜂:利用先前的蜜源信息寻找新的蜜源并与观察蜂分享蜜源信息;
观察蜂:在蜂房中等待并依据雇佣蜂分享的信息寻找新的蜜源;
侦查蜂:寻找一个新的有价值的蜜源,它们在蜂房附近随机的寻找蜜源。
雇佣蜂根据,
更新蜜源信息,同时确定蜜源花蜜量;观察蜂根据雇佣蜂提供的信息,采用一定的适应函数,计算每个蜜源的概率,如公式1所示(SN代表雇佣蜂的数量),然后采用轮盘赌选择一个蜜源。根据
,
更新蜜源信息,同时确定蜜源的花蜜量。侦查蜂是用来判断某一个蜜源在指定步骤内是否提高,若没有提高,则丢弃该蜜源,重新初始化一个蜜源再次搜索。
算法流程:
- 问题定义;
- 初始化;
- 重复以下过程:
- 将雇佣蜂与蜜源一一对应,根据
更新蜜源信息,同 时确定蜜源的花蜜量;
- 观察蜂根据雇佣蜂所提供的信息采用一定的选择策略(每只观察蜂依据概率,采用轮盘赌)选择蜜源,根据 更新蜜源信息,同时确定蜜源的花蜜量;
- 确定侦查蜂,并根据
寻找新的蜜源;
- 记忆目前为止找到的最好的蜜源;
- 将雇佣蜂与蜜源一一对应,根据
- 判断终止条件是否成立;
以标准ABC算法为例:https://www.mathworks.com/matlabcentral/fileexchange/52966-artificial-bee-colony-abc-in-matlab
问题定义:随机生成(-10 10)之间的5个数,使5个数的平方和最小。
算法中用到的函数如下所示:
CostFunction=@(x) Sphere(x):函数句柄,未知数是x,相当于建立了一个函数文件
round():四舍五入取整
inf:无穷大量
unifrnd(-10,10,[1 5]):产生均匀分布的随机数,产生一个1*5的随机数矩阵,其值在-10到10之间均匀分布
numel(A):返回数组A中的元素个数
randi([1 10]):生成一个1到10之间的伪随机整数
k=[1:i-1 i+1:10]:生成不包括i的1到10之间的数
mean([Pop.Cost]):求向量的均值
disp():显示文本或数组
num2str():把数值转换成字符串,转换后可以用disp输出
r=rand:随机产生0-1之间的整数
cumsum(A):A是向量,返回一个向量,该向量中第m行元素是A中第1行到第m行的所有元素的累加和
find(r<=C,1,’first’):返回满足r<=C的第一个元素在C中的位置
% 随机生成(-10 10)之间的5个数,使5个数的平方和最小
clc;
clear;
close all;
% 问题定义
CostFunction=@(x) Sphere(x);
nVar=5;
VarSize=[1 5];
VarMin=-10;
VarMax=10;
% ABC参数定义
MaxIt=200; % 种群迭代次数
nPop=100; % 雇佣蜂数量
nOnlooker=nPop; %观察蜂数量
L=round(0.6*nVar*nPop); %蜜源试验限制,侦查蜂判断
a=1; % 加速系数的最大值
%% 初始化时期
empty_bee.Position=[];
empty_bee.Cost=[]; % 蜜源
pop=repmat(empty_bee,nPop,1);
BestSol.Cost=inf;
for i=1:nPop
pop(i).Position=unifrnd(VarMin,VarMax,VarSize);
pop(i).Cost=CostFunction(pop(i).Position);
if pop(i).Cost<BestSol.Cost
BestSol=pop(i)
end
end
C=zeros(nPop,1); % 用来判断蜜源的试验限制
BestCost=zeros(MaxIt,1); %用来记录迄今为止最好的蜜源
for it=1:MaxIt
% 雇佣蜂时期
for i=1:nPop
K=[1:i-1 i+1:nPop];
k=K(randi([1 numel(K)]));
phi=a*unifrnd(-1,1,VarSize); % 加速系数
newbee.Position=pop(i).Position+phi.*(pop(i).Position-pop(k).Position);
newbee.Cost=CostFunction(newbee.Position);
if newbee.Cost<=pop(i).Cost
pop(i)=newbee;
else
C(i)=C(i)+1;
end
end
F=zeros(nPop,1);
MeanCost=mean([pop.Cost]);
for i=1:nPop
F(i)=exp(-pop(i).Cost/MeanCost); % 适应函数
end
P=F/sum(F);
% 观察蜂时期
for m=1:nOnlooker
i=RouletteWheelSelection(P); % 采用轮盘赌随机选择一个蜜源
K=[1:i-1 i+1:nPop];
k=K(randi([1 numel(K)]));
phi=a*unifrnd(-1,1,VarSize);
newbee.Position=pop(i).Position+phi.*(pop(i).Position-pop(k).Position);
newbee.Cost=CostFunction(newbee.Position);
if newbee.Cost<=pop(i).Cost
pop(i)=newbee;
else
C(i)=C(i)+1;
end
end
% 侦查蜂
for i=1:nPop
if C(i)>=L % 判断蜜源是否到达试验限制
pop(i).Position=unifrnd(VarMin,VarMax,VarSize);
pop(i).Cost=CostFunction(pop(i).Position);
C(i)=0;
end
end
for i=1:nPop
if pop(i).Cost<=BestSol.Cost
BestSol=pop(i); %寻找最佳蜜源
end
end
BestCost(it)=BestSol.Cost; % 存储最佳蜜源
disp(['Iteration ' num2str(it) ': Best Cost= ' num2str(BestCost(it))]);
end
figure;
semilogy(BestCost,'lineWidth',2)
xlabel('Iteration');
ylabel('Best Cost');
grid on;
% 代价函数
function z=Sphere(x)
z=sum(x.^2);
end
% 轮盘赌算法
function i=RouletteWheelSelection(P)
r=rand;
C=cumsum(P);
i=find(r<=C,1,'first');
end