粒子群优化算法详解

粒子群优化(Particle Swarm Optimization, PSO)是一种基于群体智能的优化算法,最初由Jim Kennedy和Russ Eberhart于1995年提出。该算法最初用于模拟鸟群的飞行行为。其基本思想是让一组问题解决实体(粒子)在可能的解空间范围内移动(飞行)。粒子在解空间中的移动具有随机性,但主要由三个因素指导:粒子当前位置、粒子找到的最优位置(个人最优,pBest)以及群体中找到的最优位置(全局最优,gBest)。

粒子群优化算法步骤

以寻找方程(X*X)-(Y*Y)的最小值为例,其中X和Y是0到10之间的整数。算法的执行路径如下:

  1. 用0到10范围内的随机值初始化粒子的X和Y。
  2. 通过用当前X和Y的值评估方程来确定粒子的适应度。
  3. 根据个人最优和全局最优适应度值更新每个粒子的位置。
  4. 要么在预设的适应度值或迭代次数达到一定数量后终止,要么重复步骤2和3。

Rosenbrock函数

Rosenbrock函数常用作优化器的测试。由于它是多维的,并且有很多局部最小值,所以很难找到最小值。在选择适合的函数进行测试时,需要记住优化器具有内置的偏差。在解空间的中心或边缘找到解决方案更容易。

关键优化公式分步解析

以C#语言为例,更新每个维度的速度,例如X和Y。速度是位置变化的量。

double[] vid = vid * W + C1 * Rand(pid - xid) + C2 * Rand(pgd - xid);

其中:

  • vid是当前速度,
  • W、C1、C2是常数。常数的近似值是C1=C2=1.4,W=0.7,
  • Rand和rand是两个随机生成的双精度浮点数,范围在0到1之间,
  • xid是当前位置,
  • pid是个人最优位置,pgd是全局最优位置。

通过将新速度加到当前位置来更新当前位置。

double[] xid = xid + vid;

就是这样。没有变异或生成新粒子。它只是一个半随机的搜索过程,通过群体成员之间的信息交换来指导。

最近的改进

现代算法的变体使用局部最优位置而不是全局最优。这有助于更好地探索解空间,并防止过快地收敛到某个区域最小值。每个粒子都有一个固定的重叠信息集合,从中得出其局部最优位置。粒子以环状结构相互连接。例如,在6粒子群体中,A到F,信息数量设置为2,粒子A将由粒子F和B提供信息。粒子B将由粒子A和C提供信息,粒子F将由粒子E和A提供信息。另一种变体是将信息者分成不同的组,并在一定数量的迭代后没有改变全局最优值时重新组织它们。这种变体使得所有组可以同时在不同的线程上进行优化,并在一定数量的时期没有改进后重新分配。

保持粒子在解空间内

粒子可能会飞出解空间,例如,X可能会获得大于10的值。处理这种情况有几种方法。最简单的就是让它们飞,但不允许逃逸的粒子更新pBest或lBest位置。粒子将在pBest和lBest的影响下被拉回到正确的范围内。

代码实现

Particle类具有以下构造函数。

public Particle(int dimensions, Func errorFunc, ParticleManager particleManager) { this.Dimensions = dimensions; this.particleManager = particleManager; this.errorFunc = errorFunc; this.Initialize(); }

要解决的问题作为Func传递。它返回算法将尝试最小化的误差值。double[]包含函数的所有参数(维度)。ParticleManager类处理数学运算。

优化函数

Optimize函数相当直接。连续静态时期的数量用于在没有改进时提供早期退出。优化器的属性在app.config文件中设置。

public double[] Optimize() { int epoch = 0; int staticEpochs = 0; while (epoch < this.psoAttributes.MaxEpochs && staticEpochs < psoAttributes.MaxStaticEpochs) { bool isErrorImproved = false; foreach (IParticle particle in this.Swarm) { double error = particle.OptimizePosition(); if (error < this.BestGlobalError) { particle.Position.CopyTo(this.BestGlobalPosition, 0); this.BestGlobalError = error; isErrorImproved = true; staticEpochs = 0; } } if (!isErrorImproved) { staticEpochs++; } epoch++; } return this.BestGlobalPosition; }

示例应用

  • Beale函数。解在xd[0]=3 xd[1]=0.5。
  • Rosenbrock函数。解在xd[0]=1 xd[1]=1。
  • Sphere函数。解在xd[0]=0 xd[1]=0 xd[2]=0 xd[3]=0。
  • Griewank函数。解在xd[0]=0 xd[1]=0 xd[2]=0 xd[3]=0。
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485