• 13988888888
  • youweb@qq.com
  • 广东省广州市番禺经济开发区
  • 定制化设计一站式临时空间解决方案

  • 高端产品行业领先进口生产线

  • 核心技术装配式移动建筑系统

公司新闻
   主页 > 公司新闻

关于智能优化算法的改进策略,如何选择?

作者:佚名  发布时间:2024-04-08 06:12  浏览:

群智能优化算法是一种模拟自然界生物行为和自然现象的元启发式算法,具有良好的并行性和自主探索性。

已知智能优化算法的改进策略有如下:

1.通过初始化种群改进

大多数群体智能算法(启发式智能优化算法)初始种群中个体的生成是给定范围内随机生成,导致初始个体具有较大的随机性和不确定性,所以可以通过改进初始化种群的方式改进算法优化和收敛性能,实现局部开发和全局探索能力的提升。


1.1 混沌映射

1.2 反向学习

1.3 莱维飞行

2.策略优化个体迭代更新

2.1高斯游走策略

2.2 随机游走策略

2.3正余弦优化策略

2.4自适应策略

3.混合算法

将两种算法的优点结合进行改进,如遗传算法和粒子群算法结合的遗传粒子群算法(GAPSO)

想问一下知乎大佬,我在看一同一优化问题的文章时对不同的优化算法采用了不同的改进策略,那么这种改进策略的选择是如何确定的呢?是针对不同优化问题或不同优化算法进行的选择,还是任意选择都可以呢?如果是针对性选择,选择的标准又是什么呢?

更多,更全的【Python与seo应用实战】视频关注我,私聊我!

可以改进初始化,也可以增加一些新的策略,可以考虑试试最新的群智能优化算法:蜣螂优化算法,亲测效果不错,新算法更容易发论文

哈里斯鹰优化算法 (Harris Hawks Optimization,HHO)是Heidari等于2019年提出的一种群体优化算法,该算法模拟哈里斯鹰(美国亚利桑那州南部的猛禽)的捕食行为,主要分为探索阶段、探索与开发转换阶段和开发阶段。

智能优化算法:哈里斯鹰算法

cec2017简介

部分代码

from HHO import HHO
import matplotlib.pyplot as plt
import numpy as np
import cec2017.functions as functions
#主程序
function_name=10 #测试函数 1-29
SearchAgents_no=50#种群大小
Max_iter=100#最大迭代次数
dim=30;#维度只能是 10/30/50/100
lb=-100*np.ones(dim)#下界
ub=100*np.ones(dim)#上界
fobj=functions.all_functions[function_name-1]
BestX,BestF,curve=HHO(SearchAgents_no, Max_iter,lb,ub,dim,fobj)#问题求解

reference code link: https://mbd.pub/o/bread/ZJmYlpdu

#画收敛曲线图
if BestF>0:
    plt.semilogy(curve,color='r',linewidth=2,label='HHO')
else:
    plt.plot(curve,color='r',linewidth=2,label='HHO')
plt.xlabel("Iteration")
plt.ylabel("Fitness")
plt.xlim(0,Max_iter)
plt.title("F"+str(function_name))
plt.legend()
plt.savefig(str(function_name)+'.png')
plt.show()
print('\
The best solution is:\
'+str(BestX))
print('\
The best optimal value of the objective funciton is:\
'+str(Best

部分结果

代码获取请添加博主主页联系方式。


本文由译自Andrey Dik的俄文文章

细菌觅食优化(BFO)算法是一种引人入胜的优化技术,可在极其复杂或不可能的数值函数里找到最大化/最小化问题得近似解。 该算法被广泛认为应对分布式优化和控制的全局优化算法。 BFO 的灵感来自大肠杆菌的社会觅食行为。 BFO 已经引起了研究人员的注意,因为它已表现出在多个应用领域中解决实际优化问题方面的有效性。 大肠杆菌觅食策略背后的生物学,是以原始方式模拟,并作为一种简单的优化算法。

细菌,如大肠杆菌或沙门氏菌,是地球上最成功的生物之一。 这些灵动的细菌具有称为鞭毛的半刚性附属物,它们通过扭曲运动推动自己。 当所有的鞭毛逆时针旋转时,会产生螺旋桨效应,推动细菌或多或少地沿直线方向移动。 在这种情况下,细菌执行称为游泳的运动。 所有鞭毛都顺同一方向旋转。

鞭毛帮助大肠杆菌翻滚或游泳,这是细菌在觅食期间执行的两项主要操作。 当它们顺时针旋转鞭毛时,每个鞭毛都会反向推动细胞。 当鞭毛向不同方向旋转时,细菌就会翻滚。 细菌在有利的环境中移动时翻滚较少,而在有害的环境中,它经常翻滚,从而感知营养梯度。 鞭毛的逆时针运动有助于细菌以非常高的速度游泳。

在上述算法中,细菌的行为是由一种称为细菌趋化性的机制决定的,该机制是这些微生物对环境中化学刺激的运动反应。 这种机制允许细菌向引诱剂(最常见的营养物质)移动,并远离驱虫剂(对细菌有潜在危害的物质)。 检测引诱剂和驱虫剂的受体位于细菌的两极。

由于细菌体积小,它无法捕捉两极之间有用和有害物质浓度的差异。 细菌通过测量运动过程中浓度的变化来判定这些物质的梯度。 这种运动的速度可以达到每秒几十个细菌长度。 例如,大肠杆菌通常以每秒 10-20 倍其体长的速度移动。

图例 1. 复制:分为原始(保持运动向量)和克隆(运动向量变化)细菌。翻滚 - 细菌运动向量的变化

如果细菌选择的运动方向对应于引诱剂浓度的增加(驱虫剂浓度的降低),则至下一次翻滚之前的时间增加。 由于细菌体形小,其运动受到布朗运动的强烈影响。 结果就是,细菌只平均朝着有益物质的方向移动,远离有害物质。

所研究的细菌运动机制并不是唯一的。 有些细菌有一个鞭毛。 在这种情况下,细菌运动的变体提供了不同的旋转和停止模式。 然而,在所有情况下,如果细菌朝正确的方向移动,那么这种运动的持续时间就会增加。 因此,一般来说,细菌趋化性可以定义为游泳和翻滚的复杂组合,它允许细菌停留在营养物质浓度高的地方,躲避不可接受的有害物质浓度。

在搜索引擎优化问题的背景下,细菌趋化性也可以解释为一种机制,用于优化细菌对已知食物资源的利用,并寻找新的、潜在的、更有价值的区域。足够丰度的细菌种群可以形成复杂的时空结构 — 在细菌种群中形成的结构影响。 这种影响可能是由趋化性和许多其它原因引起的。

对于一些细菌,这种结构的形成可以通过其代谢产物的调节特性来解释。 基于磁性(对磁场的敏感性)、生物对流、负地质趋向性(微生物对重力方向的优先运动)、和其它现象,类似的效果是可能的。 常规下,细菌在友好的环境中能传播更远的距离。 当它们获得足够的食物时,它们的长度会更长,并在适当的温度下从中间断裂,变成自己的精确复制品。

这种现象激发了帕西诺(Passino)将繁衍事件引入BFO。 由于环境的突然变化或攻击,趋化过程可能会被破坏,那么细菌群落可以移动到其它地方。 这代表了真实细菌种群中的消除和扩散事件,当该区域中的所有细菌死亡、或一组细菌扩散到环境的新部分时。 此外,所研究的趋化性和繁衍过程通常不足以找到多极值目标函数的全局最大值,因为这些过程不允许细菌离开它们发现的该函数的局部最大值。 消除和扩散过程旨在克服这一缺点。 根据自然选择(适者生存),适应性差的细菌将会消亡,适应性较高的细菌会自我繁衍。

BFO 的规范版本包括以下主要步骤:

  1. 初始化细菌群落。
  2. 趋化性。
  3. 聚集。
  4. 繁衍。
  5. 流动和分群。


1. 初始化细菌群落。
细菌可以在一些半固体营养物质中形成复杂、稳定的时空模式,如果最初一同安置在中心,它们就可以在环境中生存。 甚至,在某些条件下,它们会分泌细胞间引诱信号,以便它们相互聚集和保护。

2. 趋化性。
细菌寻找食物的运动特征可以通过两种方式判定,即一同游动和翻滚被称为趋化性。 据说细菌如果朝正确的方向移动,就会“游动”,如果它向环境恶化的方向移动,就会“翻滚”。


3. 聚集。
细菌为了到达食物最丰富的地方,希望在搜索期间最佳细菌于某个时间点尝试吸引其它细菌,如此它们就能更快地在所需位置聚合在一起。 为此,根据每个细菌从适者菌落到此搜索持续时间的相对距离,在原始成本函数中添加一个惩罚函数。 最后,当所有细菌融合到决策点时,这个惩罚函数变为零。 聚集的效果是细菌成群聚拢,并以同心模式移动,细菌密度高。


4. 繁衍。

最初的一组细菌经过几个趋化阶段,达到繁衍阶段。 此刻,最好的一组细菌分为两组。 更健康的一半被另一半细菌所取代,寻找食物能力较低的则消亡。 这令细菌的数量在进化过程中保持不变。


5. 消除和扩散。
在进化过程中,可能会发生突然的不可预见的事件,该事件可以极大地改变进化过程的顺畅,并导致许多细菌的消除和/或它们扩散到新的环境中。 具有讽刺意味的是,这种未知事件并不会破坏一组细菌的正常趋化性生长,反而可能会令较新的一组细菌更接近食物的位置。 从广义上讲,消除和扩散是种群长距离行为的一部分。 当应用于优化时,这有助于减少此类并行搜索算法中常见的停滞。

我实现的 BFO 与规范版本略有不同。 在研究代码的特定部分时,除了需要这些更改的理由外,我还将详细介绍差异。 一般来讲,实现中的修改不能被认为是重要的,因此我不会将 “m”(修改版本)标记分配给算法名称。 我只想提示,已实现的修改改善了结果。

接下来,研究我实现的算法和代码。

算法步骤:

1. 细菌菌落初始化。
2. 测量细菌健康(适应度)。
3. 繁衍?
3.1. 是的。 执行繁衍。
3.2. 不。 第四步。
4. 老化 (达到生命极限)?
4.1. 是的。 执行翻滚(更改移动矢量)。
4.2. 不。 第五步。
5. 移至正确方向?
5.1. 是的。 按相同矢量继续移动。
5.2. 不。 执行翻滚 (改变运动矢量)。
6. 测量细菌健康(适应度)。
7. 从地三步继续,直到满足停止条件。

该算法的逻辑方案如图例 1 所示:

图例 2. BFO 算法逻辑框图

我们看一下代码

描述细菌的最佳方式是包含坐标和运动矢量数组的结构。 细菌当前和以前的健康值和生命计数器。 从本质上讲,生命计数器对于限制一个方向的顺序运动量是必要的,这与原始版本不同,在原始版本中,达到寿命极限时,细菌将消亡,并在搜索空间的随机位置创建一个新的细菌。 然而,由于我们在之前的文章中已经触及了这个主题,因此在随机位置创建新代理者没有实际意义,只会降低搜索功能。 在这种情况下,最好在最佳解的位置创建新代理者,或者继续从当前位置移动,但更改方向矢量。 第二个选项表现出更好的结果。

规范版本使用常量运动矢量。 由于有大量的活物,这将导致细菌在搜索空间中沿直线移动。 如果这条线不能穿过任何更好的极值,那么这种直线运动的过程将无限发生,但在这里计数器起着强制翻滚的作用,这令细菌在其整个生命周期中避免直线运动。 在不具有梯度的区域函数上,它最终仍然会导致一个可以开始改善其适应性的地方。

//——————————————————————————————————————————————————————————————————————————————
struct S_Bacteria
{
  double c[];   //coordinates
  double v[];   //vector
  double f;       //current health
  double fLast;   //previous health
  double lifeCNT; //life counter
};
//——————————————————————————————————————————————————————————————————————————————

我们将 BFO 算法类声明为 C_AO_BFO。 该类包含细菌菌落的声明、搜索空间的边界、最佳解的值和最佳解的坐标数组。 此外,声明算法参数的常量值。

//——————————————————————————————————————————————————————————————————————————————
class C_AO_BFO
{
  //----------------------------------------------------------------------------
  public: S_Bacteria b[]; //bacteria
  public: double rangeMax[]; //maximum search range
  public: double rangeMin[]; //manimum search range
  public: double rangeStep[]; //step search
  public: double cB[]; //best coordinates
  public: double fB;           //FF of the best coordinates

  public: void Init (const int    paramsP,         //number of opt. parameters
                     const int    populationSizeP, //population size
                     const double lambdaP,         //lambda
                     const double reproductionP,   //probability of reproduction
                     const int    lifeCounterP);   //life counter

  public: void Swimming   ();
  public: void Evaluation ();

  //----------------------------------------------------------------------------
  private: double NewVector (int paramInd);
  private: S_Bacteria bT[]; //bacteria
  private: double v[];
  private: int    ind[];
  private: double val[];
  private: int    populationSize; //population size
  private: int    parameters;     //number of optimized parameters
  private: double lambda;         //lambda
  private: double reproduction;   //probability of reproduction
  private: int    lifeCounter;    //life counter
  private: bool   evaluation;

  private: void   Sorting ();
  private: double SeInDiSp             (double In, double InMin, double InMax, double Step);
  private: double RNDfromCI            (double min, double max);
};
//——————————————————————————————————————————————————————————————————————————————

公开的 Init() 方法初始化常量变量、分配数组大小、和重置标志、以及最佳解的值。

//——————————————————————————————————————————————————————————————————————————————
void C_AO_BFO::Init (const int    paramsP,         //number of opt. parameters
                     const int    populationSizeP, //population size
                     const double lambdaP,         //lambda
                     const double reproductionP,   //probability of reproduction
                     const int    lifeCounterP)    //life counter
{
  fB=-DBL_MAX;
  evaluation=false;

  parameters=paramsP;
  populationSize=populationSizeP;
  lambda=lambdaP;
  reproduction=reproductionP;
  lifeCounter=lifeCounterP;

  ArrayResize (rangeMax,  parameters);
  ArrayResize (rangeMin,  parameters);
  ArrayResize (rangeStep, parameters);
  ArrayResize (v,         parameters);

  ArrayResize (ind,       populationSize);
  ArrayResize (val,       populationSize);

  ArrayResize (b,  populationSize);
  ArrayResize (bT, populationSize);

  for (int i=0; i < populationSize; i++)
{
    ArrayResize (b[i].c,  parameters);
    ArrayResize (b[i].v,  parameters);
    b[i].f=-DBL_MAX;
    b[i].fLast=-DBL_MAX;

    ArrayResize (bT[i].c,  parameters);
    ArrayResize (bT[i].v,  parameters);
  }

  ArrayResize (cB, parameters);
}
//——————————————————————————————————————————————————————————————————————————————

每次迭代时需要调用的第一个公开方法 — Swim() 或细菌泳动,包括算法的所有主要逻辑。

void C_AO_BFO::Swimming ()
{}

我们详细研究一下该方法。 在第一次迭代中,当评估标志设置为 “false” 时,我们将细菌以均匀分布随机散布在整个搜索空间当中。 在这个阶段,当前的健康状况(适应度)和前值都是未知的。 我们将 DBL_MAX 值分配给相应的变量。 检查随机获得的坐标是否超出边界,并应用更改优化参数的步骤。 在此迭代中,有必要调用 NewVector() 私密方法为每个细菌设置一个单独的位移矢量(我将在下面讨论)。 所有细菌均匀地向前泳动,并与相同的单个矢量呈直线游动,直到满足其变化的条件。

//----------------------------------------------------------------------------
if (!evaluation)
{
  fB=-DBL_MAX;

  for (int s=0; s < populationSize; s++)
{
    for (int k=0; k < parameters; k++)
{
      b[s].c[k]=RNDfromCI (rangeMin[k], rangeMax[k]);
      b[s].c[k]=SeInDiSp (b[s].c[k], rangeMin[k], rangeMax[k], rangeStep[k]);

      v[k]=rangeMax[k]- rangeMin[k];

      b[s].v[k]=NewVector (k);

      b[s].f=-DBL_MAX;
      b[s].fLast=-DBL_MAX;

      b[s].lifeCNT=0;
    }
  }

  evaluation=true;
}

在第二次、及以后的迭代中,当达到生命极限时,将执行泳动,翻滚,繁衍和消亡细菌的操作。 逻辑中的第一个是繁衍操作(参数中指定的概率)。 这意味着细菌菌落在上一次迭代中按健康值降序排序。

繁衍在算法中执行一个重要函数:通过改善细菌菌落的“基因库”来加速算法的收敛。 该操作是将细菌按想象分裂为两部分,并且只允许菌落的第一部分,较佳的一半允许分离。 菌落的前半部分减半,原始亲本版本放置在菌落的后半部分。 亲本细菌将继续以相同的矢量移动,与其克隆体相反。 克隆体保留在菌落中的位置,并为其分配一个新的运动矢量。 亲本及其克隆将继续从发生分裂的空间点移动。

r=RNDfromCI (0.0, 1.0);

//==========================================================================if (r < reproduction)
{
  int st=populationSize / 2;
  for (int s=0; s < st; s++)
{
    //bacterium original--------------------------------------------------
    for (int k=0; k < parameters; k++)
{
      b[st + s].v[k]=b[s].v[k];
      b[st + s].c[k]=b[s].c[k]+ b[s].v[k];
      b[st + s].c[k]=SeInDiSp (b[st + s].c[k], rangeMin[k], rangeMax[k], rangeStep[k]);
      b[st + s].fLast=b[s].f;
      b[st + s].lifeCNT++;
    }

    //bacterium clone-------------------------------------------------------
    for (int k=0; k < parameters; k++)
{
      b[s].v[k]=NewVector (k);
      b[s].c[k]=b[s].c[k]+ b[s].v[k];
      b[s].c[k]=SeInDiSp (b[s].c[k], rangeMin[k], rangeMax[k], rangeStep[k]);
      b[s].fLast=b[s].f;
      b[s].lifeCNT=0;
    }
  }
}

如果未实现复制概率,则进行检查是否达到细菌生命极限。 在算法的规范版本中,“旧”细菌理应消亡,并创建一个新细菌,替代其在细菌列表内搜索空间的随机位置。 在一般情况下,繁殖和趋化性的操作不足以找到多极端适应度函数的全局最大值,因为
这些程序不允许细菌离开它们发现的局部最小值。 而流动过程旨在克服这一缺陷。 然而,正如运用这种算法和其它算法的验证实践所表明的那样,在这种情况下,简单地改变运动矢量更有效。 生命计数器被重置。 计数器是在给定步数(生命)后改变移动方向的触发器。 由于繁衍和消亡,细菌总数保持不变。

if (b[s].lifeCNT >=lifeCounter)
{
  for (int k=0; k < parameters; k++)
{
    b[s].v[k]=NewVector (k);
    b[s].c[k]=b[s].c[k]+ b[s].v[k];
    b[s].c[k]=SeInDiSp (b[s].c[k], rangeMin[k], rangeMax[k], rangeStep[k]);
    b[s].fLast=b[s].f;
    b[s].lifeCNT=0;
  }
}

如果生命限制尚未用尽,那么我们将检查细菌是否朝着改善适应度函数梯度的方向发展。 换言之,我们检查两个健康值 — 在当前迭代和前一次个迭代时。 如果健康状况有所改善,则保留运动矢量,否则细菌应进行翻滚(改变运动矢量)。

在规范版本中,执行严格的“大于”当前和以前的健康检查,而在我的版本中,应用“大于或等于”,这令细菌即使在所研究表面的完全“水平”部分也能继续移动,那里没有适应度函数梯度,否则细菌会在一个地方无休止地翻滚(健康状况没有变化, 这意味着没有泳动方向)。 在这个阶段,我们还需要检查接收到的新坐标的输出是否超出搜索空间的边界。

else
{
  if (b[s].f >=b[s].fLast)
{
    for (int k=0; k < parameters; k++)
{
      b[s].c[k]=b[s].c[k]+ b[s].v[k];
      b[s].c[k]=SeInDiSp (b[s].c[k], rangeMin[k], rangeMax[k], rangeStep[k]);
      b[s].fLast=b[s].f;
      b[s].lifeCNT++;
    }
  }
  else
{
    for (int k=0; k < parameters; k++)
{
      b[s].v[k]=NewVector (k);
      b[s].c[k]=b[s].c[k]+ b[s].v[k];
      b[s].c[k]=SeInDiSp (b[s].c[k], rangeMin[k], rangeMax[k], rangeStep[k]);
      b[s].fLast=b[s].f;
      b[s].lifeCNT++;
    }
  }
}

NewVecror () - 是更改运动矢量(翻滚)的私密方法。 该方法应用于每个坐标。 这里的思路很简单:将相应坐标 v 的搜索边界之间的差异乘以范围[-1.0;1.0]中的随机数 r,然后乘以 lambda 比例因子(算法参数之一)。 细菌采用的运动矢量不改变,直到生命极限耗尽(在同一个地方产生新的细菌,但有新的运动矢量),在繁衍期间(克隆体有一个新的矢量)和健康恶化期间(试图找到一个新的更有利的环境)。

//——————————————————————————————————————————————————————————————————————————————
double C_AO_BFO::NewVector (int paramInd)
{
  double r=RNDfromCI (-1.0, 1.0);
  return lambda * v[paramInd]* r;
}
//——————————————————————————————————————————————————————————————————————————————

第二个公开的 Evaluation() 方法应在每次迭代时执行,它调用排序方法,检查全局解的更新,将分类菌落中最佳细菌的健康状况与找到的最佳解进行比较。

//——————————————————————————————————————————————————————————————————————————————
void C_AO_BFO::Evaluation ()
{
  Sorting ();

  if (b[0].f > fB)
{
    fB=b[0].f;
    ArrayCopy (cB, b[0].c, 0, 0, WHOLE_ARRAY);
  }
}
//——————————————————————————————————————————————————————————————————————————————

3. 测试结果

BFO 测试台结果:

2023.01.21 12:52:46.501 Test_AO_BFO (.US500Cash,M1) C_AO_BFO:50;0.01;0.8;100
2023.01.21 12:52:46.501 Test_AO_BFO (.US500Cash,M1)=============================
2023.01.21 12:52:48.451 Test_AO_BFO (.US500Cash,M1) 5 Rastrigin's; Func runs 10000 result: 72.94540549092933
2023.01.21 12:52:48.451 Test_AO_BFO (.US500Cash,M1) Score: 0.90383
2023.01.21 12:52:51.778 Test_AO_BFO (.US500Cash,M1) 25 Rastrigin's; Func runs 10000 result: 54.75744312933767
2023.01.21 12:52:51.778 Test_AO_BFO (.US500Cash,M1) Score: 0.67848
2023.01.21 12:53:21.197 Test_AO_BFO (.US500Cash,M1) 500 Rastrigin's; Func runs 10000 result: 40.668487609790404
2023.01.21 12:53:21.197 Test_AO_BFO (.US500Cash,M1) Score: 0.50391
2023.01.21 12:53:21.197 Test_AO_BFO (.US500Cash,M1)=============================
2023.01.21 12:53:23.211 Test_AO_BFO (.US500Cash,M1) 5 Forest's; Func runs 10000 result: 0.8569098398505888
2023.01.21 12:53:23.211 Test_AO_BFO (.US500Cash,M1) Score: 0.48471
2023.01.21 12:53:26.878 Test_AO_BFO (.US500Cash,M1) 25 Forest's; Func runs 10000 result: 0.37618151461180294
2023.01.21 12:53:26.878 Test_AO_BFO (.US500Cash,M1) Score: 0.21279
2023.01.21 12:54:22.339 Test_AO_BFO (.US500Cash,M1) 500 Forest's; Func runs 10000 result: 0.08748190028975696
2023.01.21 12:54:22.339 Test_AO_BFO (.US500Cash,M1) Score: 0.04948
2023.01.21 12:54:22.339 Test_AO_BFO (.US500Cash,M1)=============================
2023.01.21 12:54:28.849 Test_AO_BFO (.US500Cash,M1) 5 Megacity's; Func runs 10000 result: 4.8
2023.01.21 12:54:28.849 Test_AO_BFO (.US500Cash,M1) Score: 0.40000
2023.01.21 12:54:40.089 Test_AO_BFO (.US500Cash,M1) 25 Megacity's; Func runs 10000 result: 2.216
2023.01.21 12:54:40.089 Test_AO_BFO (.US500Cash,M1) Score: 0.18467
2023.01.21 12:55:24.640 Test_AO_BFO (.US500Cash,M1) 500 Megacity's; Func runs 10000 result: 0.4232
2023.01.21 12:55:24.640 Test_AO_BFO (.US500Cash,M1) Score: 0.03527

现在得出明确的结论还为时过早。 有必要首先分析与其它测试参与者相关的结果。

Rastrigin 测试函数上的 BFO
基于 Forest 测试函数的 BFO。
基于 Megacity 测试函数的 BFO。

我们关注测试可视化。 动画证实了在我们的算法中将“大于”算符替换为“大于或等于”的决定的正确性。 这允许细菌继续在测试函数的水平部分中移动。 这在 Forest 和 Megacity 函数中尤其明显。 即使根本没有函数梯度,细菌也会尝试继续前进。 还需要注意细菌菌落在视觉上分成几个单独的菌落的能力,这些菌落在视觉上分为不同的局部极值,这可以明确地被认为是一个积极的特征,尽管该算法不包含任何形成亚菌落的逻辑方法。 一般来说,细菌在搜索空间中的均匀运动是显而易见的,而无需尝试在任何方向上急剧跳跃,这可以通过均匀的增量运动 — 趋化性来解释。

到分析测试结果的时候了。 BFO 位于评级表的中间,在当前参与算法列表中的总体得分刚刚超过 55。 结果并不令人印象深刻,但也不差。 特别是,在具有 10 个变量的 Rastrigin 函数上获得了良好的结果。 在 50 和 1000 个变量的情况下,结果则明显更糟。 此外,该算法在 Forest 函数上表现不佳。 离散 Megacity 函数上相对良好的行为令人惊讶,因为算法中没有处理此类函数的机制。 此外,与其它算法相比,具有良好的可扩展性(测试采用 1000 个参数的 Megacity 进行)。

BFO 是一个具有广泛可能性的科学领域。 一般来说,可以对细菌觅食和动物觅食的许多方面进行建模,以提高优化性能。 对于 BFO 算法,控制参数的自动适应可能特别重要,因为有很多参数,并且可以提高性能,这是进行额外实验的原因。

BFO 具有许多优点,包括在初始化和参数选择期间对坐标初始值的敏感性低,可靠性好,逻辑简单,易于实现,并行化和全局搜索的可能性。 因而,BFO 算法可解决广泛的优化问题。 然而,BFO 也有许多缺点,包括收敛缓慢,在某些情况下无法超越局部最优,以及固定的步长。 BFO 是一种元启发式方法,这意味着它只是一个概念框架,可据其开发算法的各种修改版。 我在这里介绍的 BFO 版本只是众多可能性之一,应该被视为实验的起点,而非关于该主题的最后结语。

算法测试结果的直方图如下:

图例 3. 测试算法最终结果的直方图

关于细菌觅食优化(BFO)算法性质的结论:

优点:
1. 高速。
2. 逻辑简单。
3. 收敛贯穿所有迭代,尽管速度很慢。

缺点:
1. 收敛慢。
2. 没有退出局部极值的方法。

特注:需要文章中的代码等附件可以关注并且私聊我们,我们将免费赠送给您

欢迎大家把“赫兹量化”推荐给你的家人和朋友哟,为确保您能收到每一篇章,可以关注我们的官方账号,并帮忙点赞和转发,谢谢!


本文改进主要参考:

S. Li and J. Li, "Chaotic dung beetle optimization algorithm based on adaptive t-Distribution," 2023 IEEE 3rd International Conference on Information Technology, Big Data and Artificial Intelligence (ICIBA), Chongqing, China, 2023, pp. 925-933, doi: 10.1109/ICIBA56860.2023.10165106.

作者在上一篇文章中介绍了蜣螂优化算法(dung beetle optimizer,DBO),其具有收敛速度快和准确率高的特点,可以有效地解决复杂的寻优问题。然而虽然其具有比PSO、GWO等算法更好的优化性能,但其存在初始种群分布不均匀、全局探索和局部开发能力不平衡、易陷入局部最优等缺点。

因此,受混沌映射和自适应T分布的启发,提出对DBO算法进行改进。混沌映射如Logistic映射和Tent映射,能够提高初始种群在搜索空间的分布质量,加强其全局搜索能力;而自适应t分布能在迭代的不同时期提高算法的全局/局部搜索能力。两种方法相辅相成,能够帮助DBO算法获得更好的优化性能。

实验部分,本文将改进的DBO算法与DBO以及一些常用的智能算法在9个标准测试函数上进行实验对比,以验证改进的有效性。

00 文章目录

1 蜣螂优化算法原理

2 自适应混沌蜣螂优化算法

3 代码目录

4 实验结果

5 源码获取

01 蜣螂优化算法原理

关于蜣螂算法原理作者在上一篇文章中已经作了介绍,感兴趣的朋友可以点下面的链接查看。

超详细 | 蜣螂优化算法DBO原理及其实现(Matlab)

02 自适应混沌蜣螂(Adaptive Chaos DBO,AC-DBO)优化算法

2.1 改进的Tent混沌映射

与其他群智能算法一样,原始DBO在求解复杂问题时,通过随机生成位置的方法初始化种群的个体位置,会导致种群的多样性低,对问题进行寻优的收敛速度比较慢。为了能够让个体在算法开始时有较高的全局搜索能力,需要让种群的位置均匀分布在整个问题的解空间内,因此使用混沌算子对种群进行初始化。

混沌作为一种非线性的自然现象,以其混沌序列具有遍历性、随机性等优点,被广泛用于优化搜索问题。利用混沌变量搜索显然比无序随机搜索具有更大的优越性[1]。

目前文献中常用的混沌扰动方程有Logistic映射和Tent映射等。Logistic映射在作者前面的文章中介绍过,由文献[2]可知Logistic映射的分布特点是:中间取值概率比较均匀,但在两端概率特别高,因此当全局最优点不在设计变量空间的两端时,对寻找最优点是不利的。而Tent混沌映射具有比Logistic混沌映射更好的遍历均匀性和更快的搜索速度。下图中展示了Logistic和Tent的混沌序列:





可以看到,Logistic混沌映射在边界区域取值概率明显更高,而Tent在可行域的取值概率更为均匀,因此若将Logistic混沌映射用于初始化种群时,其混沌序列的不均匀性会影响算法寻优的速度和精度。因此本文利用Tent的遍历性产生更为均匀分布的混沌序列,减少初始值对算法优化的影响。

Tent混沌映射的表达式如下:



分析Tent混沌迭代序列能够发现序列中存在小周期,并且存在不稳周期点. 为避免Tent混沌序列在迭代时落入小周期点和不稳定周期点,在原有的Tent 混沌映射表达式上引入一个随机变量rand(0, 1) /N ,则改进后的Tent混沌映射表达式如下[3]:



其中: N 是序列内粒子的个数。引入随机变量rand(0, 1) /N 不仅仍然保持了Tent混沌映射的随机性、遍历性、规律性,而且能够有效避免迭代落入小周期点和不稳定周期点内。本文算法引入的随机变量,既保持了随机性, 又将随机值控制在一定的范围之内,保证了Tent混沌 的规律性.根据Tent混沌映射的特性。改进的Tent混沌序列效果如下:



由图可知,改进后的Tent混沌映射其均匀性得到了提高,因此本文以改进Tent混沌性来代替蜣螂优化算法的随机初始化,以提高和改善初始种群在搜索空间上的分布质量,加强其全局搜索能力,从而提高算法求解精度。


2.2 自适应t分布

t分布也叫学生t分布,包含自由度参数n。n的值决定t分布曲线的形状,n值越小,则曲线越平坦,n值越大,则曲线越陡峭。




t分布的概率密度函数为:




式中,t为自由度参数,x 为扰动力度,Γ( )为伽玛函数。当t(n→∞)→N(0,1)时,t(n→1)=C(0,1),N(0,1)为高斯分布,C(0,1)为柯西分布。高斯分布和柯西分布是t分布的两种边界特例[4],它们的函数分布如图2所示。



当算子发生柯西突变时,算法的全局搜索性能较好,种群多样性较高。当算子发生高斯突变时,算法收敛速度更快,局部寻优能力更强

t分布结合了柯西分布和高斯分布的优点,在自由度参数n从1→∞的过程中,可以通过t分布突变算子来平衡和提高算法的全局/局部搜索能力。因此,本文采用自由度参数n=iter的t分布来优化个体的搜索方向和距离,步长会随着迭代次数的增加而自适应变化。采用自适应t分布突变策略对蜣螂位置进行扰动的方程如下:



式中,xti为突变后的蜣螂位置,xi为第i只蜣螂个体位置,t(iter)为以迭代次数iter为自由度的t分布。

迭代开始时,t分布突变类似柯西突变,此时算法具有良好的全局探索能力,增加了种群的多样性,且跳出局部最优的能力也增强了。随着迭代次数的增加,t分布突变近似于高斯突变,提高了算法的局部开发能力,其对于整个种群的扰动力度也从强到弱转化。通过引入自适应t分布突变作为一种改进的搜索策略,能够有效增强算法的优化性能,有利于提高算法逃避局部最优的能力

通过自适应t分布突变扰动策略虽然能增强算法全局搜索和跳出局部最优的能力,但是没法确定扰动之后得到的新位置一定比原位置的适应度值要好,因此在进行变异扰动更新后,加入贪婪规则,通过比较新旧两个位置的适应度值,确定是否要更新位置



其中, xnewg(t)为经过贪婪规则更新后的个体位置,xlg(t)为扰动后的个体,xg(t)为扰动前的个体, f ()代表粒子适应度函数。

2.3 自适应混沌蜣螂优化算法步骤

综上所述,自适应混沌蜣螂优化算法主要分为六个步骤。

1)初始化种群大小,迭代次数,t分布概率等参数

2)使用改进的Tent混沌映射初始化蜣螂种群

3)根据目标函数计算所有蜣螂位置的适度值;

4)更新所有蜣螂的位置;

5)判断每个更新后的蜣螂是否出了边界;

6)若随机数rand小于给定P值,则根据t分布突变策略进行扰动,产生新解

7)根据贪婪规则确定是否更新

8)更新当前最优解及其适度值;

9)重复上述步骤,在 达到最大迭代次数后,输出全局最优值及其最优解。

流程图如下:




03 代码目录

代码注释完整,其中部分程序如下:



代码注释完整,其中部分程序如下:




04 实验结果

在本节中,通过单峰,多峰,固定多峰共9个经典测试函数验证AC-DBO的搜索性能,通过仅具有一个全局最优值的单峰函数来测试算法的局部搜索能力,并使用多峰函数来评估全局搜索能力。将改进的蜣螂优化算法与另4种被广泛研究的优化算法(PSO、GA、GWO、DBO)进行比较。

为保证实验公平性,所有算法的迭代次数与种群数都设置为100。

单峰函数采用F1,F2,F3。多峰函数采用F9,F10,F11。固定多峰函数采用F19,F20,F21。部分函数样图如下:







利用上述的5种优化算法对共计9种测试函数进行寻优,结果如下:



由图可以看出,改进后的算法在搜索精度以及收敛速度上皆优于其他算法,其性能得到了显著提高。


05 源码获取

见个人简介

参考文献

[1]张云鹏,左飞,翟正军.基于双Logistic变参数和Cheby-chev混沌映射的彩色图像密码算法[J.西北工业大学学报, 2010,28(4): 628-632.

[2]江善和,王其申,汪巨浪.一种新型SkewTent映射的混沌混合优化算法[J.控制理论与应用, 2007,24(2): 269-273.

[3]张娜,赵泽丹,包晓安,等.基于改进的Tent混沌万有引力搜索算法[J].控制与决策,2020,35(4):893-900.

[4]Fangjun Zhou , Xiangjun Wang , Min Zhang . Evolutionary Programming Using Mutations Based on the t Probability Distribution[J].2008.36(4):667-671.

另:如果有伙伴有待解决的优化问题(各种领域都可),可以发我,我会选择性的更新利用优化算法解决这些问题的文章。

如果这篇文章对你有帮助或启发,可以点击右下角的赞/在看(?_)?(不点也行)


返回

平台注册入口