资讯动态

scikit-opt 粒子群算法(PSO)收敛过程动画可视化实战

发布时间:2026/9/17 19:40:22 来源:尧图企业网站定制
scikit-opt 粒子群算法PSO收敛过程动画可视化实战【免费下载链接】scikit-optGenetic Algorithm, Particle Swarm Optimization, Simulated Annealing, Ant Colony Optimization Algorithm,Immune Algorithm, Artificial Fish Swarm Algorithm, Differential Evolution and TSP(Traveling salesman)项目地址: https://gitcode.com/GitHub_Trending/sci/scikit-opt导读本文基于 scikit-opt 官方文档 docs/en/more_pso.md 与配套示例 examples/demo_pso_ani.py完整讲解如何用 scikit-opt 的 PSO 求解器求解带非线性约束的二维优化问题并将粒子群的寻优过程逐帧渲染为动态图GIF。读完本文你将掌握PSO的record_mode轨迹记录机制、record_value数据结构的含义以及基于 matplotlibFuncAnimation的动画绘制与 GIF 导出全流程。一、问题背景二维 Ackley 函数与非线性约束示例要最小化的目标函数是一个二维 Ackley 函数def demo_func(x): x1, x2 x return -20 * np.exp(-0.2 * np.sqrt(0.5 * (x1 ** 2 x2 ** 2))) - np.exp( 0.5 * (np.cos(2 * np.pi * x1) np.cos(2 * np.pi * x2))) 20 np.eAckley 函数是启发式算法领域常用的基准测试函数其特点是存在大量局部极小值强烈的周期性震荡而全局最小值位于(0, 0)、函数值为 0代入可得-20 - e 20 e 0。这样的地形非常考验算法在全局探索与局部开发之间的平衡也正因如此用动画观察粒子在不同迭代阶段如何翻越局部低谷、逐步收敛到全局最优具有很好的教学价值。与此同时示例还叠加了一个非线性不等式约束要求解必须落在以(1, 0)为圆心、半径 0.5 的圆内constraint_ueq ( lambda x: (x[0] - 1) ** 2 (x[1] - 0) ** 2 - 0.5 ** 2 , )即(x[0] - 1) ** 2 x[1] ** 2 - 0.5 ** 2 0。注意 scikit-opt 约定constraint_ueq中的每个约束函数返回大于 0 时视为违反约束对应 sko/PSO.py 中check_constraint的判断逻辑if constraint_func(x) 0: return False。后续动画里那条红色圆周正是约束边界的可视化。二、Step 1配置 PSO 并开启轨迹记录先构造 PSO 求解器并运行迭代完整代码对应 examples/demo_pso_ani.py 第 121 行如下import numpy as np from sko.PSO import PSO def demo_func(x): x1, x2 x return -20 * np.exp(-0.2 * np.sqrt(0.5 * (x1 ** 2 x2 ** 2))) - np.exp( 0.5 * (np.cos(2 * np.pi * x1) np.cos(2 * np.pi * x2))) 20 np.e constraint_ueq ( lambda x: (x[0] - 1) ** 2 (x[1] - 0) ** 2 - 0.5 ** 2 , ) max_iter 50 pso PSO(funcdemo_func, n_dim2, pop40, max_itermax_iter, lb[-2, -2], ub[2, 2] , constraint_ueqconstraint_ueq) pso.record_mode True pso.run() print(best_x is , pso.gbest_x, best_y is, pso.gbest_y)2.1 关键参数说明对照 sko/PSO.py 中PSO.__init__的签名func, n_dimNone, pop40, max_iter150, lb-1e5, ub1e5, w0.8, c10.5, c20.5, constraint_eqtuple(), constraint_ueqtuple(), verboseFalse, dimNone, n_processes0本示例涉及的参数含义如下参数示例取值默认值作用funcdemo_func必填待最小化的目标函数入参是一个解向量xn_dim2必填决策变量维数即func的参数个数旧版本参数名dim仍兼容pop4040粒子群规模即粒子数量与 GA 的size_pop语义一致max_iter50150最大迭代代数lb/ub[-2, -2]/[2, 2]-1e5/1e5每个变量的下界 / 上界源码要求len(lb) len(ub) n_dim且ub lbconstraint_ueq圆内约束元组tuple()非线性不等式约束可传多个 lambdaw未指定0.8惯性权重控制粒子保持原速度的程度c1/c2未指定0.5/0.5认知系数个人最优牵引与社会系数全局最优牵引2.2 核心record_mode与record_value要生成动画关键开关是这一行pso.record_mode True在 sko/PSO.py#L118-L120 中PSO默认以字典形式维护记录结构self.record_mode False self.record_value {X: [], V: [], Y: []}而真正的记录发生在每次迭代的recorder()方法里sko/PSO.py#L169-L174def recorder(self): if not self.record_mode: return self.record_value[X].append(self.X) self.record_value[V].append(self.V) self.record_value[Y].append(self.Y)也就是说开启record_mode后每一轮迭代都会把当前的粒子位置矩阵X、速度矩阵V和适应度Y追加进对应列表。结合run()的迭代顺序sko/PSO.py#L185-L191update_V → recorder → update_X → cal_y → update_pbest → update_gbest可以明确第i个位置的X_list[i]就是第i轮迭代开始时的粒子位置V_list[i]则是本轮粒子将施加的速度。动画正是利用这两者的线性插值来制造粒子连续飞行的视觉效果。2.3 底层迭代机理位置与速度更新从源码可以印证 PSO 的标准更新公式sko/PSO.py#L130-L139def update_V(self): r1 np.random.rand(self.pop, self.n_dim) r2 np.random.rand(self.pop, self.n_dim) self.V self.w * self.V \ self.cp * r1 * (self.pbest_x - self.X) \ self.cg * r2 * (self.gbest_x - self.X) def update_X(self): self.X self.X self.V self.X np.clip(self.X, self.lb, self.ub)即速度由惯性项 个体认知项 社会学习项三部分构成位置在速度累加后还会被np.clip限制在[lb, ub]区间内这也是为什么示例把边界设为[-2, 2]以配合绘制范围。约束处理则在update_pbestsko/PSO.py#L146-L157中完成只有满足所有constraint_ueq的更优位置才允许成为个人最优从而引导粒子只在可行域内搜索。运行结束后pso.gbest_x/pso.gbest_y保存历史全局最优解本示例理论上应接近(0, 0)pso.gbest_y_hist保存每轮最优适应度可用于像 examples/demo_pso.py 那样绘制收敛曲线plt.plot(pso.gbest_y_hist)。三、Step 2用 matplotlib 绘制粒子飞行动画3.1 取出记录数据record_value pso.record_value X_list, V_list record_value[X], record_value[V]X_list长度等于max_iter 50每个元素是形状(40, 2)的粒子位置矩阵V_list对应每个粒子在当前迭代的位移速度。动画绘制部分完整代码对应 examples/demo_pso_ani.py 第 2369 行如下import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation record_value pso.record_value X_list, V_list record_value[X], record_value[V] fig, ax plt.subplots(1, 1) ax.set_title(title, loccenter) line ax.plot([], [], b.) # 蓝色的散点对象动画中反复更新其数据 X_grid, Y_grid np.meshgrid(np.linspace(-2.0, 2.0, 40), np.linspace(-2.0, 2.0, 40)) Z_grid demo_func((X_grid, Y_grid)) ax.contour(X_grid, Y_grid, Z_grid, 30) # 30 层等值线勾勒出 Ackley 函数的地形 ax.set_xlim(-2, 2) ax.set_ylim(-2, 2) t np.linspace(0, 2 * np.pi, 40) ax.plot(0.5 * np.cos(t) 1, 0.5 * np.sin(t), colorr) # 红色圆周 约束边界 plt.ion() p plt.show() def update_scatter(frame): i, j frame // 10, frame % 10 ax.set_title(iter str(i)) X_tmp X_list[i] V_list[i] * j / 10.0 plt.setp(line, xdata, X_tmp[:, 0], ydata, X_tmp[:, 1]) return line ani FuncAnimation(fig, update_scatter, blitTrue, interval25, framesmax_iter * 10) plt.show() ani.save(pso.gif, writerpillow)3.2 动画逐帧原理拆解静态背景先用np.meshgrid在[-2, 2]²上生成 40×40 的网格并计算函数值通过ax.contour(..., 30)画出 30 层等高线作为 Ackley 函数的地形底图再用参数方程0.5*cos(t)1, 0.5*sin(t)画出约束圆。帧数与插值FuncAnimation的framesmax_iter * 10表示总共 50×10 500 帧。在update_scatter中frame // 10得到当前所属的迭代序号iframe % 10得到该迭代内的子帧号j09。粒子位置用线性插值模拟连续运动j 0时X_tmp X_list[i]迭代 i 的初始位置j 10时X_tmp X_list[i] V_list[i]恰好等于迭代 i1 的初始位置中间帧即粒子沿本轮速度方向的平滑过渡。plt.setp更新散点line是初始为空数据的b.蓝色散点对象每帧用plt.setp重设xdata/ydatablitTrue只重绘变化区域以提高帧率interval25表示每帧间隔 25 毫秒约 40 FPS。GIF 导出ani.save(pso.gif, writerpillow)借助 Pillow 将动画逐帧写入 GIF 文件方便嵌入网页、文档或汇报材料中。3.3 运行注意事项依赖库动画与目标函数计算需要numpy、matplotlibGIF 导出还需要pillowwriterpillow路径下必装。基础依赖可参见 requirements.txt 与 sko/requirements.txt。交互式显示脚本中先调用了plt.ion()与一次plt.show()用于交互窗口预览随后FuncAnimation会驱动窗口播放动画若在无图形界面的服务器环境运行可跳过plt.show()直接调用ani.save(pso.gif, ...)导出文件。目标函数写法PSO内部通过 sko/tools.py 的func_transformer把这种解向量作单一入参的函数包装为按种群批量计算的形态因此demo_func直接按x1, x2 x解包即可无需手动写循环如需进一步提升大规模计算性能可参考 examples/example_function_modes.py 使用set_run_mode切换到 vectorization / multithreading / multiprocessing / cached 模式。四、进阶把动画技术迁移到其他场景record_mode record_value FuncAnimation这套模式不仅适用于 PSO也可以迁移到 scikit-opt 的其他求解器PSO_TSP在 sko/PSO.py#L313-L317 中PSO_TSP同样实现了recorder()但其record_value只记录X与Y速度概念被路径重组算子取代适合观察旅行商问题的路径演化。GA / SA 等各算法的run()都会维护gbest_y_hist/best_y_history之类的历史最优序列可复用动画思路绘制最优值随迭代变化的动态曲线。自定义记录项由于record_value只是PSO实例上的普通字典sko/PSO.py#L119-L120你完全可以在run()之后自行补充记录其他中间量如约束违反程度、种群多样性指标扩展出更丰富的可视化分析。五、总结动画可视化的三步套路配置PSO→ 开启pso.record_mode True并run()→ 读取record_value的X/V用FuncAnimation逐帧渲染。record_value[X]、record_value[V]分别按迭代保存粒子位置与速度矩阵二者线性插值即可还原粒子在迭代间的连续飞行轨迹。示例以二维 Ackley 函数 圆形不等式约束为载体等高线底图 红色约束圆 蓝色粒子散点的组合能直观展示约束对搜索空间的影响以及算法收敛到全局最优(0, 0)的过程。完整可运行代码见 examples/demo_pso_ani.pyPSO 参数与底层更新逻辑可对照 sko/PSO.pyPSO 的基础用法含收敛曲线绘制见 docs/en/README.md 的 3. PSO 一节。【免费下载链接】scikit-optGenetic Algorithm, Particle Swarm Optimization, Simulated Annealing, Ant Colony Optimization Algorithm,Immune Algorithm, Artificial Fish Swarm Algorithm, Differential Evolution and TSP(Traveling salesman)项目地址: https://gitcode.com/GitHub_Trending/sci/scikit-opt创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价