0


人工蜂群算法(源码)

人工蜂群算法(源码)

AN IDEA BASED ON HONEY BEE SWARM FOR NUMERICAL OPTIMIZATION

这篇论文没有讲到具体如何实现,但是大家可以通过去官网学习一下这个算法。

算法主要的变化,由三种蜜蜂的行为决定。

适应度值修正

       fitness  
     
     
     
       ( 
      
      
       
       
         X 
        
       
         m 
        
       
      
        → 
       
      
     
       ) 
      
     
    
      = 
     
     
     
       { 
      
      
       
        
         
          
          
            1 
           
          
            / 
           
           
           
             ( 
            
           
             1 
            
           
             + 
            
           
             f 
            
            
            
              ( 
             
             
              
              
                X 
               
              
                m 
               
              
             
               → 
              
             
            
              ) 
             
            
           
             ) 
            
           
          
         
        
        
         
          
          
             if  
           
          
            f 
           
           
           
             ( 
            
            
             
             
               X 
              
             
               m 
              
             
            
              → 
             
            
           
             ) 
            
           
          
            ≥ 
           
          
            0 
           
          
         
        
       
       
        
         
          
          
            1 
           
          
            + 
           
          
            a 
           
          
            b 
           
          
            s 
           
           
           
             ( 
            
           
             f 
            
            
            
              ( 
             
             
              
              
                X 
               
              
                m 
               
              
             
               → 
              
             
            
              ) 
             
            
           
             ) 
            
           
          
         
        
        
         
          
          
             if  
           
          
            f 
           
           
           
             ( 
            
            
             
             
               X 
              
             
               m 
              
             
            
              → 
             
            
           
             ) 
            
           
          
            < 
           
          
            0 
           
          
         
        
       
      
     
       } 
      
     
    
   
     \text { fitness }\left(\overrightarrow{X_m}\right)=\left\{\begin{array}{cl}1 /\left(1+f\left(\overrightarrow{X_m}\right)\right) & \text { if } f\left(\overrightarrow{X_m}\right) \geq 0 \\1+a b s\left(f\left(\overrightarrow{X_m}\right)\right) & \text { if } f\left(\overrightarrow{X_m}\right)<0\end{array}\right\} 
    
   
  fitness (Xm​​)=⎩⎨⎧​1/(1+f(Xm​​))1+abs(f(Xm​​))​ if f(Xm​​)≥0 if f(Xm​​)<0​⎭⎬⎫​

首先,人工蜂群算法做的是求解最小值的问题,为了使得后面的轮盘赌算法能更好的运行,所以使用了这个修正函数,当原来的适应度值越小的时候,修正后的适应度值就会变得更大,并且修正过后的适应度值都为正数,同时,当适应度值为正数时候他修改后的适应度值小于等1,适应度值为负数的时候,适应度值大于1。

雇佣蜂(employed bee)

雇佣蜂负责在蜜源的附近搜索

publicvoidemployeeMove(){for(int i =0;i<employeeBeeSize;i++){int j =(int)(Math.random()*employeeBeeSize);while(j==i){
                j =(int)(Math.random()*employeeBeeSize);//i!=j}//遍历所有的蜜源, 并且从里面挑出一个不是自己的蜜源的蜜源,i!=jint d =(int)(Math.random()*dimension);//随机挑一个维度进行变异Individual oldInd = honey.get(i);double xid = oldInd.getPosition().get(d);double xjd = honey.get(j).getPosition().get(d);double phi =Math.random()*2-1;//[-1,1)double vid = xid+phi*(xid-xjd);Position newPos = oldInd.getPosition().clone();
            newPos.set(d,vid);Individual newInd =newIndividual(newPos);updateFitness(newInd);if(newInd.modifyFitness>oldInd.modifyFitness){//修正过以后越大越好
                honey.set(i,newInd);//贪婪交换
                trail[i]=0;}else{
                trail[i]++;}}}

这里是雇佣蜂的搜索

  • 遍历所有的雇佣蜂,由于直接将蜜源当成雇佣蜂来写比较方便,所以后面不管是雇佣蜂还是旁观蜂都用蜜源(honey表示)
  • 随机挑一个和自己不一样的蜜源,并且挑选一个维度使用公式 x i d = x i d + ϕ ∗ ( x i d − x k d ) x_{id} = x_{id}+\phi *(x_{id}-x_{kd}) xid​=xid​+ϕ∗(xid​−xkd​)进行变异,其中i是当前的蜜源,k是随机挑出来的蜜源,d代表着要变异的维度, ϕ \phi ϕ为(-1,1)上面均匀分布的随机数。
  • 假如更新过后的蜜源比原来的蜜源要好,就替换,假如不是则 t r a i l trail trail增加, t r a i l trail trail是记录当前的蜜源有多久没有变化的。 t r a i l trail trail具有上限,当 t r a i l trail trail超过 l i m i t limit limit值的时候就会进行侦察峰的行为, l i m i t = d i m e n s i o n ∗ 10 limit = dimension * 10 limit=dimension∗10

旁观蜂(onlooker bee)

publicvoidonlookerMove(){double sum =0;for(int i =0;i<employeeBeeSize;i++){
            sum+=honey.get(i).getModifyFitness();}for(int i =0;i<onlookersSize;i++){double prob =Math.random()*sum;int select =0;double curProb =0;for(int j =0;j<employeeBeeSize;j++){
                curProb+=honey.get(j).getModifyFitness();if(prob<curProb){
                    select = j;break;}}int selectDimension =(int)(dimension*Math.random());Individual oldInd = honey.get(i);double xid = oldInd.getPosition().get(selectDimension);double xjd = honey.get(select).getPosition().get(selectDimension);double phi =Math.random()*2-1;//[-1,1)double vid = xid+phi*(xid-xjd);Position newPos = oldInd.getPosition().clone();
            newPos.set(selectDimension,vid);Individual newInd =newIndividual(newPos);updateFitness(newInd);if(newInd.modifyFitness>oldInd.modifyFitness){//最大化修正过的适应度值,mini
                honey.set(i,newInd);//贪婪交换
                trail[i]=0;}else{
                trail[i]++;}}}

旁观蜂阶段大致是和雇佣蜂阶段相同的,最大的不同点就是,雇佣蜂阶段使用的是随机挑选一个雇佣蜂进行跟随,但是在旁观蜂阶段使用的是贪心形选择,将修正过后的适应度值作为选取轮盘赌的依据

轮盘赌的公式为:

       p 
      
     
       m 
      
     
    
      = 
     
     
      
      
        f 
       
      
        i 
       
       
       
         t 
        
       
         m 
        
       
       
       
         ( 
        
        
         
         
           X 
          
         
           m 
          
         
        
          → 
         
        
       
         ) 
        
       
      
      
       
       
         ∑ 
        
        
        
          m 
         
        
          = 
         
        
          1 
         
        
        
        
          ∣ 
         
        
          P 
         
        
          ∣ 
         
        
       
      
        f 
       
      
        i 
       
       
       
         t 
        
       
         m 
        
       
       
       
         ( 
        
        
         
         
           X 
          
         
           m 
          
         
        
          → 
         
        
       
         ) 
        
       
      
     
    
   
     p_m=\frac{f i t_m\left(\overrightarrow{X_m}\right)}{\sum_{m=1}^{|P|} f i t_m\left(\overrightarrow{X_m}\right)} 
    
   
 pm​=∑m=1∣P∣​fitm​(Xm​​)fitm​(Xm​​)​

注意这里的fit为修改过后的适应度值,修改过后的适应度值越大,则在该轮被选取的概率越大。

同样的,这里变化的公式为

      x 
     
     
     
       i 
      
     
       d 
      
     
    
   
     = 
    
    
    
      x 
     
     
     
       i 
      
     
       d 
      
     
    
   
     + 
    
   
     ϕ 
    
   
     ∗ 
    
   
     ( 
    
    
    
      x 
     
     
     
       i 
      
     
       d 
      
     
    
   
     − 
    
    
    
      x 
     
     
     
       k 
      
     
       d 
      
     
    
   
     ) 
    
   
  
    x_{id} = x_{id}+\phi *(x_{id}-x_{kd}) 
   
  
xid​=xid​+ϕ∗(xid​−xkd​),k为根据轮盘赌选出的蜜蜂。

侦察峰(scout bee)

侦察峰

publicvoidscoutMove(){int selectMaxTrail =0;int limit = dimension*10;for(int i =0;i<employeeBeeSize;i++){//find max trail beeif(trail[i]>limit&&trail[selectMaxTrail]< trail[i]){
                selectMaxTrail = i;}}if(trail[selectMaxTrail]>limit){Individual scout =newIndividual(positionFactory.initRandomPosition());updateFitness(scout);
            trail[selectMaxTrail]=0;
            honey.set(selectMaxTrail,scout);}}

这里就是每一轮都挑出最大的trail的蜜源出来,假如蜜源超过上限的话,就重新初始化这个蜜源。

总体流程就是这样↓

将侦察蜂送到初始化的食物源
重复
    雇佣蜂行为
    旁观蜂行为
    侦察峰行为
    记录下最优解
直到(需求被满足)

总体流程代码

importjava.util.*;//人工蜂群优化算法publicclass ABC{int populationSize =40;int onlookersSize = populationSize/2;//跟随蜂int employeeBeeSize = populationSize/2;//雇佣蜂Individual scout;List<Individual> honey;PositionFactory positionFactory;Individual bestBee;int dimension;int trail[];//记录迭代次数publicABC(int dimension,int ub,int lb){this.dimension = dimension;
        positionFactory =newPositionFactory(dimension,ub,lb);init();int iterTime =0;int maxIterTime =1000;while(iterTime<maxIterTime){employeeMove();onlookerMove();recordBest();scoutMove();recordBest();
            iterTime++;System.out.println(bestBee.fitness+"   "+bestBee.modifyFitness);}}publicstaticvoidmain(String[] args){newABC(2,4,-2);}publicvoidinit(){
        scout =newIndividual(positionFactory.initRandomPosition());updateFitness(scout);
        honey =newArrayList<>(onlookersSize);for(int i =0; i < onlookersSize; i++){Position p = positionFactory.initRandomPosition();Individual individual =newIndividual(p);updateFitness(individual);
            honey.add(individual);}
        trail =newint[onlookersSize];Arrays.fill(trail,0);}publicvoidemployeeMove(){for(int i =0;i<employeeBeeSize;i++){int j =(int)(Math.random()*employeeBeeSize);while(j==i){
                j =(int)(Math.random()*employeeBeeSize);//i!=j}int d =(int)(Math.random()*dimension);Individual oldInd = honey.get(i);double xid = oldInd.getPosition().get(d);double xjd = honey.get(j).getPosition().get(d);double phi =Math.random()*2-1;//[-1,1)double vid = xid+phi*(xid-xjd);Position newPos = oldInd.getPosition().clone();
            newPos.set(d,vid);Individual newInd =newIndividual(newPos);updateFitness(newInd);if(newInd.modifyFitness>oldInd.modifyFitness){//修正过以后越大越好
                honey.set(i,newInd);//贪婪交换
                trail[i]=0;}else{
                trail[i]++;}}}publicvoidonlookerMove(){double sum =0;for(int i =0;i<employeeBeeSize;i++){
            sum+=honey.get(i).getModifyFitness();}for(int i =0;i<onlookersSize;i++){double prob =Math.random()*sum;int select =0;double curProb =0;for(int j =0;j<employeeBeeSize;j++){
                curProb+=honey.get(j).getModifyFitness();if(prob<curProb){
                    select = j;break;}}int selectDimension =(int)(dimension*Math.random());Individual oldInd = honey.get(i);double xid = oldInd.getPosition().get(selectDimension);double xjd = honey.get(select).getPosition().get(selectDimension);double phi =Math.random()*2-1;//[-1,1)double vid = xid+phi*(xid-xjd);Position newPos = oldInd.getPosition().clone();
            newPos.set(selectDimension,vid);Individual newInd =newIndividual(newPos);updateFitness(newInd);if(newInd.modifyFitness>oldInd.modifyFitness){//最大化修正过的适应度值,mini
                honey.set(i,newInd);//贪婪交换
                trail[i]=0;}else{
                trail[i]++;}}}publicvoidscoutMove(){int selectMaxTrail =0;int limit = dimension*10;for(int i =0;i<employeeBeeSize;i++){//find max trail beeif(trail[i]>limit&&trail[selectMaxTrail]< trail[i]){
                selectMaxTrail = i;}}if(trail[selectMaxTrail]>limit){Individual scout =newIndividual(positionFactory.initRandomPosition());updateFitness(scout);
            trail[selectMaxTrail]=0;
            honey.set(selectMaxTrail,scout);}}//求解最小值问题publicvoidrecordBest(){Individual curBestBee =Collections.min(honey,newComparator<Individual>(){@Overridepublicintcompare(Individual o1,Individual o2){returnnewDouble(o1.getFitness()).compareTo(newDouble(o2.getFitness()));}});if(bestBee==null){
            bestBee = curBestBee;}elseif(bestBee.fitness>curBestBee.fitness){
            bestBee = curBestBee;}}publicvoidupdateFitness(Individual individual){
        individual.fitness =sinsin(individual.getPosition());
        individual.modifyFitness =modifyFitness(individual.fitness);}publicstaticdoubleMichalewicz(Position position){double res =0;double m =10;for(int i =0; i < position.size(); i++){double x = position.get(i);
            res+=-Math.sin(x)*Math.pow(Math.sin((i+1)*x*x/Math.PI),2*m);}return res;}publicstaticdoublesinsin(Position position){double res =0;for(int i =0;i<position.size();i++){double x = position.get(i);
            res+=Math.sin(x);}return res;}publicstaticdoublemodifyFitness(double value){if(value>=0){return1.0/(1.0+value);}else{return1+Math.abs(value);}}}

总结

这篇算法有粒子群算法的影子,在旁观蜂阶段使用轮盘赌算法,同时也有差分进化算法的影子:雇佣蜂阶段搜索猎物。而且这个算法没有什么需要调参的地方,感觉还行,这篇算法要注意的地方是适应度修正的地方然后就没有了。

标签: 算法

本文转载自: https://blog.csdn.net/qq_43445553/article/details/131045406
版权归原作者 我是嘉心糖 所有, 如有侵权,请联系我们删除。

“人工蜂群算法(源码)”的评论:

还没有评论