如何正确为灰狼优化器(GWO)模型制作动画并显示背景等高线图
灰狼优化器动画等高线不显示问题修复
我实现了一种简单的基于种群的随机优化方法——灰狼优化器(Grey Wolf Optimizer),在使用celluloid库的Camera组件捕获每次迭代的Matplotlib绘图时遇到了问题:针对目标函数$f(x,y) = x^2 + y^2$运行GWO算法时,仅能观察到候选解向最小值收敛的过程,等高线图未正常显示。
复现代码
GWO算法实现
%matplotlib notebook import matplotlib.pyplot as plt import numpy as np from celluloid import Camera import ffmpeg import pillow # X : 初始种群的位置向量 # n : 初始种群规模 def gwo(f,max_iterations,LB,UB): fig = plt.figure() camera = Camera(fig) def random_population_uniform(m,a,b): dims = len(a) x = [list(a + np.multiply(np.random.rand(dims),b - a)) for i in range(m)] return np.array(x) def search_agent_fitness(fitness): alpha = 0 if fitness[1] < fitness[alpha]: alpha, beta = 1, alpha else: beta = 1 if fitness[2] > fitness[alpha] and fitness[2] < fitness[beta]: beta, delta = 2, beta elif fitness[2] < fitness[alpha]: alpha,beta,delta = 2,alpha,beta else: delta = 2 for i in range(3,len(fitness)): if fitness[i] <= fitness[alpha]: alpha, beta,delta = i, alpha, beta elif fitness[i] > fitness[alpha] and fitness[i] <= fitness[beta]: beta,delta = i,beta elif fitness[i] > fitness[beta] and fitness[i] <= fitness[delta]: delta = i return alpha, beta, delta def plot_search_agent_positions(f,X,alpha,beta,delta,a,b): # 绘制搜索个体的位置 x = X[:,0] y = X[:,1] plt.scatter(x,y,c='gray',zorder=1) plt.scatter(x[alpha],y[alpha],c='red',zorder=1) plt.scatter(x[beta],y[beta],c='blue',zorder=1) plt.scatter(x[delta],y[delta],c='green',zorder=1) camera.snap() # 初始化搜索个体位置 X = random_population_uniform(50,np.array(LB),np.array(UB)) n = len(X) l = 1 # 绘制初始背景等高线 x = np.linspace(LB[0],LB[1],1000) y = np.linspace(LB[0],UB[1],1000) X1,X2 = np.meshgrid(x,y) Z = f(X1,X2) cont = plt.contour(X1,X2,Z,20,linewidths=0.75) while (l < max_iterations): # 提取初始种群的x,y坐标 x = X[:,0] y = X[:,1] # 计算每个搜索个体的目标函数值 fitness = list(map(f,x,y)) # 更新alpha, beta, delta alpha,beta,delta = search_agent_fitness(fitness) # 绘制搜索个体位置 plot_search_agent_positions(f,X,alpha,beta,delta,LB,UB) # a从2线性衰减到0 a = 2 - l *(2 / max_iterations) # 更新所有搜索个体的位置(包括omega个体) for i in range(n): x_prey = X[alpha] r1 = np.random.rand(2) # r1是[0,1]区间的随机向量 r2 = np.random.rand(2) # r2是[0,1]区间的随机向量 A1 = 2*a*r1 - a C1 = 2*r2 D_alpha = np.abs(C1 * x_prey - X[i]) X_1 = x_prey - A1*D_alpha x_prey = X[beta] r1 = np.random.rand(2) r2 = np.random.rand(2) A2 = 2*a*r1 - a C2 = 2*r2 D_beta = np.abs(C2 * x_prey - X[i]) X_2 = x_prey - A2*D_beta x_prey = X[delta] r1 = np.random.rand(2) r2 = np.random.rand(2) A3 = 2*a*r1 - a C3 = 2*r2 D_delta = np.abs(C3 * x_prey - X[i]) X_3 = x_prey - A3*D_delta X[i] = (X_1 + X_2 + X_3)/3 l = l + 1 return X[alpha],camera
函数调用
# 定义目标函数 def f(x,y): return x**2 + y**2 minimizer,camera = gwo(f,7,[-10,-10],[10,10]) animation = camera.animate(interval = 1000, repeat = True, repeat_delay = 500)
问题原因与修复方案
核心问题
原代码中生成网格数据时存在笔误:x轴的取值范围写为LB[0]到LB[1],而传入的LB是[-10,-10],导致x轴所有值都是-10,根本无法生成有效的二维等高线,这是等高线不显示的主要原因。
修复步骤
- 修正网格生成逻辑,将x轴的取值范围改为
LB[0]到UB[0],y轴改为LB[1]到UB[1],确保生成正确的二维网格:
# 修正后的网格生成代码 x = np.linspace(LB[0], UB[0], 1000) y = np.linspace(LB[1], UB[1], 1000) X1, X2 = np.meshgrid(x, y) Z = f(X1, X2)
- 给等高线设置低于散点的zorder,避免等高线盖住散点:
cont = plt.contour(X1, X2, Z, 20, linewidths=0.75, zorder=0)
- 若需要确保每帧都能捕获到等高线,可将等高线绘制逻辑移动到
plot_search_agent_positions函数的最开头,或者在绘制完等高线后、进入迭代循环前先调用一次camera.snap()。
修改后运行代码,即可看到等高线作为背景正常显示,和候选解的收敛过程同步出现在动画中。
内容的提问来源于stack exchange,提问作者Quasar
相关产品推荐
相关产品推荐

