You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确为灰狼优化器(GWO)模型制作动画并显示背景等高线图

灰狼优化器动画等高线不显示问题修复

我实现了一种简单的基于种群的随机优化方法——灰狼优化器(Grey Wolf Optimizer),在使用celluloid库的Camera组件捕获每次迭代的Matplotlib绘图时遇到了问题:针对目标函数$f(x,y) = x^2 + y^2$运行GWO算法时,仅能观察到候选解向最小值收敛的过程,等高线图未正常显示。
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,根本无法生成有效的二维等高线,这是等高线不显示的主要原因。

修复步骤

  1. 修正网格生成逻辑,将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)
  1. 给等高线设置低于散点的zorder,避免等高线盖住散点:
cont = plt.contour(X1, X2, Z, 20, linewidths=0.75, zorder=0)
  1. 若需要确保每帧都能捕获到等高线,可将等高线绘制逻辑移动到plot_search_agent_positions函数的最开头,或者在绘制完等高线后、进入迭代循环前先调用一次camera.snap()。

修改后运行代码,即可看到等高线作为背景正常显示,和候选解的收敛过程同步出现在动画中。


内容的提问来源于stack exchange,提问作者Quasar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 21:24:03