种群优化算法:灰狼优化器

灰狼算法是 2014 年开发出的一种元启发式随机群体智能算法。 它的思路是基于灰狼群狩猎模型。 狼群内有四种类型阶层:阿尔法、贝塔、德尔塔、和欧米茄。 阿尔法阶层在群体决策和管理方面拥有最大的“权重”。 接下来是贝塔和德尔塔阶层,它们服从阿尔法截仓,并拥有对狼群内其余阶层成员的压制。 欧米茄阶层的狼总是服从其余的统治阶层狼。

在狼的阶层数学模型中,阿尔法阶层狼被认为是狼群中的主导狼,它的命令应该由狼群成员执行。 贝塔阶层的从属狼协助阿尔法阶层制定决策,被认为是阿尔法角色的最佳候选。 德尔塔阶层狼应该服从阿尔法和贝塔阶层,但它们支配着欧米茄阶层。 欧米茄阶层狼被认为是狼群的替罪羊,也是重要性最低下的个体。 它们只允许在最后才能进食。 阿尔法阶层被认为是最有利的解。

第二和第三最佳解分别是贝塔和德尔塔阶层。 欧米茄阶层则认为是解的残料。 假设最适者的狼(阿尔法、贝塔、和德尔塔),即最接近猎物的狼,然后接近的是其余的狼。 每次接近后,就能判定谁是这个阶段的阿尔法、贝塔和德尔塔,然后狼群再次重新排列。 编队持续进行,直至狼群聚集在一起,这将是以最小距离进行攻击的最优方向。

在算法过程中,执行 3 个主要阶段,其中狼群搜索猎物、包围、和攻击猎物。 搜索揭示出阿尔法、贝塔和德尔塔 — 最接近猎物的狼。 而其余的,服从占主导地位的指挥,也许会开始包围猎物,或继续随机移动,以便寻找最佳选项。

2 条所述情况。 算法说明

图 1 示意性地展示狼群的阶层结构。阿尔法阶层起着主导作用。

图例 1. 狼群中的社会阶层

数学模型和算法
社会阶层:

  • 优等解是由阿尔法(α)狼形成的。
  • 二等解由贝塔(β)狼形成。
  • 三等解由德尔塔(δ)狼形成。
  • 其它可能的解,由欧米茄伏(ω)狼形成。

包围猎物:当已经有最佳解的阿尔法、贝塔、和德尔塔在场时,进一步的行动取决于欧米茄。
 

图例 2. 狩猎阶段:搜索、包围、攻击。

算法的所有迭代都表现为三个阶段:搜索、包围、和狩猎。 该算法的规范版本具有引入的a 计算比率,以提高算法的收敛性。 该比率在每次迭代时递减,直至为零。 只要比率超过 1,狼群的初始化就会持续进行。 在这个阶段,猎物的位置是完全未知的,所以狼群应该是随机分布的。

在“搜索”阶段之后,判定适应度函数的值,然后才有可能进入“包围”阶段。 在此阶段,a 比率大于 1。 这意味着阿尔法、贝塔和德尔塔正在远离它们之前的位置,从而可以优调估算猎物的位置。 当 a 比率等于 1 时,“攻击”阶段开始,而比率在迭代结束前趋于 0。 这导致狼群接近猎物,表明已经找到了最佳位置。 虽然,如果在这个阶段,其中某只狼找到了更好的解,那么猎物的位置和狼群的层次结构将会更新,但比例仍然趋于 0。 变化的过程由非线性函数表示。 这些阶段示意如图例 2 所示。

欧米茄阶层的狼,其行为在所有世代都是不变的,包括遵循当前占主导地位的个体位置之间的几何中心。 在图例 3 中,阿尔法、贝塔和德尔塔在随机方向上偏离它们之前的位置,半径由系数给出,欧米茄移动到它们之间的中心,但在半径内有一定程度偏离它的概率。 半径决定了 a比率,正如我们记得的那样,它的变化导致半径成比例地减小。

图例 3. 欧米茄相对阿尔法、贝塔和德尔塔的的运动图

GWO 算法的伪代码如下:

1) 随机初始化灰狼种群。
2) 计算种群每只个体成员的体质状况。
3) 狼群领导者:
-α = 具有最佳体质值的成员
-β = 第二等强大的成员(就体质值而言)
-δ = 第三等强大的成员(就体质值而言)
根据 α、β、δ 方程更新所有欧米茄狼的位置
4) 计算种群中每个成员的体质。
5) 重复步骤 3。

我们继续讨论算法代码。 我对原始版本所做的唯一补充就是能够设置狼群中主导狼的数量。 现在,您可以设置任意数量的主导者,最多可达整个狼群。 对于特定任务这可能很实用。

如往常一样,我们从算法的基本单元 — 狼开始,这是问题的解。 这是一个包含坐标数组和猎物值(适应度函数)的结构。 对于主导者和次等成员,结构是相同的。 这简化了算法,并允许我们在循环操作中使用相同的结构。 甚至,在所有迭代过程中,狼的角色会多次变化。 角色由排序后在数组中的位置唯一确定。 主导者位于数组的开头。

//——————————————————————————————————————————————————————————————————————————————
struct S_Wolf
{double c []; //coordinatesdouble p;    //prey
};
//——————————————————————————————————————————————————————————————————————————————

狼群由一个紧凑且易于理解的类代表。 在此,我们声明要优化的参数范围和步长,最佳生产位置,最佳解的值,和辅助函数。

//——————————————————————————————————————————————————————————————————————————————
class C_AO_GWO //wolfpack
{//============================================================================public: double rangeMax  []; //maximum search rangepublic: double rangeMin  []; //manimum search rangepublic: double rangeStep []; //step searchpublic: S_Wolf wolves    []; //wolves of the packpublic: double cB        []; //best prey coordinatespublic: double pB;           //best preypublic: void InitPack (const int    coordinatesP,   //number of opt. parametersconst int    wolvesNumberP,  //wolves numberconst int    alphaNumberP,   //alpha beta delta numberconst int    epochCountP);   //epochs numberpublic: void TasksForWolves      (int epochNow);public: void RevisionAlphaStatus ();//============================================================================private: void   ReturnToRange (S_Wolf &wolf);private: void   SortingWolves ();private: double SeInDiSp      (double In, double InMin, double InMax, double Step);private: double RNDfromCI     (double Min, double Max);private: int    coordinates;     //coordinates numberprivate: int    wolvesNumber;    //the number of all wolvesprivate: int    alphaNumber;     //Alpha beta delta number of all wolvesprivate: int    epochCount;private: S_Wolf wolvesT    [];   //temporary, for sortingprivate: int    ind        [];   //array for indexes when sortingprivate: double val        [];   //array for sortingprivate: bool   searching;       //searching flag
};
//——————————————————————————————————————————————————————————————————————————————

传统上,类声明后跟初始化。 而在此,我们重置为狼群适应度的最小 “double” 值,并分配数组的大小。

//——————————————————————————————————————————————————————————————————————————————
void C_AO_GWO::InitPack (const int    coordinatesP,   //number of opt. parametersconst int    wolvesNumberP,  //wolves numberconst int    alphaNumberP,   //alpha beta delta numberconst int    epochCountP)    //epochs number
{MathSrand (GetTickCount ());searching = false;pB        = -DBL_MAX;coordinates  = coordinatesP;wolvesNumber = wolvesNumberP;alphaNumber  = alphaNumberP;epochCount   = epochCountP;ArrayResize (rangeMax,  coordinates);ArrayResize (rangeMin,  coordinates);ArrayResize (rangeStep, coordinates);ArrayResize (cB,        coordinates);ArrayResize (ind, wolvesNumber);ArrayResize (val, wolvesNumber);ArrayResize (wolves,  wolvesNumber);ArrayResize (wolvesT, wolvesNumber);for (int i = 0; i < wolvesNumber; i++){ArrayResize (wolves  [i].c, coordinates);ArrayResize (wolvesT [i].c, coordinates);wolves  [i].p = -DBL_MAX;wolvesT [i].p = -DBL_MAX;}
}
//——————————————————————————————————————————————————————————————————————————————

每次迭代时调用的第一个公开方法最令人难以理解,也是体量最庞大的。 此处是算法的主要逻辑。 事实上,该算法的性能是严格由等式描述的概率机制提供的。 我们来逐步研究此方法。 在第一次迭代中,当预期猎物的位置未知时,在检查标志后,我们只需依从来自优化参数最大值和最小值的生成值,即可将狼发往随机方向。

//----------------------------------------------------------------------------
//space has not been explored yet, then send the wolf in a random direction
if (!searching)
{for (int w = 0; w < wolvesNumber; w++){for (int c = 0; c < coordinates; c++){wolves [w].c [c] = RNDfromCI (rangeMin [c], rangeMax [c]);wolves [w].c [c] = SeInDiSp  (wolves [w].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);}}searching = true;return;
}

在算法描述的规范版本中,存在运算向量的方程。 然而,它们以代码的形式表达更加清晰。 欧米茄狼的计算是在阿尔法、贝塔、和的额尔塔狼之前进行的,因为我们需要使用前面的主导者数值。

提供三个狩猎阶段(搜索、包围、和攻击)的主要组成部分是 a 比率。 它代表对当前迭代和总迭代次数的非线性依赖性,并且趋于 0。 等式的下一个组成部分是 Ai 和 Сi

  • Ai = 2.0 * a * r1 - a;
  • Ci = 2.0 * r2;

其中 r1 和 r2 是在 [0.0;1.0] 范围内的随机数。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部