自适应改进灰狼算法

灰狼算法(GWO)非自动化的参数调整和缺乏系统的停止标准,通常会导致计算资源的低效使用。本文介绍一个改进版的灰狼优化器(GWO),名为自适应的GWO(AGWO),它通过在优化过程中根据候选方案的适配性自适应调整探索/开发参数来解决这些问题。
在优化过程中,通过基于候选解决方案的适配性历史,自适应地调整探索/开发参数来解决这些问题。通过根据优化过程中适配度提高的重要性来控制停止标准,AGWO解决了这些问题,可以在最短的时间内自动收敛到一个足够好的最优方案。

GWO算法局限性

GWO算法的一个主要局限性是,它要求我们选择一些最大的迭代值。要求我们选择一些最大的迭代值T,这影响了操作的计算时间。如果这个参数被选得太小,我们就会过早地收敛到一个不满意的点上这可能离目标函数的真正最小值很远。另一方面,增加这个参数来确保收敛到一个假定的好的点可能会导致计算时间的浪费,而对最终的质量没有明显的改善。

改进灰狼算法简介

灰狼算法的改进角度有三种,一是改参数,增加一些context,而是与其他算法杂交,取他人之长,三是设计算子,如下图所示:

灰狼算法能和机器学习模型结合吗 灰狼算法的改进_人工智能

这些改进措施有缺陷:

1、没有分析目标函数,一个未知的目标函数有一个未知的复杂性,未知的目标函数有一个未知的复杂性。而所需时间在很大程度上取决于目标函数。

2、这些算法都不能根据目标函数自动调整收敛参数,仍然需要事先输入最大迭代次数。

AGWO

AGWO提出了阻尼参数的概念,即减少系数灰狼算法能和机器学习模型结合吗 灰狼算法的改进_人工智能_02,它可以减少探索率。这种参数的减少类似于基于梯度的方法中常用的学习率衰减。AGWO令历史的窗口平均适应度灰狼算法能和机器学习模型结合吗 灰狼算法的改进_算法_03
和其他自适应GWO算法一样,AGWO也是修改灰狼算法能和机器学习模型结合吗 灰狼算法的改进_python_04,当且仅当灰狼算法能和机器学习模型结合吗 灰狼算法的改进_自适应_05灰狼算法能和机器学习模型结合吗 灰狼算法的改进_python_04得以衰减,即灰狼算法能和机器学习模型结合吗 灰狼算法的改进_算法_07。否则更新狼群参数。

由此提出了宕机准则:灰狼算法能和机器学习模型结合吗 灰狼算法的改进_人工智能_08是停止迭代。

AGWO类别深度学习里的梯度优化器Adam,利用适应度函数的梯度来选取灰狼算法能和机器学习模型结合吗 灰狼算法的改进_python_04,即:

灰狼算法能和机器学习模型结合吗 灰狼算法的改进_人工智能_10灰狼算法能和机器学习模型结合吗 灰狼算法的改进_python_04灰狼算法能和机器学习模型结合吗 灰狼算法的改进_灰狼算法能和机器学习模型结合吗_12的衰减而衰减。

灰狼算法能和机器学习模型结合吗 灰狼算法的改进_python_13

代码

详细代码见这个github仓库,这里分析AGWO代码:

def AGWO(objf, lb, ub, dim, SearchAgents_no, Max_iter):
    # initialize alpha, beta, and delta_pos
    # objf: 目标函数
    # dim: 参数个数
    # lb: 参数搜索下限
    # ub: 参数搜索上限
    
    Alpha_pos = np.zeros(dim)
    Alpha_score = float("inf")

    Beta_pos = np.zeros(dim)
    Beta_score = float("inf")

    Delta_pos = np.zeros(dim)
    Delta_score = float("inf")

    if not isinstance(lb, list):
        lb = [lb] * dim
    if not isinstance(ub, list):
        ub = [ub] * dim

    # Initialize the positions of search agents
    # Position 的行表示每只灰狼,列表示各个待搜索的参数
    Positions = np.zeros((SearchAgents_no, dim))
    Prev_Positions = np.zeros((SearchAgents_no, dim))
    for i in range(dim):
        Positions[:, i] = (
            np.random.uniform(0, 1, SearchAgents_no) * (ub[i] - lb[i]) + lb[i]
        )

    Convergence_curve = np.zeros(Max_iter)
    s = solution()
    print('AGWO is optimizing  "' + objf.__name__ + '"')

    timerStart = time.time()
    dF_avg_list = []
    F_avg_list = []
    a_list = []
    damper = 1
    # Main loop
    for l in range(0, Max_iter):
        dF = []
        F_all = []
        for i in range(0, SearchAgents_no):
            # Return back the search agents that go beyond the boundaries of the search space
            for j in range(dim):
                Positions[i, j] = np.clip(Positions[i, j], lb[j], ub[j])
            # Calculate objective function for each search agent
            fitness = objf(Positions[i, :])
            if l ==0:
                dF_avg = float('-inf')
            if l != 0:
                Prev_fitness = objf(Prev_Positions[i, :])
                dF.append(fitness - Prev_fitness)
                F_all.append(fitness)
            # Update Alpha, Beta, and Delta
            if fitness < Alpha_score:
                Delta_score = Beta_score  # Update delte
                Delta_pos = Beta_pos.copy()
                Beta_score = Alpha_score  # Update beta
                Beta_pos = Alpha_pos.copy()
                Alpha_score = fitness
                # Update alpha
                Alpha_pos = Positions[i, :].copy()

            if fitness > Alpha_score and fitness < Beta_score:
                Delta_score = Beta_score  # Update delte
                Delta_pos = Beta_pos.copy()
                Beta_score = fitness  # Update beta
                Beta_pos = Positions[i, :].copy()

            if fitness > Alpha_score and fitness > Beta_score and fitness < Delta_score:
                Delta_score = fitness  # Update delta
                Delta_pos = Positions[i, :].copy()

        Convergence_curve[l] = Alpha_score

        ########################### ADAPTIVE GWO #####################################################
        ### Epsilon parameter (Equation 4 in paper)
        eps = 1e-5
        ### Damping parameter (Algorithm 1 in paper)
        gamma = 0.95 
        ### Minimum initial steps (Full Exploration Time)
        min_steps = 10
        ### delta (threshold in paper )
        threshold = 1e-3 

        ##### Tune the damper variable with gamma
        if l>min_steps and F_avg >= (mov_avg_F - eps):
            damper = damper * gamma
        
        #### Store function values and changes 
        if l != 0:
            dF_avg = np.mean(np.abs(dF))
            dF_avg_list.append(dF_avg)
            F_avg = np.mean(F_all)
            F_avg_list.append(F_avg)

        #### Full Exploration
        if l <= min_steps:
            a = 2
        #### Control parameter 'a' with AGWO damper
        Delta = False ### Using Extended Delta Version if True
        if l > min_steps: 
            if Delta == False:
                ### AGWO with epsilon (Damper only)
                a = damper * 2
            else:
                ## AGWO Delta (Extended version in the paper)
                a = 0.9*a + 0.1 * damper * 2 * (dF_avg)/(np.sqrt(E_g2))
                a = np.clip(a ,0,2)
        
        if Delta == True:
            if l ==0 :
                E_g2 = 0
            else: 
                E_g2 =  (dF_avg)**2

        #### Moving Average (Sliding window for objective function values)
        mov_avg_dF = np.mean(dF_avg_list[-10:])  # Exclude -inf at 0
        mov_avg_F = np.mean(F_avg_list[-10:])  # Exclude -inf at 0

        ###### Stopping criteria
        if (l>min_steps and a < threshold ) and F_avg >= mov_avg_F -eps:
            break

        a_list.append(a)
        ############################################################################################   

        # Update the Position of search agents including omegas (GWO Original implemented as EvoloPy)
        for i in range(0, SearchAgents_no):
            for j in range(0, dim):

                r1 = random.random()  # r1 is a random number in [0,1]
                r2 = random.random()  # r2 is a random number in [0,1]

                A1 = 2 * a * r1 - a
                C1 = 2 * r2

                D_alpha = abs(C1 * Alpha_pos[j] - Positions[i, j])
                X1 = Alpha_pos[j] - A1 * D_alpha

                r1 = random.random()
                r2 = random.random()

                A2 = 2 * a * r1 - a
                C2 = 2 * r2

                D_beta = abs(C2 * Beta_pos[j] - Positions[i, j])
                X2 = Beta_pos[j] - A2 * D_beta

                r1 = random.random()
                r2 = random.random()

                A3 = 2 * a * r1 - a
                C3 = 2 * r2

                D_delta = abs(C3 * Delta_pos[j] - Positions[i, j])
                X3 = Delta_pos[j] - A3 * D_delta
                Prev_Positions[i,j]= Positions[i,j]
                Positions[i, j] = (X1 + X2 + X3) / 3  

        if l % 100 == 0:
            print(
                ["At iteration " + str(l) + " the best fitness is " + str(Alpha_score)]
            )

    print("Damper: ", damper)
    timerEnd = time.time()
    s.executionTime = timerEnd - timerStart
    s.convergence = Convergence_curve
    s.optimizer = "AGWO"
    s.objfname = objf.__name__
    s.stopiter = l 
    s.dF_list = dF_avg_list
    s.F_list = F_avg_list 
    s.a_list = a_list

    return s