说明:算法为了演示功能,所以没有优化,没有异常处理等,仅作演示用。
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.util.Random;
/**
*粒子类
* 求解函数 f(x)=x1^2+(x2-x3)^2 的最大值
* @author FashionXu
*/
public class Particle {
public double[] pos;//粒子的位置,求解问题多少维,则此数组为多少维
public double[] v;//粒子的速度,维数同位置
public double fitness;//粒子的适应度
public double[] pbest;//粒子的历史最好位置
public static double[] gbest;//所有粒子找到的最好位置
public static Random rnd;
public static int dims;
public static double w;
public static double c1;
public static double c2;
double pbest_fitness;//历史最优解
/**
* 返回low—uper之间的数
* @param low 下限
* @param uper 上限
* @return 返回low—uper之间的数
*/
double rand(double low, double uper) {
rnd = new Random();
return rnd.nextDouble() * (uper - low) + low;
}
/**
* 初始化粒子
* @param dim 表示粒子的维数
*/
public void initial(int dim) {
pos = new double[dim];
v = new double[dim];
pbest = new double[dim];
fitness = -1e6;
pbest_fitness = -1e6;
dims = dim;
for (int i = 0; i < dim; ++i) {
pos[i] = rand(-10, 10);
pbest[i] = pos[i];
v[i] = rand(-20, 20);
}
}
/**
* 评估函数值,同时记录历史最优位置
*/
public void evaluate() {
fitness = pos[0] * pos[0] + (pos[1] - pos[2]) * (pos[1] - pos[2]);
if (fitness > pbest_fitness) {
for (int i = 0; i < dims; ++i) {
pbest[i] = pos[i];
}
}
}
/**
* 更新速度和位置
*/
public void updatev() {
for (int i = 0; i < dims; ++i) {
v[i] = w * v[i] + c1 * rnd.nextDouble() * (pbest[i] - pos[i])
+ c2 * rnd.nextDouble() * (gbest[i] - pos[i]);
if (v[i] > 20) {
v[i] = 20;
}
if (v[i] < -20) {
v[i] = -20;
}
pos[i] = pos[i] + v[i];
if (pos[i] > 10) {
pos[i] = 10;
}
if (pos[i] < -10) {
pos[i] = -10;
}
}
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*粒子群类
* @author FashionXu
*/
public class PSO {
/**
* 粒子群
*/
Particle[] pars;
double global_best;//全局最优解
int pcount;//粒子的数量
/**
* 粒子群初始化
* @param n 粒子的数量
*/
public void init(int n) {
pcount = n;
global_best = -1e6;
int index = -1;
pars = new Particle[pcount];
//类的静态成员的初始化
Particle.c1 = 2;
Particle.c2 = 2;
Particle.w = 0.8;
Particle.dims = 3;
for (int i = 0; i < pcount; ++i) {
pars[i] = new Particle();
pars[i].initial(3);
pars[i].evaluate();
if (global_best < pars[i].fitness) {
global_best = pars[i].fitness;
index = i;
}
}
Particle.gbest = new double[Particle.dims];
for (int i = 0; i < 3; ++i) {
Particle.gbest[i] = pars[index].pos[i];
}
}
/**
* 粒子群的运行
*/
public void run() {
int runtimes = 500;
int index;
while (runtimes > 0) {
index = -1;
//每个粒子更新位置和适应值
for (int i = 0; i < pcount; ++i) {
pars[i].updatev();
pars[i].evaluate();
if (global_best < pars[i].fitness) {
global_best = pars[i].fitness;
index = i;
}
}
//发现更好的解
if (index != -1) {
for (int i = 0; i < 3; ++i) {
Particle.gbest[i] = pars[index].pos[i];
}
}
--runtimes;
}
}
/**
* 显示程序求解结果
*/
public void showresult() {
System.out.println("程序求得的最优解是" + global_best);
System.out.println("每一维的值是");
for (int i = 0; i < Particle.dims; ++i) {
System.out.println(Particle.gbest[i]);
}
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*测试粒子群算法
* @author FashionXu
*/
public class TestPSO {
public static void main(String []arg)
{
PSO pso=new PSO();
pso.init(50);
pso.run();
pso.showresult();
}
}