狼群算法实战:用Python从零实现智能优化(附完整代码)
·
狼群算法实战:用Python从零实现智能优化(附完整代码)
自然界中狼群的协作捕猎行为启发了众多智能优化算法的设计。狼群算法(Wolf Pack Algorithm, WPA)通过模拟狼群的社会分工和捕猎策略,展现出强大的全局搜索能力。本文将带您从零开始实现这一算法,并通过可视化展示其优化过程。
1. 算法核心原理拆解
狼群算法的精髓在于将狼群的社会结构转化为数学建模。狼群中主要包含三类角色:
- 头狼(Leader):当前适应度最优的个体,负责指挥群体行动
- 探狼(Scouter):负责探索未知区域,寻找更优解
- 猛狼(Follower):响应头狼召唤,向最优位置聚集
算法通过以下三种智能行为实现优化:
# 伪代码展示算法流程
def wolf_pack_optimization():
initialize_population() # 初始化狼群
while not stopping_condition:
scout_phase() # 探狼游走搜索
summon_phase() # 猛狼奔袭
siege_phase() # 群体围攻
update_hierarchy() # 更新头狼
population_renew() # 群体更新
return best_solution
三种行为对应的数学表达:
| 行为类型 | 位置更新公式 | 参数说明 |
|---|---|---|
| 游走行为 | $x_{id}^p = x_{id} + sin(2π×p/h)×step_a^d$ | p:方向序号, h:总方向数 |
| 召唤行为 | $x_{id}^{k+1} = x_{id}^k + step_b^d⋅\frac{(g_d^k−x_{id}^k)}{ | g_d^k−x_{id}^k |
| 围攻行为 | $x_{id}^{k+1} = x_{id}^k + λ⋅step_c^d⋅ | G_d^k−x_{id}^k |
2. Python实现详解
2.1 基础框架搭建
首先构建算法的主框架,包含必要的类和基本方法:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
class WolfPackAlgorithm:
def __init__(self, objective_func, dim, lb, ub,
pop_size=50, max_iter=100,
alpha=0.5, beta=0.5, delta=0.5):
"""
初始化狼群算法参数
:param objective_func: 目标函数
:param dim: 问题维度
:param lb: 变量下界
:param ub: 变量上界
:param pop_size: 种群规模
:param max_iter: 最大迭代次数
:param alpha: 探狼比例因子
:param beta: 群体更新因子
:param delta: 步长调节因子
"""
self.obj_func = objective_func
self.dim = dim
self.lb = lb
self.ub = ub
self.pop_size = pop_size
self.max_iter = max_iter
self.alpha = alpha
self.beta = beta
self.delta = delta
# 初始化种群
self.population = np.random.uniform(lb, ub, (pop_size, dim))
self.fitness = np.array([self.obj_func(ind) for ind in self.population])
self.leader_idx = np.argmin(self.fitness)
self.leader_pos = self.population[self.leader_idx].copy()
self.leader_fit = self.fitness[self.leader_idx]
# 记录优化过程
self.history = {
'positions': [],
'fitness': [],
'leader_pos': []
}
2.2 核心行为实现
探狼游走行为
def scout_phase(self, T_max=10):
# 确定探狼数量
S_num = np.random.randint(
int(self.pop_size/(self.alpha+1)),
int(self.pop_size/self.alpha)+1
)
# 选择适应度较好的个体作为探狼(排除头狼)
scout_indices = np.argsort(self.fitness)[1:S_num+1]
for idx in scout_indices:
improved = False
for t in range(T_max):
# 随机选择游走方向
h = np.random.randint(4, 8) # 方向数
p = np.random.randint(1, h+1)
# 计算游走步长
step_a = (self.ub - self.lb) / (10 * self.delta)
# 更新位置
new_pos = self.population[idx] + \
np.sin(2*np.pi*p/h) * step_a
# 边界处理
new_pos = np.clip(new_pos, self.lb, self.ub)
# 评估新位置
new_fit = self.obj_func(new_pos)
if new_fit < self.fitness[idx]:
self.population[idx] = new_pos
self.fitness[idx] = new_fit
improved = True
# 检查是否成为头狼
if new_fit < self.leader_fit:
self.leader_idx = idx
self.leader_pos = new_pos.copy()
self.leader_fit = new_fit
break
if not improved:
# 未改进则随机移动
self.population[idx] += np.random.uniform(-1, 1, self.dim) * step_a
self.population[idx] = np.clip(self.population[idx], self.lb, self.ub)
self.fitness[idx] = self.obj_func(self.population[idx])
猛狼召唤行为
def summon_phase(self):
# 猛狼数量为剩余个体
follower_indices = [i for i in range(self.pop_size)
if i != self.leader_idx]
step_b = (self.ub - self.lb) / (5 * self.delta) # 奔袭步长
for idx in follower_indices:
# 计算与头狼的距离
dist = np.linalg.norm(self.population[idx] - self.leader_pos)
# 距离判定因子
d_near = np.sum(self.ub - self.lb) / (self.dim * 10)
if dist > d_near:
# 向头狼移动
direction = (self.leader_pos - self.population[idx]) / \
(dist + 1e-10) # 避免除以零
new_pos = self.population[idx] + step_b * direction
# 边界处理
new_pos = np.clip(new_pos, self.lb, self.ub)
# 评估新位置
new_fit = self.obj_func(new_pos)
if new_fit < self.fitness[idx]:
self.population[idx] = new_pos
self.fitness[idx] = new_fit
# 检查是否成为头狼
if new_fit < self.leader_fit:
self.leader_idx = idx
self.leader_pos = new_pos.copy()
self.leader_fit = new_fit
群体围攻行为
def siege_phase(self):
step_c = (self.ub - self.lb) / (20 * self.delta) # 攻击步长
for idx in range(self.pop_size):
if idx == self.leader_idx:
continue
# 随机扰动系数
lambda_ = np.random.uniform(-1, 1, self.dim)
# 更新位置
new_pos = self.population[idx] + \
lambda_ * step_c * np.abs(self.leader_pos - self.population[idx])
# 边界处理
new_pos = np.clip(new_pos, self.lb, self.ub)
# 评估新位置
new_fit = self.obj_func(new_pos)
if new_fit < self.fitness[idx]:
self.population[idx] = new_pos
self.fitness[idx] = new_fit
# 检查是否成为头狼
if new_fit < self.leader_fit:
self.leader_idx = idx
self.leader_pos = new_pos.copy()
self.leader_fit = new_fit
2.3 群体更新机制
def population_renew(self):
# 确定淘汰数量
R = np.random.randint(
int(self.pop_size/(2*self.beta)),
int(self.pop_size/self.beta)+1
)
# 淘汰适应度最差的R匹狼
worst_indices = np.argsort(self.fitness)[-R:]
# 生成新个体
self.population[worst_indices] = np.random.uniform(
self.lb, self.ub, (R, self.dim)
)
self.fitness[worst_indices] = [self.obj_func(ind)
for ind in self.population[worst_indices]]
# 更新头狼
new_leader_idx = np.argmin(self.fitness)
if self.fitness[new_leader_idx] < self.leader_fit:
self.leader_idx = new_leader_idx
self.leader_pos = self.population[new_leader_idx].copy()
self.leader_fit = self.fitness[new_leader_idx]
3. 完整算法流程整合
将各阶段组合成完整的优化流程:
def optimize(self):
for iter in range(self.max_iter):
# 记录当前状态
self.history['positions'].append(self.population.copy())
self.history['fitness'].append(self.fitness.copy())
self.history['leader_pos'].append(self.leader_pos.copy())
# 执行优化步骤
self.scout_phase()
self.summon_phase()
self.siege_phase()
self.population_renew()
# 打印进度
if (iter+1) % 10 == 0:
print(f"Iteration {iter+1}/{self.max_iter}, Best Fitness: {self.leader_fit:.4f}")
return self.leader_pos, self.leader_fit
4. 可视化优化过程
创建动态可视化展示狼群优化过程:
def visualize_optimization(self, interval=200):
fig, ax = plt.subplots(figsize=(10, 6))
# 仅展示前两个维度(适用于二维问题)
positions_history = np.array(self.history['positions'])
leader_history = np.array(self.history['leader_pos'])
# 创建散点图
scatter = ax.scatter([], [], c='blue', alpha=0.6, label='Wolf Positions')
leader_scatter = ax.scatter([], [], c='red', s=100, label='Leader')
# 设置图形属性
ax.set_xlim(self.lb[0], self.ub[0])
ax.set_ylim(self.lb[1], self.ub[1])
ax.set_xlabel('X1')
ax.set_ylabel('X2')
ax.set_title('Wolf Pack Algorithm Optimization Process')
ax.legend()
ax.grid(True)
def update(frame):
# 更新散点图数据
current_pos = positions_history[frame]
scatter.set_offsets(current_pos[:, :2])
# 更新头狼位置
current_leader = leader_history[frame]
leader_scatter.set_offsets([current_leader[:2]])
# 添加迭代信息
ax.set_title(f'Wolf Pack Algorithm (Iteration {frame+1}/{self.max_iter})')
return scatter, leader_scatter
ani = FuncAnimation(fig, update, frames=len(positions_history),
interval=interval, blit=True)
plt.close()
return ani
5. 实际应用案例
5.1 测试函数优化
使用经典的Rastrigin函数进行测试:
def rastrigin(x):
"""Rastrigin测试函数"""
A = 10
return A * len(x) + np.sum(x**2 - A * np.cos(2 * np.pi * x))
# 参数设置
dim = 2
lb = np.array([-5.12] * dim)
ub = np.array([5.12] * dim)
# 创建优化器实例
wpa = WolfPackAlgorithm(rastrigin, dim, lb, ub,
pop_size=30, max_iter=100,
alpha=0.8, beta=0.6, delta=0.8)
# 执行优化
best_solution, best_fitness = wpa.optimize()
print(f"Best Solution: {best_solution}")
print(f"Best Fitness: {best_fitness}")
# 可视化
ani = wpa.visualize_optimization()
from IPython.display import HTML
HTML(ani.to_jshtml())
5.2 参数调优技巧
狼群算法的性能很大程度上取决于参数设置。以下是关键参数的调优建议:
-
种群规模 (pop_size)
- 一般设置在20-50之间
- 复杂问题需要更大种群
- 可通过网格搜索确定最优值
-
步长调节因子 (delta)
- 影响算法的探索能力
- 典型值范围:0.5-1.5
- 可随迭代次数动态衰减:
delta = delta_max - (delta_max-delta_min)*(iter/max_iter)
-
探狼比例因子 (alpha)
- 控制探索与开发的平衡
- 推荐范围:0.5-1.0
- 值越大,探狼数量越少
参数组合效果对比:
| 参数组合 | 收敛速度 | 全局搜索能力 | 适用场景 |
|---|---|---|---|
| 大pop_size + 小delta | 慢 | 强 | 多峰复杂问题 |
| 小pop_size + 大delta | 快 | 弱 | 简单凸问题 |
| 动态delta + 适中alpha | 中等 | 平衡 | 大多数问题 |
5.3 工程优化案例
考虑一个实际的机械设计优化问题:弹簧设计优化。目标是最小化弹簧重量,同时满足应力、挠度和几何约束。
问题建模:
def spring_design(x):
"""弹簧设计优化问题"""
d = x[0] # 钢丝直径
D = x[1] # 平均线圈直径
N = x[2] # 活动线圈数
# 约束条件
g1 = 1 - (D**3 * N)/(71785 * d**4)
g2 = (4*D**2 - d*D)/(12566*(D*d**3 - d**4)) + 1/(5108*d**2) - 1
g3 = 1 - (140.45*d)/(D**2*N)
g4 = (D + d)/1.5 - 1
# 惩罚项
penalty = 0
for g in [g1, g2, g3, g4]:
if g > 0:
penalty += 1e6 * g**2
# 目标函数:弹簧重量
return (N + 2) * D * d**2 + penalty
# 参数范围
lb = np.array([0.05, 0.25, 2.0]) # d, D, N的下界
ub = np.array([0.20, 1.30, 15.0]) # d, D, N的上界
# 优化执行
wpa = WolfPackAlgorithm(spring_design, dim=3, lb=lb, ub=ub,
pop_size=40, max_iter=200)
best_design, min_weight = wpa.optimize()
print(f"Optimal Design: d={best_design[0]:.4f}m, D={best_design[1]:.4f}m, N={best_design[2]:.2f}")
print(f"Minimum Weight: {min_weight:.4f} kg")
6. 算法改进与扩展
6.1 自适应步长策略
传统固定步长会影响算法性能,改进方案:
def adaptive_step(current_iter, max_iter):
"""自适应步长调整"""
step_min = 0.1
step_max = 1.0
return step_max - (step_max-step_min)*(current_iter/max_iter)
# 在行为阶段调用
step_a = adaptive_step(iter, self.max_iter) * (self.ub-self.lb)/10
6.2 混合策略改进
结合其他算法的优势:
def hybrid_strategy(self):
# 遗传算法交叉变异
if np.random.rand() < 0.1:
parent1, parent2 = np.random.choice(self.pop_size, 2, replace=False)
crossover_point = np.random.randint(1, self.dim)
child = np.concatenate([
self.population[parent1][:crossover_point],
self.population[parent2][crossover_point:]
])
# 边界变异
if np.random.rand() < 0.2:
mutate_gene = np.random.randint(0, self.dim)
child[mutate_gene] = np.random.uniform(self.lb[mutate_gene], self.ub[mutate_gene])
child_fit = self.obj_func(child)
# 替换最差个体
worst_idx = np.argmax(self.fitness)
if child_fit < self.fitness[worst_idx]:
self.population[worst_idx] = child
self.fitness[worst_idx] = child_fit
6.3 并行化实现
利用多核加速计算:
from multiprocessing import Pool
def parallel_evaluate(self, positions):
"""并行评估适应度"""
with Pool() as pool:
return np.array(pool.map(self.obj_func, positions))
# 替换原评估方式
self.fitness = self.parallel_evaluate(self.population)
实际项目中,根据问题复杂度选择合适的改进策略。对于简单问题,基础算法已足够;复杂多模态问题则需要混合策略。
更多推荐


所有评论(0)