インテリジェントな最適化アルゴリズム Gray Wolf Optimization Algorithm (GWO) の実装 (Python とソース コード)

1. ハイイロオオカミ最適化アルゴリズムの実装アイデア

ハイイロオオカミ オプティマイザー (GWO) は、2014 年に Seyedali Mirjalili らによって提案されたグループ インテリジェンス最適化アルゴリズムです。このアルゴリズムは、主に自然界のハイイロオオカミの集団の捕食行動にインスピレーションを得ています。ハイイロオオカミは、通常 5 ~ 12 頭で構成される社会的な動物です。通常の動物の群れとは異なり、この群れには非常に厳格な社会的支配階級が存在し、主に4つの階層からなるピラミッド構造によく似ています。
まず、最上位のレベルはαと呼ばれるもので、主に集団内で狩猟場所や休憩場所などのさまざまなルールを策定し、集団全体がその決定に従うことになります。次に、第 2 レベルは β と呼ばれます。このレベルのハイイロオオカミの個体は、主に α が適切な意思決定を行うのを助け、さまざまな意思決定の問題を α オオカミにフィードバックします。個体群全体におけるその地位は、α オオカミに次ぐものです。低レベルのハイイロオオカミ個体もベータオオカミの命令を受けなければなりません。次のレベルはデルタです。このレベルは執行者の役割を果たし、アルファ オオカミとベータ オオカミによって設定された規則と命令を実行に移します。彼らは見張り、偵察、ハンター、さらには集団内の負傷したオオカミの世話役になることもあります。最後のレベルは ω です。このレベルのハイイロオオカミ個体は最も脆弱な個体です。彼らは通常、人口の中で高齢か障害のある個体であるため、前の各レベルのハイイロオオカミ個体にのみ従うことができます。
上記の考えを組み合わせると、ハイイロオオカミ最適化アルゴリズムの原理は、社会階層の分類、獲物の探索、獲物の周囲の行動、獲物の攻撃の 4 つの基本行動に分類できますので、以下にこれら 4 つの基本行動を紹介します。

1. 社会階級構造の分類

このアルゴリズムでは、ハイイロオオカミ集団の社会階層構造に適合させるため、解候補の優劣を評価基準として用いており、また、解の一意性により、最初の3つのレベルα、βの数は、 δ は 1 に設定されます。つまり、候補解の中で最もパフォーマンスの高い解が α に設定され、2 番目と 3 番目の最適な解がそれぞれ β と δ に設定され、残りの解はすべて ω になります。より高いレベルのハイイロオオカミ個体に従う低レベルのハイイロオオカミ個体のルールに従って、ω 解はより良いパフォーマンスを達成するために α、β、δ 解を継続的に学習します。

2. 獲物を囲む

獲物を取り囲むハイイロオオカミの集団の特徴を考慮して、彼らの行動を記述するために次の公式が使用されます。
ここに画像の説明を挿入します
ここに画像の説明を挿入します

ここで、 t は現在の反復数、A ⃗ と C ⃗ は係数ベクトル、(X_p ) ⃗ はハイイロオオカミ個体の位置ベクトル、X ⃗ はハイイロオオカミ個体の位置情報です。
A ⃗ と C ⃗ は、それぞれ次の 2 つの式で計算されます。
ここに画像の説明を挿入します
ここに画像の説明を挿入します

このうち、a ⃗ は反復回数に応じて 2 から 0 まで直線的に減少し、r1 と r2 は両方とも 0 と 1 の間のランダム ベクトルです。

3. 獲物を攻撃する

包囲行動により、ハイイロオオカミの全個体が包囲内で獲物を制御し、αオオカミ、βオオカミ、δオオカミの誘導の下でωオオカミが狩りをすることになるが、獲物の現在地が不明であるため、最適な位置を代表するハイイロオオカミが行動することになる。解 オオカミα、β、δの位置情報は既知であるため、ωオオカミはハイイロオオカミα、β、δの位置情報を学習して獲物狩りを完了するように移動することになる。次の式は、個々のハイイロオオカミの捕食行動を表しています。
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します

上式から獲物の位置はランダムであることが分かり、ハイイロオオカミ個体はハイイロオオカミα、β、δの位置情報を学習し、獲物の近くをランダムに移動することで獲物の特定の位置を推定することになる。

4. 獲物を探す

ハイイロオオカミの集団がランダムに獲物を取り囲み始めると、獲物の探索プロセスも始まります。獲物を攻撃する原理的なプロセスから、係数ベクトル A ⃗ のサイズが個々のハイイロオオカミに直接影響することがわかります。反復プロセス全体では、A ⃗ の絶対値が 1 未満であることに加えて、A ⃗ の絶対値が 1 を超える状況も存在します。この条件下では、ハイイロオオカミの個体は包囲円の周りに拡大します。 、したがって、より多くの獲物が存在する可能性のある場所を見つけます。つまり、|A|≧1 の場合、候補解は現在のプレイから外れる傾向にあり、|A|<1 の場合、候補解は徐々にプレイの位置に収束していく。
係数ベクトル A ⃗ に加えて、係数ベクトル C ⃗ もあります。C ⃗ は通常 0 から 2 までのランダムな値です。このベクトルの役割は、獲物の位置情報に新しいランダムな重みを追加することに似ています。自然, , ハイイロオオカミ個体群の獲物の狩猟は通常スムーズではありません. 時々、探索行動全体に影響を与える特定の障害があり、ハイイロオオカミ個体群が直接かつ迅速に獲物に近づくことが不可能になります. 係数ベクトル C ⃗ は、ランダム性を追加すると、最適化プロセス中にハイイロオオカミの個体群全体がよりランダムな動作を示すようになり、より多くの領域を探索し、局所的な最適性に陥るのを避けることができます。

2. アルゴリズムのステップ

ハイイロオオカミ最適化アルゴリズムを使用して最適化問題を解決するときの具体的な手順は、次のように要約できます。

  1. 母集団内の個人の位置情報は、最適化される問題の解として使用され、母集団内のすべての個人の位置情報は、最適化される問題の解の範囲に従ってランダムに初期化されます。
  2. 初期化パラメータ a ⃗、A ⃗、および C ⃗;
  3. 最適化の対象となる問題に応じて、母集団の各個体の適応度を計算して分類し、適応度が高いほどその個体の位置情報が最適解に近いことを示し、適応度上位 3 個体をそれぞれランク付けします。それらをハイイロオオカミα、β、δとして定義し、現在の最適な位置情報を保存します。
  4. 母集団内の各個人の位置情報を順番に更新します。
  5. 更新された各個体の位置情報に対して適応度が再計算され、新たな適応度に応じてハイイロオオカミα、β、δの位置情報と過去の最適位置情報が更新され、パラメータa⃗が更新される. A ⃗ および C ⃗;
  6. 反復回数に応じて手順 3 ~ 5 を繰り返し、最大反復回数に達すると反復処理を停止し、アルゴリズム最適化後の最適解となる過去の最適位置情報を出力します。

3. 例

解決すべき問題:
Rosenbrock の場合、値の範囲は [-10,10]、値の範囲内の理想的な最適解は 0、その探索の空間次元は 20 に設定されます。
ここに画像の説明を挿入します

実装ソースコード:

#库的导入
import numpy as np
import matplotlib.pyplot as plt
import heapq

#待求解问题,求解问题为求最小值
def function(x):
    y1 = 0
    for i in range(len(x)-1):
        y2 = 100*((x[i+1] - x[i]**2)**2)+(x[i]-1)**2
        y1 = y1 + y2
    y = abs(0 - y1)
    return y

m = 30   #种群数量
imax = 100   #迭代次数
dimen = 20   #解的搜索维度
rangelow = -10   #解的最小取值
rangehigh = 10   #解的最大取值
amax = 2   #系数向量初始值

#pop用于存储种群个体的位置信息,pop_fitness用于存储个体对应的适应度值
pop = np.zeros((m,dimen))
pop_fitness = np.zeros(m)
#对种群个体进行初始化并计算对应适应度值
for j in range(m):
    pop[j] = np.random.uniform(low=rangelow, high=rangehigh,size=(1, dimen))
    pop_fitness[j] = function(pop[j])

#allbestpop,allbestfit分别存储种群在历史迭代过程中最优个体解及对应适应度
allbestpop,allbestfit = pop[pop_fitness.argmin()].copy(),pop_fitness.min()

#通过排序找出种群中适应度值最优的前三个个体,并获得它们的位置信息
pop_fitness1 = pop_fitness.flatten()
pop_fitness1 = pop_fitness1.tolist()
three = list(map(pop_fitness1.index, heapq.nsmallest(3, pop_fitness1)))
Xalpha = pop[three[0]]
Xbeta = pop[three[1]]
Xdelta = pop[three[2]]

#his_bestfit存储每次迭代时种群历史适应度值最优的个体适应度
his_bestfit=np.zeros(imax)

#开始训练
for i in range(imax):
    print("The iteration is:", i + 1)
    #对系数向量的计算参数a进行计算
    iratio = i / imax
    a = amax * (1 - iratio)
    #对每个个体进行位置更新
    for j in range(m):
        #分别计算在适应度值最优的前三个个体的影响下,个体的位置移动量X1、X2、X3
        C1 = 2 * np.random.rand()
        Dalpha = np.abs(C1 * Xalpha - pop[j])
        A1 = 2 * a * np.random.rand() - a
        X1 = Xalpha - A1 * Dalpha

        C2 = 2 * np.random.rand()
        Dbeta = np.abs(C2 * Xbeta - pop[j])
        A2 = 2 * a * np.random.rand() - a
        X2 = Xbeta - A2 * Dbeta

        C3 = 2 * np.random.rand()
        Ddelta = np.abs(C3 * Xdelta - pop[j])
        A3 = 2 * a * np.random.rand() - a
        X3 = Xdelta - A3 * Ddelta
        #计算个体移动后的位置及适应度值
        pop[j] = (X1 + X2 + X3) / 3
        pop_fitness[j] = function(pop[j])
    #对种群历史最优位置信息与适应度值进行更新
    if pop_fitness.min() < allbestfit:
        allbestfit = pop_fitness.min()
        allbestpop = pop[pop_fitness.argmin()].copy()

    #通过排序找出种群中适应度值最优的前三个个体,并获得它们的位置信息
    pop_fitness1 = pop_fitness.flatten()
    pop_fitness1 = pop_fitness1.tolist()
    three = list(map(pop_fitness1.index, heapq.nsmallest(3, pop_fitness1)))
    Xalpha = pop[three[0]]
    Xbeta = pop[three[1]]
    Xdelta = pop[three[2]]

    #存储当前迭代下的种群历史最优适应度值并输出
    his_bestfit[i] = allbestfit
    print("The best fitness is:", allbestfit)
print("After iteration, the best pop is:",allbestpop)
print("After iteration, the best fitness is:","%e"%allbestfit)

#输出训练后种群个体适应度值的均值与标准差
mean = np.sum(pop_fitness)/m
std = np.std(pop_fitness)
print("After iteration, the mean fitness of the swarm is:","%e"%mean)
print("After iteration, the std fitness of the swarm is:","%e"%std)
#将结果进行绘图
fig=plt.figure(figsize=(12, 10), dpi=300)
plt.title('The change of best fitness',fontdict={
    
    'weight':'normal','size': 30})
x=range(1,101,1)
plt.plot(x,his_bestfit,color="red",label="GWO",linewidth=3.0, linestyle="-")
plt.tick_params(labelsize=25)
plt.xlim(0,101)
plt.yscale("log")
plt.xlabel("Epoch",fontdict={
    
    'weight':'normal','size': 30})
plt.ylabel("Fitness value",fontdict={
    
    'weight':'normal','size': 30})
plt.xticks(range(0,101,10))
plt.legend(loc="upper right",prop={
    
    'size':20})
plt.savefig("GWO.png")
plt.show()

図の横軸は反復回数、縦軸は最適な適応度である。
ここに画像の説明を挿入します
参照ソースコード

おすすめ

転載: blog.csdn.net/weixin_42051846/article/details/128725340