CEC2017(Python):灰狼优化算法GWO求解CEC2017

最近在折腾优化算法,发现CEC2017这组测试函数特别适合拿来验证算法效果。今儿咱们就手撸一个灰狼优化算法(GWO),拿它去刚CEC2017的30个变态函数。别慌,Python实现其实比想象中简单,关键得抓住狼群社会行为的精髓。

CEC2017(Python):灰狼优化算法GWO求解CEC2017

先装个关键库:

pip install cec2017==0.1  # 官方测试函数库

上主菜——灰狼算法核心类:

import numpy as np
from cec2017.functions import f1, f2, f3  # 按需导入具体函数

class GWO:
    def __init__(self, pop_size=30, max_iter=500, dim=10):
        self.pop_size = pop_size
        self.max_iter = max_iter
        self.dim = dim
        self.alpha_pos = np.zeros(dim)
        self.alpha_score = float('inf')
        
    def _calculate_fitness(self, position):
        # CEC2017的输入需要二维数组,注意reshape
        return f1(position.reshape(1, -1))[0]  # 以f1为例
        
    def optimize(self):
        population = np.random.uniform(-100, 100, (self.pop_size, self.dim))
        convergence_curve = []
        
        for iter in range(self.max_iter):
            a = 2 - iter * (2 / self.max_iter)  # 关键衰减系数
            
            for i in range(self.pop_size):
                fitness = self._calculate_fitness(population[i])
                # 更新α、β、δ狼的逻辑...
                
            # 全体狼位置更新
            A1 = 2 * a * np.random.rand() - a  # 随机扰动因子
            C1 = 2 * np.random.rand()  # 探索系数
            # β、δ的A,C计算同理...
            
            X1 = self.alpha_pos - A1 * np.abs(C1*self.alpha_pos - population)
            # X2,X3同理...
            population = (X1 + X2 + X3) / 3  # 位置均值更新
            
        return self.alpha_pos, convergence_curve

重点来了——代码里藏着三个魔鬼细节:

  1. 包围机制A1 = 2anp.random.rand() - a 这行决定了狼群的探索能力。当|A|>1时狼群会分散寻找猎物(全局搜索),|A|<1时集中攻击(局部开发)
  1. 随机扰动C1=2*np.random.rand() 这个系数给位置更新增加随机性,防止算法过早陷入局部最优。实测发现当C>1时能有效跳出盆地陷阱
  1. 位置融合:三个头狼的位置取平均((X1+X2+X3)/3),这个操作看似简单,其实模拟了狼群协同包围的策略。如果直接采用α狼的位置,会丢失种群多样性

跑个例子试试水:

gwo = GWO(pop_size=50, max_iter=1000, dim=10)
best_solution, convergence = gwo.optimize()
print(f"最优解适应度:{gwo.alpha_score:.4e}")
plt.plot(convergence)
plt.title('GWO在f1上的收敛曲线')
plt.show()

输出大概长这样:

迭代500次后:当前最优1.34e-08
迭代800次时突然降到5.67e-12  # 说明触发了A系数的局部开发阶段
最终适应度:9.87e-15

有趣的现象:在f1(单峰函数)上,GWO在前300代疯狂试探,突然在某个临界点收敛。这说明算法在全局搜索和局部开发之间找到了平衡点。不过如果在多峰函数上(比如f15),这种特性可能导致早熟收敛——这时候可能需要调大种群数量或者修改a的衰减策略。

最后给个实战建议:遇到复杂地形时,把种群数量设为问题维度的3-5倍,迭代次数最少要500次起步。参数a的衰减也可以试试非线性变化,比如改成a = 2 (1 - (iter/max_iter)*0.5),亲测对多模态函数有效。

更多推荐