一、细菌觅食算法简介

实际生活需求促进了最优化方法的发展。近半个多世纪以来,由于传统优化方法的不足,一些具有全局优化性能且通用性强的进化算法,因其高效的优化性能、无需问题精确描述信息等优点,受到各领域广泛的关注和应用。其中产生最早也最具代表性的进化算法是20世纪70年代源于达尔文自然选择学说和孟德尔遗传变异理论的遗传算法(Genetic Algorithm,GA)。而近年来,人们模拟自然界生物群体行为产生出一系列群体智能优化算法,如Dorigo等通过模拟蚂蚁的寻径行为于1991年提出了蚁群优化算法(Ant Colony Optimization,ACO);Eberhart和Kennedy通过模拟鸟群捕食行为于1995年提出了粒子群优化算法(Particle Swarm Optimization,PSO)。这些算法被广泛应用于工程领域并取得了显著的成果。随着群体智能优化算法的蓬勃发展,Passino于2002年提出了模拟人类大肠杆菌觅食行为的细菌觅食优化算法(Bacteria Foraging Optimization Algorithm,BFOA),为仿生进化算法家族增添了新成员。本章将着重向广大编程爱好者介绍最基本的细菌觅食算法,各编程科研人员可以基于本章算法加以改进并应用到实际案例中。
1 标准细菌觅食优化算法
【图像分割】基于matlab改进的细菌觅食算法双阈值图像分割【含Matlab源码 069期】_初始化
2 趋向性操作(Chemotaxis)
【图像分割】基于matlab改进的细菌觅食算法双阈值图像分割【含Matlab源码 069期】_优化算法_02
3 聚集性操作(Swarming)
【图像分割】基于matlab改进的细菌觅食算法双阈值图像分割【含Matlab源码 069期】_matlab图像处理_03
4 复制性操作(Reproduction)
【图像分割】基于matlab改进的细菌觅食算法双阈值图像分割【含Matlab源码 069期】_初始化_04
5 迁徙性操作(Elimination and Dispersal)
实际环境中的细菌所生活的局部区域可能会发生逐渐变化(如食物消耗殆尽)或者发生突如其来的变化(如温度突然升高等)。这样可能会导致生活在这个局部区域的细菌种群被迁徙到新的区域中去或者集体被外力杀死。在BFO算法中模拟这种现象称为迁徙性操作。
6 BFO算法流程
【图像分割】基于matlab改进的细菌觅食算法双阈值图像分割【含Matlab源码 069期】_其他_05

二、部分源代码

%*********************Hybrid Bacterial Foraging with Parameter free PSO**********************
clear;
clc;
tic
a = 'lena.jpg';
x=imread(a);
a=rgb2gray(x);
count=imhist(a);
[m,n]=size(a);
N=m*n;
L=256;
count=count/N;
u0=0;
u=0;
for i=1:L
    u0=u0+(i-1)*count(i);
    w(i)=sum(count(1:i));  %w(i)是前i个像素的累加概率
    u = u + (i-1)*count(i);
    ua(i)= u;
end
%-----(1)初始化参数-----
p = 2;    % 搜索范围的维度
BacterialNum = 20;   % 细菌的个数
Nc = 30;  %趋化的次数(Number of Chemotaxis steps)
Ns = 4;   %趋化操作中单向运动的最大步数(Number of Swimming steps)
Nre = 4;    %复制操作步骤数(Number of reproduction steps)
step=0.05; %翻转选定方向后,单个细菌前进的步长
Sr = BacterialNum/2;   %每代复制(分裂)数
range = 255; 
for i = 1:BacterialNum     % 产生初始细菌个体的位置 
    Bacterial(i).location = range * rand(1,p);
end
%------先计算各个细菌的适应度,并初始化Pbest----------------------
for i=1:BacterialNum
    Bacterial(i).bestFitness = CalFitness1(Bacterial(i).location,w,ua,u0);
    Bacterial(i).bestLocation = Bacterial(i).location;
end

    %-----(2)复制操作开始-----
    for k = 1:Nre   
        %-----(3)趋化操作(翻转或游动)开始-----
        for j = 1:Nc  
            %-----对每一个细菌分别进行以下操作-----
            for i = 1:BacterialNum
                %-----(3a)计算适应度值
                Bacterial(i).fitness = CalFitness1(Bacterial(i).location,w,ua,u0);
                %-----保存细菌目前的适应度值,直到找到更好的适应度值取代之-----
                Bacterial_last = Bacterial(i);
                %-----(3b)翻转,产生一个随机向量,代表翻转后细菌的方向-----
                Delta = rands(1,p);
                % PHI表示翻转后选择的一个随机方向上前进(单位向量)
                PHI = Delta/sqrt(Delta*Delta');
                %-----(3c)移动,向着翻转后细菌的方向移动一个步长,并且改变细菌的位置-----
                Bacterial(i).location = Bacterial(i).location + step*PHI;
                %-----计算细菌当前位置的适应度值-----
                Bacterial(i).fitness = CalFitness1(Bacterial(i).location,w,ua,u0);
                %-----(3d)游动-----
                m = 0; % 给游动长度计数器赋初始值
                while(m < Ns) % 未达到游动的最大长度,则循环
                    m = m + 1;
                    % 新位置的适应度值是否更好?如果更好,将新位置的适应度值存储为细菌i目前最好的适应度值
                    if Bacterial(i).fitness < Bacterial_last.fitness 
                        Bacterial_last = Bacterial(i);  %保存更好的适应度值
                        % 在该随机方向上继续游动步长单位,修改细菌位置
                        Bacterial(i).location = Bacterial(i).location + step*PHI;
                        % 重新计算新位置上的适应度值
                        Bacterial(i).fitness = CalFitness1(Bacterial(i).location,w,ua,u0);
                    else
                        % 否则,结束此次游动
                        m = Ns;
                        Bacterial(i) = Bacterial_last; % 更新趋化操作后的适应度值
                    end
                end
                % pbest
                if Bacterial(i).fitness < Bacterial(i).bestFitness  
                    Bacterial(i).bestFitness = Bacterial(i).fitness;
                    Bacterial(i).bestLocation = Bacterial(i).location;
                end
            end  % 如果i<BacterialNum,进入下一个细菌的趋化,i=i+1
            
          %--------Mutation with pfPSO Opreator-------------
            GlobalBest= Bacterial(1);
            for i=2:BacterialNum
                if Bacterial(i).fitness < GlobalBest.fitness;
                    GlobalBest = Bacterial(i);
                end
            end
            for i=1:BacterialNum
               r1=rand();
               r2=rand();
               Bacterial(i).location = ( 1 - GlobalBest.location / Bacterial(i).location ) * r1 * GlobalBest.location + (GlobalBest.location / Bacterial(i).location ) * r2 * Bacterial(i).bestLocation;
               Bacterial(i).fitness = CalFitness1(Bacterial(i).location,w,ua,u0);  
               Bacterial(i).location = mod(Bacterial(i).location,255)+1;
            end
        end %-----(4)如果j<Nc,此时细菌还处于活跃状态,进行下一次趋化,j=j+1-----
        function fun = CalFitness1(x,w,ua,u0)
L=256;
x=int16(mod(x,255))+1;
w1=w(x(1));
u1=ua(x(1))/w1;
w2=w(x(2))-w(x(1));
u2=(ua(x(2))-ua(x(1)))/w2;
w3=w(L)-w(x(2));
u3=(ua(L)-ua(x(2)))/w3;

三、运行结果

【图像分割】基于matlab改进的细菌觅食算法双阈值图像分割【含Matlab源码 069期】_初始化_06

四、matlab版本及参考文献

1 matlab版本
2014a

2 参考文献
[1] 蔡利梅.MATLAB图像处理——理论、算法与实例分析[M].清华大学出版社,2020.
[2]杨丹,赵海滨,龙哲.MATLAB图像处理实例详解[M].清华大学出版社,2013.
[3]周品.MATLAB图像处理与图形用户界面设计[M].清华大学出版社,2013.
[4]刘成龙.精通MATLAB图像处理[M].清华大学出版社,2015.
[5]陈浩,方勇,朱大洲,王成,陈子龙.基于蚁群算法的玉米植株热红外图像边缘检测[J].农机化研究. 2015,37(06)