优点:好理解容易实现,适合解决极值问题
缺点:容易过早收敛,容易陷入局部最优解,(如果初始点选的不好,可能就会被某个粒子带偏了= =/)
(下一步写分布式
(Java实现):
1 package pso; 2 3 import java.util.Random; 4 5 /** 6 * 粒子类 7 * 8 * @see dimension 9 * @author Flyuz 10 */ 11 public class Particle { 12 // 维数 13 public int dimension = 2; 14 // 粒子的位置 15 public double[] X = new double[dimension]; 16 // 粒子的速度 17 public double[] V = new double[dimension]; 18 // 局部最好位置 19 public double[] pbest = new double[dimension]; 20 // 最大速度 21 public double Vmax = 2; 22 // 最大位置 23 public double[] Xmax = { 2, 2 }; 24 // 最小位置 25 public double[] Xmin = { -2, -2 }; 26 // 适应值 27 public double fitness; 28 29 /** 30 * 根据当前位置计算适应值 本例子求式子最大值 31 * 32 * @return newFitness 33 */ 34 public double calculateFitness() { 35 36 double newFitness = 0; 37 if (X[0] == 0 && X[1] == 0) 38 newFitness = Math.exp((Math.cos(2 * Math.PI * X[0]) + Math.cos(2 * Math.PI * X[1])) / 2) - 2.71289; 39 else 40 newFitness = Math.sin(Math.sqrt(Math.pow(X[0], 2) + Math.pow(X[1], 2))) 41 / Math.sqrt(Math.pow(X[0], 2) + Math.pow(X[1], 2)) 42 + Math.exp((Math.cos(2 * Math.PI * X[0]) + Math.cos(2 * Math.PI * X[1])) / 2) - 2.71289; 43 return newFitness; 44 } 45 46 /** 47 * 初始化自己的位置和pbest 48 */ 49 public void initialX() { 50 for (int i = 0; i < dimension; i++) { 51 X[i] = new Random().nextDouble() * (Xmax[i] - Xmin[i]) + Xmin[i]; 52 pbest[i] = X[i]; 53 } 54 } 55 56 /** 57 * 初始化自己的速度 58 */ 59 public void initialV() { 60 for (int i = 0; i < dimension; i++) { 61 V[i] = new Random().nextDouble() * Vmax * 0.5; 62 } 63 } 64 }
1 package pso; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.Random; 6 7 /** 8 * PSO算法类 9 * 10 * @return newFitness 11 * 12 */ 13 public class PSO { 14 15 private static double[] gbest;// 全局最优位置 16 private static double gbest_fitness = Double.MIN_VALUE;// 全局最优位置对应的fitness 17 private static int particle_num = 10;// 粒子数 18 private static int N = 100;// 迭代次数 19 private static int c1, c2 = 2; 20 private static double w = 1.4;// 惯性因子 21 private static List<Particle> particles = new ArrayList<Particle>();// 粒子群 22 23 /** 24 * 初始化所有粒子 25 */ 26 public static void initialParticles() { 27 for (int i = 0; i < particle_num; i++) { 28 Particle particle = new Particle(); 29 particle.initialX(); 30 particle.initialV(); 31 particle.fitness = particle.calculateFitness(); 32 particles.add(particle); 33 } 34 } 35 36 /** 37 * 更新 gbest 38 */ 39 public static void updateGbest() { 40 double fitness = Double.MIN_VALUE; 41 int index = 0; 42 for (int i = 0; i < particle_num; i++) { 43 if (particles.get(i).fitness > fitness) { 44 index = i; 45 fitness = particles.get(i).fitness; 46 } 47 } 48 if (fitness > gbest_fitness) { 49 gbest = particles.get(index).pbest.clone(); 50 gbest_fitness = fitness; 51 } 52 } 53 54 /** 55 * 更新每个粒子的速度 56 */ 57 public static void updateV() { 58 for (Particle particle : particles) { 59 for (int i = 0; i < particle.dimension; i++) { 60 double v = w * particle.V[i] + c1 * rand() * (particle.pbest[i] - particle.X[i]) 61 + c2 * rand() * (gbest[i] - particle.X[i]); 62 if (v > particle.Vmax) 63 v = particle.Vmax; 64 else if (v < -particle.Vmax) 65 v = -particle.Vmax; 66 particle.V[i] = v;// 更新Vi 67 } 68 } 69 } 70 71 /** 72 * 更新每个粒子的位置和pbest 73 */ 74 public static void updateX() { 75 for (Particle particle : particles) { 76 for (int i = 0; i < particle.dimension; i++) { 77 particle.X[i] = particle.X[i] + particle.V[i]; 78 if(particle.X[i] > particle.Xmax[i]) 79 particle.X[i] = new Random().nextDouble() * (particle.Xmax[i] - particle.Xmin[i]) + particle.Xmin[i]; 80 if(particle.X[i] < particle.Xmin[i]) 81 particle.X[i] = new Random().nextDouble() * (particle.Xmax[i] - particle.Xmin[i]) + particle.Xmin[i]; 82 } 83 double newFitness = particle.calculateFitness();// 新的适应值 84 if (newFitness > particle.fitness) { 85 particle.pbest = particle.X.clone(); 86 particle.fitness = newFitness; 87 } 88 } 89 } 90 91 /** 92 * 算法主要流程 93 */ 94 public static void process() { 95 int n = 0; 96 initialParticles(); 97 updateGbest(); 98 while (n++ < N) { 99 updateV(); 100 updateX(); 101 updateGbest(); 102 System.out.println(n + ".当前gbest:(" + gbest[0] + "," + gbest[1] + ") fitness=" + gbest_fitness); 103 } 104 } 105 106 /** 107 * 返回一个0~1的随机数 108 * 109 * @return 返回一个0~1的随机数 110 */ 111 public static double rand() { 112 return new Random().nextDouble(); 113 } 114 115 public static void main(String[] args) { 116 process(); 117 } 118 }