利用粒子集群算法,求解y=x1^2+x2^2+x3^2的最小值,迭代次数2000.
package com.song.test.pos;
import java.util.Random;
/**
* 此例子用来理解粒子集群算法。
* 注意:在编写例子过程中,曾遇到过这样一个问题:在给数组赋值时,某些数据会产生覆盖、脏读等不可预期的错误。仔细调试,发现可能是因为在给数组赋值时,直接
* 使用了一个数组给另外一个数组赋值。这种方式是不正确的,切记!!!
* */
public class Pos {
private static int M=200; //迭代次数
private static int N=50; //粒子数
private static int D=3; //粒子维数
private static double[][] xPos = new double[N][D]; //存储各粒子的位置信息
private static double[][] yPos = new double[N][D]; //存储各粒子的位置信息副本(局部最优解)
private static double[][] xVel = new double[N][D]; //存储各粒子的速度信息
private static double[] gBest = new double[D]; //全局最优解
private static double[] expense = new double[N]; //存储各粒子代价函数值
//相关参数
private static double w = 0.6;
private static double c1 = 2.0;
private static double c2 = 2.0;
private Random random = new Random();
public static void main(String args[])
{
Pos pos=new Pos();
pos.Initialize();
pos.Search();
}
//初始化
public void Initialize()
{
//初始化位置和速度
for(int i=0;i<N;i++){
for(int j=0;j<D;j++){
xPos[i][j]=random.nextGaussian();
xVel[i][j]=random.nextGaussian();
}
}
//计算每个粒子的代价函数值,并初始化局部最优解和全局最优解
for(int i=0;i<N;i++){
expense[i] = function(xPos[i]);
for(int d=0;d<D;d++){
yPos[i][d]=xPos[i][d];
}
}
for(int d=0;d<D;d++){
gBest[d] = xPos[N-1][d];
}
for(int i=0;i<N-1;i++){
if(function(gBest)>=function(xPos[i])){
for(int d=0;d<D;d++){
gBest[d] = xPos[i][d];
}
}
}
System.out.println("初始化完毕!"+function(gBest));
}
//算法主体
public void Search()
{
for(int m=0;m<M;m++){
for(int n=0;n<N;n++)
{
//计算出粒子的速度和位置
for(int d=0;d<D;d++){
xVel[n][d] = w*xVel[n][d] + c1*random.nextDouble()*(yPos[n][d]-xPos[n][d])+c2*random.nextDouble()*(gBest[d]-xPos[n][d]);
System.out.print(xPos[n][d]+" ");
xPos[n][d] += xVel[n][d];
}
//将粒子新位置的代价与粒子原本的代价进行比较,如果新的代价更小,则用此时新的位置更新粒子局部最优解,并更新此粒子代价
if(function(xPos[n])<expense[n]){
expense[n] = function(xPos[n]);
for(int d=0;d<D;d++){
yPos[n][d]=xPos[n][d];
}
}
//将此粒子的代价(是否更新过取决于上一步)与全局最优解的代价进行比较。如果此时的全局最优解代价更大,则将此粒子的局部最优解用来更新全局最优解
if(expense[n]<function(gBest)){
for(int d=0;d<D;d++){
gBest[d] = yPos[n][d];
}
}
}
System.out.println(function(gBest)+"\r\n");
}
}
public double function(double[] temp)
{
double y = temp[0] * temp[0] + temp[1] * temp[1] + temp[2] * temp[2];
return y;
}
}