PSO算法在C#中的实现,代码如下:
using System;
namespace PSO_algorithm
{
class Program
{
//粒子群算法容易陷入局部最优,算法容易出现早熟的情况
//////////////////////////
// //
// 指定相关的参数 //
// //
/////////////////////////
private static int dimention = 2;//指定维度
private static int particle_number = 40;//指定粒子数量
private static int low = 1;
private static int high = 40;
public static int generations = 10000;//指定迭代的代数
private static double v_max = 30;//指定最大速度
private static double c1 = 2;//指定信任度1
private static double c2 = 2;//指定信任度2
private static double w = 0.6;//指定惯性因子
//////////////////////////
// //
// 定义粒子的属性 //
// //
/////////////////////////
//某个粒子
public static double[,] particle = new double[particle_number, dimention];
//粒子的局部最优位置
private double[,] particle_local_best_position = new double[particle_number, dimention];
//粒子的局部最优适应度
private double[] particle_local_best_fitness = new double[particle_number];
//粒子的全局最优位置,一个一维的数组,两个元素
public double[] particle_global_best_position = new double[dimention];
//粒子的全局最优适应度,是一个值
public double particle_global_fitness;
//某个粒子当前的速度
private double[,] particle_current_v = new double[particle_number, dimention];
//某个粒子当前的适应度
private double[] particle_current_fit = new double[particle_number];
/// <summary>
/// 适应度计算函数
/// </summary>
/// <param name="b"></param>
/// <param name="h"></param>
/// <returns></returns>
public double fitness(double b,double h)//适应度计算
{
int i, A, B;
double f = 0;
for (i = 0; i < dimention; i++)
{
if (1680000/(30*h-0.25*h*h)<=7200)
{
A = 0;
}
else
{
A = 30;
}
if (16800/(5400*b)<=120)
{
B = 0;
}
else
{
B = 30;
}
f = 90 * (b+A) * (h+B);
}
return f;
}
public void initial()//粒子初始化
{
int i, j;
for (i = 0; i < particle_number; i++)
{
Random rand = new Random(Guid.NewGuid().GetHashCode());
particle[i,0] = low + (high - low) * 1.0 * rand.NextDouble();//初始化群体
particle_local_best_position[i,0] = particle[i,0];//将当前最优结果写入局部最优
particle[i,1] = low + (high - low) * 1.0 * rand.NextDouble();//初始化群体
particle_local_best_position[i,1] = particle[i,1];//将当前最优结果写入局部最优
//初始化粒子的速度
particle_current_v[i,0] = -v_max + 2 * v_max * 1.0 * rand.NextDouble();
particle_current_v[i,1] = -v_max + 2 * v_max * 1.0 * rand.NextDouble();
}
//计算每个粒子的适应度
for (i = 0; i < particle_number; i++)
{
particle_current_fit[i] = fitness(particle[i,0], particle[i,1]);
particle_local_best_fitness[i] = particle_current_fit[i];
}
//找出全局最优的适应度
particle_global_fitness = particle_local_best_fitness[0];
j = 0;
for (i = 0; i < particle_number; i++)
{
if (particle_local_best_fitness[i] < particle_global_fitness)
{
particle_global_fitness = particle_local_best_fitness[i];
j = i;
}
}
//更新全局最优向量
for (i = 0; i < dimention; i++)
{
particle_global_best_position[i] = particle_local_best_position[j,i];
}
Console.WriteLine("初始化粒子完成!");
Console.WriteLine("开始进行迭代寻优...");
}
/// <summary>
/// 更新粒子位置
/// </summary>
public void renew_particle()//每次迭代后需要重新更新粒子所在的位置
{
int i, j;
for (i = 0; i < particle_number; i++)
{
for (j = 0; j < dimention; j++)
{
particle[i, j] = particle[i, j] + particle_current_v[i,j];
if (particle[i, j]>high)
{
particle[i, j] = high;
}
if (particle[i, j] < low)
{
particle[i, j] = low;
}
}
}
}
/// <summary>
/// 更新局部和全局的适应度和位置
/// </summary>
public void renew_var()
{
int i, j;
for (i = 0; i < particle_number; i++)
{
particle_current_fit[i] = fitness(particle[i,0],particle[i,1]);//计算个体的适应度
if (particle_current_fit[i]<particle_local_best_fitness[i])
{
particle_local_best_fitness[i] = particle_current_fit[i];//更新局部最优适应度
for ( j = 0; j < dimention; j++)
{
particle_local_best_position[i,j] = particle[i,j];//更新局部最优位置
}
}
}
for (i = 0,j=-1; i < particle_number; i++)
{
if (particle_local_best_fitness[i]<particle_global_fitness)
{
particle_global_fitness = particle_local_best_fitness[i];//更新全局最优适应度
j = i;
}
}
if (j!=-1)//如果条件满足,说明前面进行了全局最优适应度的更新,因此,全局最优位置也需要进行更新
{
for (i = 0; i < dimention; i++)
{
particle_global_best_position[i] = particle_local_best_position[j,i];//更新全局最优位置
}
}
for (i = 0; i < particle_number; i++)//更新个体速度,为下一次迭代做准备
{
for (j = 0; j < dimention; j++)
{
Random rand = new Random(Guid.NewGuid().GetHashCode());
particle_current_v[i,j] = particle_current_v[i, j] * w +
c1 * 1.0 * rand.NextDouble() * (particle_local_best_position[i, j] - particle[i, j]) +
c2 * 1.0 * rand.NextDouble() * (particle_global_best_position[j] - particle[i, j]);
}
}
}
/// <summary>
/// 主函数
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Program pso = new Program();
int i = 0;
pso.initial();
while (i < Program.generations)
{
pso.renew_particle();
pso.renew_var();
i++;
}
Console.WriteLine("最小体积为:{0}", pso.particle_global_fitness);
Console.ReadKey();
}
}
}