这些算法已被证明在解决实际问题方面非常有效。一些可以使用SI算法解决的任务是聚类,行星映射,控制纳米机器人和数据挖掘中的各种问题,如特征选择和分类。
在数学上讲,要使用计算智能算法解决现实世界中的优化问题,我们需要一个数学表示我们的问题,这种表示称为目标函数,它是描述问题和所有决策变量的数学规则。
简而言之,优化问题由搜索空间定义,搜索空间是我们将寻找解决方案的区域,一组决策变量,其中包含影响我们问题的所有参数,当然还有目标函数,其中的数学规则这个问题也给了我们一个候选解决方案的良好测量。
优化问题的目标是从所有可行的解决方案中找到最佳解决方案。这通常意味着我们想要最小化或最大化目标函数。换句话说,我们希望找到最小化我们的目标函数值(也称为适应值)的输入决策变量集合。
人工蜜蜂群体(ABC)算法是一种模拟蜜蜂群体行为的优化算法,并于2005年首次提出由Karaboga提出进行实参优化。
来自蜜蜂的新兴智能行为可以概括为几个步骤:
尽管我们描述了三种类型的蜜蜂,但在实施层面,我们意识到只有两种类型,即员工和旁观者。侦察蜂实际上是一种可以由员工和旁观者蜜蜂执行的探索行为。
在本文中,我们将使用Python,因为它在数值计算中越来越显示出高效性,并且更容易实现一组客观基准以重用我们的群智能算法。
importnumpyasnp
fromscipyimportoptimize
fromdeap.benchmarksimportschwefel
fromabcimportABCMeta
fromabcimportabstractmethod
fromsiximportadd_metaclass
@add_metaclass(ABCMeta)
classObjectiveFunction(object):
def__init__(self,name,dim,minf,maxf):
self.name=name
self.dim=dim
self.minf=minf
self.maxf=maxf
defsample(self):
returnnp.random.uniform(low=self.minf,high=self.maxf,size=self.dim)
defcustom_sample(self):
returnnp.repeat(self.minf,repeats=self.dim)\
+np.random.uniform(low=0,high=1,size=self.dim)*\
np.repeat(self.maxf-self.minf,repeats=self.dim)
@abstractmethod
defevaluate(self,x):
pass
classSphere(ObjectiveFunction):
def__init__(self,dim):
super(Sphere,self).__init__('Sphere',dim,-100.0,100.0)
returnsum(np.power(x,2))
classRosenbrock(ObjectiveFunction):
super(Rosenbrock,self).__init__('Rosenbrock',dim,-30.0,30.0)
returnoptimize.rosen(x)
classRastrigin(ObjectiveFunction):
super(Rastrigin,self).__init__('Rastrigin',dim,-5.12,5.12)
return10*len(x)\
+np.sum(np.power(x,2)-10*np.cos(2*np.pi*np.array(x)))
classSchwefel(ObjectiveFunction):
super(Schwefel,self).__init__('Schwefel',dim,-500.0,500.0)
returnschwefel(x)[0]
考虑到这一点,我们可以在python中实现类ArtificialBee,如下所示:
fromcopyimportdeepcopy
classArtificialBee(object):
TRIAL_INITIAL_DEFAULT_VALUE=0
INITIAL_DEFAULT_PROBABILITY=0.0
def__init__(self,obj_function):
self.pos=obj_function.custom_sample()
self.obj_function=obj_function
self.minf=obj_function.minf
self.maxf=obj_function.maxf
self.fitness=obj_function.evaluate(self.pos)
self.trial=ArtificialBee.TRIAL_INITIAL_DEFAULT_VALUE
self.prob=ArtificialBee.INITIAL_DEFAULT_PROBABILITY
defevaluate_boundaries(self,pos):
if(posself.maxf).any():
pos[pos>self.maxf]=self.maxf
pos[pos
returnpos
defupdate_bee(self,pos,fitness):
iffitness<=>
self.pos=pos
self.fitness=fitness
self.trial=0
else:
self.trial+=1
defreset_bee(self,max_trials):
ifself.trial>=max_trials:
self.__reset_bee()
def__reset_bee(self):
self.pos=self.obj_function.custom_sample()
self.fitness=self.obj_function.evaluate(self.pos)
该EmployeeBee类可以实现如下:
classEmployeeBee(ArtificialBee):
defexplore(self,max_trials):
ifself.trial<=>
component=np.random.choice(self.pos)
phi=np.random.uniform(low=-1,high=1,size=len(self.pos))
n_pos=self.pos+(self.pos-component)*phi
n_pos=self.evaluate_boundaries(n_pos)
n_fitness=self.obj_function.evaluate(n_pos)
self.update_bee(n_pos,n_fitness)
defget_fitness(self):
return1/(1+self.fitness)ifself.fitness>=0else1+np.abs(self.fitness)
defcompute_prob(self,max_fitness):
self.prob=self.get_fitness()/max_fitness
旁观者蜜蜂将巡视员工蜜蜂的工作。会飞过蜂房,检查他们工作的进展情况,并评估哪些员工在收集食物方面更加成功。
旁观者的蜜蜂总是以最优秀的员工为目标,采用概率方法作为“交汇点”,其他蜜蜂应该来到这个成功的位置,希望能提取更多的食物。
该OnlookerBee类可以实现如下:
classOnLookerBee(ArtificialBee):
defonlook(self,best_food_sources,max_trials):
candidate=np.random.choice(best_food_sources)
self.__exploit(candidate.pos,candidate.fitness,max_trials)
def__exploit(self,candidate,fitness,max_trials):
component=np.random.choice(candidate)
phi=np.random.uniform(low=-1,high=1,size=len(candidate))
n_pos=candidate+(candidate-component)*phi
ifn_fitness<=>
self.pos=n_pos
self.fitness=n_fitness
注意我们已经在分离的方法中实现了我们算法的每一步。首先我们重置我们的ABC算法的内部参数,并将我们的员工蜜蜂和旁观者蜜蜂初始化为随机位置。一个在现实世界问题中取得成功的默认策略是将整个蜂房的一半初始化为员工蜜蜂,而将另一半初始化为旁观者蜜蜂。
完整的ABC算法可以实现如下:
classABC(object):
def__init__(self,obj_function,colony_size=30,n_iter=5000,max_trials=100):
self.colony_size=colony_size
self.n_iter=n_iter
self.max_trials=max_trials
self.optimal_solution=None
self.optimality_tracking=[]
def__reset_algorithm(self):
def__update_optimality_tracking(self):
self.optimality_tracking.append(self.optimal_solution.fitness)
def__update_optimal_solution(self):
n_optimal_solution=\
min(self.onlokeer_bees+self.employee_bees,
key=lambdabee:bee.fitness)
ifnotself.optimal_solution:
self.optimal_solution=deepcopy(n_optimal_solution)
ifn_optimal_solution.fitness<>
def__initialize_employees(self):
self.employee_bees=[]
foritrinrange(self.colony_size//2):
self.employee_bees.append(EmployeeBee(self.obj_function))
def__initialize_onlookers(self):
self.onlokeer_bees=[]
self.onlokeer_bees.append(OnLookerBee(self.obj_function))
def__employee_bees_phase(self):
map(lambdabee:bee.explore(self.max_trials),self.employee_bees)
def__calculate_probabilities(self):
sum_fitness=sum(map(lambdabee:bee.get_fitness(),self.employee_bees))
map(lambdabee:bee.compute_prob(sum_fitness),self.employee_bees)
def__select_best_food_sources(self):
self.best_food_sources=\
filter(lambdabee:bee.prob>np.random.uniform(low=0,high=1),
self.employee_bees)
whilenotself.best_food_sources:
def__onlooker_bees_phase(self):
map(lambdabee:bee.onlook(self.best_food_sources,self.max_trials),
self.onlokeer_bees)
def__scout_bees_phase(self):
map(lambdabee:bee.reset_bee(self.max_trials),
self.onlokeer_bees+self.employee_bees)
defoptimize(self):
self.__reset_algorithm()
self.__initialize_employees()
self.__initialize_onlookers()
foritrinrange(self.n_iter):
self.__employee_bees_phase()
self.__update_optimal_solution()
self.__calculate_probabilities()
self.__select_best_food_sources()
self.__onlooker_bees_phase()
self.__scout_bees_phase()
self.__update_optimality_tracking()
print('iter:{}=cost:{}'
.format(itr,'%04.03e'%self.optimal_solution.fitness))
SI算法优于经典和基于梯度的方法的优点是能够在非可微函数和多模函数上表现得非常好。
就优化问题而言,有几个众所周知的基准函数用于评估优化算法的性能。其中一些函数在我们的objective_function.py上实现,其公式如下所示。
用于测量优化算法性能的一些对象函数列表
为了测试我们的框架并检查我们的ABC算法是否按预期行事,我们可以实现以下测试代码并绘制迭代中的适应值,并评估最小化过程对每个函数的执行情况。
importmatplotlib.pyplotasplt
fromalgorithm.abcimportABC
frommatplotlib.styleimportuse
fromobjection_functionimportRastrigin
fromobjection_functionimportRosenbrock
fromobjection_functionimportSphere
fromobjection_functionimportSchwefel
use('classic')
defget_objective(objective,dimension=30):
objectives={'Sphere':Sphere(dimension),
'Rastrigin':Rastrigin(dimension),
'Rosenbrock':Rosenbrock(dimension),
'Schwefel':Schwefel(dimension)}
returnobjectives[objective]
defsimulate(obj_function,colony_size=30,n_iter=5000,
max_trials=100,simulations=30):
itr=range(n_iter)
values=np.zeros(n_iter)
box_optimal=[]
for_inrange(simulations):
optimizer=ABC(obj_function=get_objective(obj_function),
colony_size=colony_size,n_iter=n_iter,
max_trials=max_trials)
optimizer.optimize()
values+=np.array(optimizer.optimality_tracking)
box_optimal.append(optimizer.optimal_solution.fitness)
print(optimizer.optimal_solution.pos)
values/=simulations
plt.plot(itr,values,lw=0.5,label=obj_function)
plt.legend(loc='upperright')
defmain():
plt.figure(figsize=(10,7))
simulate('Rastrigin')
plt.ticklabel_format(axis='y',style='sci',scilimits=(-2,2))
plt.xticks(rotation=45)
plt.show()
if__name__=='__main__':
main()
我们可以通过分析每个基准函数的适应度图和迭代次数来检查结果,还可以检查optimizer.optimal_solution.pos的输出结果,并检查ABC是否具有非常好的近似值我们的基准功能的最佳点。