# 粒子群优化

## 粒子

``````public class Particle
{
public double[] position;
public double fitness;
public double[] velocity;

public double[] bestPosition;
public double bestFitness;

public Particle(double[] position, double fitness,
double[] velocity, double[] bestPosition, double bestFitness)
{
this.position = new double[position.Length];
position.CopyTo(this.position, 0);
this.fitness = fitness;
this.velocity = new double[velocity.Length];
velocity.CopyTo(this.velocity, 0);
this.bestPosition = new double[bestPosition.Length];
bestPosition.CopyTo(this.bestPosition, 0);
this.bestFitness = bestFitness;
}

public override string ToString()
{
string s = "";
s += "==========================\n";
s += "Position: ";
for (int i = 0; i < this.position.Length; ++i)
s += this.position[i].ToString("F2") + " ";
s += "\n";
s += "Fitness = " + this.fitness.ToString("F4") + "\n";
s += "Velocity: ";
for (int i = 0; i < this.velocity.Length; ++i)
s += this.velocity[i].ToString("F2") + " ";
s += "\n";
s += "Best Position: ";
for (int i = 0; i < this.bestPosition.Length; ++i)
s += this.bestPosition[i].ToString("F2") + " ";
s += "\n";
s += "Best Fitness = " + this.bestFitness.ToString("F4") + "\n";
s += "==========================\n";
return s;
}
} // class Particle
``````

## PSO 算法

v(t+1) = (w * v(t)) + (c1 * r1 * (p(t) – x(t)) + (c2 * r2 * (g(t) – x(t))

x(t+1) = x(t) + v(t+1)

v(t + 1) = (0.7 * {-1.0、-1.5}） +

(1.4 * 0.5 * {2.5, 3.6} - {3.0, 4.0}) +

(1.4 * 0.6 * {2.3, 3.4} – {3.0, 4.0})

= {-0.70, -1.05} + {-0.35, -0.28} + {-0.59, -0.50}

= {-1.64, -1.83}

x(t + 1) = {3.0、 4.0} + {-1.64、-1.83}

= {1.36, 2.17}

## 实施 PSO 算法

``````using System;
namespace ParticleSwarmOptimization
{
class Program
{
static Random ran = null;
static void Main(string[] args)
{
try
{
Console.WriteLine("\nBegin PSO demo\n");
ran = new Random(0);

int numberParticles = 10;
int numberIterations = 1000;
int iteration = 0;
int Dim = 2; // dimensions
double minX = -100.0;
double maxX = 100.0;

Particle[] swarm = new Particle[numberParticles];
double[] bestGlobalPosition = new double[Dim];
double bestGlobalFitness = double.MaxValue;

double minV = -1.0 * maxX;
double maxV = maxX;

// Initialize all Particle objects

double w = 0.729; // inertia weight
double c1 = 1.49445; // cognitive weight
double c2 = 1.49445; // social weight
double r1, r2; // randomizations

// Main processing loop

// Display results
Console.WriteLine("\nEnd PSO demo\n");
}
catch (Exception ex)
{
Console.WriteLine("Fatal error: " + ex.Message);
}
} // Main()

static double ObjectiveFunction(double[] x)
{
return 3.0 + (x[0] * x[0]) + (x[1] * x[1]);
}

} // class Program

public class Particle
{
// Definition here
}

} // ns
``````

``````int numberParticles = 10;
int numberIterations = 1000;
int iteration = 0;
int Dim = 2;
double minX = -100.0;
double maxX = 100.0;
``````

``````Particle[] swarm = new Particle[numberParticles];
double[] bestGlobalPosition = new double[Dim];
double bestGlobalFitness = double.MaxValue;
double minV = -1.0 * maxX;
double maxV = maxX;
``````

``````for (int i = 0; i < swarm.Length; ++i)
{
double[] randomPosition = new double[Dim];
for (int j = 0; j < randomPosition.Length; ++j) {
double lo = minX;
double hi = maxX;
randomPosition[j] = (hi - lo) * ran.NextDouble() + lo;
}
...
``````

``````double fitness = ObjectiveFunction(randomPosition);
double[] randomVelocity = new double[Dim];
for (int j = 0; j < randomVelocity.Length; ++j) {
double lo = -1.0 * Math.Abs(maxX - minX);
double hi = Math.Abs(maxX - minX);
randomVelocity[j] = (hi - lo) * ran.NextDouble() + lo;
}
swarm[i] = new Particle(randomPosition, fitness, randomVelocity,
randomPosition, fitness);
...
``````

``````...
if (swarm[i].fitness < bestGlobalFitness) {
bestGlobalFitness = swarm[i].fitness;
swarm[i].position.CopyTo(bestGlobalPosition, 0);
}
} // End initialization loop
``````

``````double w = 0.729; // inertia weight
double c1 = 1.49445; // cognitive weight
double c2 = 1.49445; // social weight
double r1, r2; // randomizers
``````

W，惯性粗细值设置为 0.729。 此值被建议的调查对一组准则最小化问题的各种 PSO 参数值的影响研究论文。 而不是 w 的 w 单个的常量值，另一种方法是 w 的不同值。 例如，如果您 PSO 算法是设置为迭代 10000 次，可以最初设置 w 到 0.90，逐渐减少 0.40 通过减少 w w 0.10 每 2000 次迭代后。 动态 w 的思想是早期算法中您想要浏览位置，较大的更改，但希望以后更小的粒子运动。 我设置 c1 和 c2、 认知和社会重量，值为 1.49445。 同样，此值被推荐一次调查研究。 如果您设置的值大于 c2 的值的 c1，比蜂群的全球已知最佳位置，反之亦然粒子的已知最佳位置上放置更多的重量。 随机变量 r1 和 r2 随机组件添加到 PSO 算法，并帮助防止算法停留在非最佳的本地最小值或最大解决方案。

``````for (int i = 0; i < swarm.Length; ++i)
{
Particle currP= swarm[i];

for (int j = 0; j < currP.velocity.Length; ++j)
{
r1 = ran.NextDouble();
r2 = ran.NextDouble();

newVelocity[j] = (w * currP.velocity[j]) +
(c1 * r1* (currP.bestPosition[j] - currP.position[j])) +
(c2 * r2 * (bestGlobalPosition[j] - currP.position[j]));
...
``````

``````if (newVelocity[j] < minV)
newVelocity[j] = minV;
else if (newVelocity[j] > maxV)
newVelocity[j] = maxV;
} // each j
newVelocity.CopyTo(currP.velocity, 0);
...
``````

``````for (int j = 0; j < currP.position.Length; ++j)
{
newPosition[j] = currP.position[j] + newVelocity[j];
if (newPosition[j] < minX)
newPosition[j] = minX;
else if (newPosition[j] > maxX)
newPosition[j] = maxX;
}
newPosition.CopyTo(currP.position, 0);
...
``````

``````newFitness = ObjectiveFunction(newPosition);
currP.fitness = newFitness;

if (newFitness < currP.bestFitness) {
newPosition.CopyTo(currP.bestPosition, 0);
currP.bestFitness = newFitness;
}
if (newFitness < bestGlobalFitness) {
newPosition.CopyTo(bestGlobalPosition, 0);
bestGlobalFitness = newFitness;
}

} // each Particle
} // main PSO loop
...
``````

``````Console.WriteLine("\nProcessing complete");
Console.Write("Final best fitness = ");
Console.WriteLine(bestGlobalFitness.ToString("F4"));
Console.WriteLine("Best position/solution:");
for (int i = 0; i < bestGlobalPosition.Length; ++i){
Console.Write("x" + i + " = " );
Console.WriteLine(bestGlobalPosition[i].ToString("F4") + " ");
}
Console.WriteLine("");
Console.WriteLine("\nEnd PSO demonstration\n");
}
catch (Exception ex)
{
Console.WriteLine("Fatal error: " + ex.Message);
}
} // Main()
``````

## 扩展和修改

PSO 是基于自然系统的行为的几种 AI 技术之一。 可能是最接近 PSO 算法的技术是遗传算法 (气体)。 这两种技术非常适合于数字难以解决的问题。 天然气被广泛研究数十年。 天然气 Pso 的优点是 PSO 算法实现天然气比简单得多。 它并不清楚这次 Pso 是否比天然气更多或更少有效或大致等于它们。

Dr. James McCaffrey 适用于伏信息科学 Inc.，他管理着软件工程师使用 Microsoft 雷蒙德，Wash.，在校园内的技术培训。 他参与过多项 Microsoft 产品的研发工作，包括 Internet Explorer 和 MSN Search。 Dr. McCaffrey 是作者"。NET 测试自动化食谱"（Apress，2006年），并可以通过jammc@microsoft.com