標籤:
一.演算法流程
Step1:初始化一群粒子(粒子個數為50個),包括隨即位置和速度;
Step2:計算每個粒子的適應度fitness;
Step3:對每個粒子,將其適應度與其進過的最好位置(局部)pbest做比較,如果較好,則將其作為當前的最好位置pbest;
Step4:對每個粒子,將其將其適應值與群體所經過的最好位置gbest做比較,如果較好,則將其作為當前最好位置gbest;
Step5:更新所有粒子位置和速度;
Step6:未達到結束條件則轉Step2。
二.實驗設定
(1) 粒子數particle_num=20;
(2) 迭代次數N=50;
(3) 慣性因子w=1.4;
(4) c1=c2=2;
(5) 最大速度Vmax=2。
三.實驗說明
PSO維基:https://en.wikipedia.org/wiki/Particle_swarm_optimization
目標函數:https://en.wikipedia.org/wiki/Test_functions_for_optimization 中的Ackley‘s function、Sphere function、和Rosenbrock function(都是求最小值)
完整代碼見我的github: https://github.com/wqpod2g/PSO
四.java代碼
1.particle類
package nju.iip;import java.util.Random;/** * 粒子類 * @author mrpod2g * */public class Particle { //維數 public int dimension = 2; //粒子的位置 public double[] X = new double[dimension]; //局部最好位置 public double[] pbest = new double[dimension]; //粒子的速度 public double[] V = new double[dimension]; //最大速度 public double Vmax = 2; //適應值 public double fitness; /** * 根據當前位置計算適應值 * @return newFitness */ public double calculateFitness() { //1.Ackley‘s function: //double newFitness = -20*Math.pow(Math.E,(-0.2*Math.sqrt(0.5*(X[0]*X[0]+X[1]*X[1]))))-Math.pow(Math.E,(0.5*(Math.cos(2*Math.PI*X[0])+Math.cos(2*Math.PI*X[1]))))+Math.E+20; //2.Sphere function //double newFitness = X[0]*X[0]+X[1]*X[1]; //3.Rosenbrock function double newFitness = 100*(Math.pow((X[1]-X[0]*X[0]),2))+Math.pow((X[0]-1), 2); return newFitness; } /** * 初始化自己的位置和pbest */ public void initialX() { for(int i=0;i<dimension;i++) { X[i] = new Random().nextInt(100); pbest[i] = X[i]; } } /** * 初始化自己的速度 */ public void initialV() { for(int i=0;i<dimension;i++) { double tmp = new Random().nextDouble();//隨機產生一個0~1的隨機小數 V[i] = tmp*4+(-2); } } }
2.PSO演算法實現過程
package nju.iip;import java.util.ArrayList;import java.util.List;import java.util.Random;/** * PSO演算法實現 * @author mrpod2g * */public class PSO { private static double[] gbest;//全域最優位置 private static double gbest_fitness = Double.MAX_VALUE;//全域最優位置對應的fitness private static int particle_num = 20;//粒子數 private static int N = 50;//迭代次數 private static int c1,c2 = 2; private static double w = 1.4;//慣性因子 private static List<Particle> particles = new ArrayList<Particle>();//粒子群 /** * 初始化所有粒子 */ public static void initialParticles() { for(int i=0;i<particle_num;i++) { Particle particle = new Particle(); particle.initialX(); particle.initialV(); particle.fitness = particle.calculateFitness(); particles.add(particle); } } /** * update gbest */ public static void updateGbest() { double fitness = Double.MAX_VALUE; int index = 0; for(int i=0;i<particle_num;i++) { if(particles.get(i).fitness<fitness) { index = i; fitness = particles.get(i).fitness; } } if(fitness<gbest_fitness) { gbest = particles.get(index).pbest.clone(); gbest_fitness = fitness; } } /** * 跟新每個粒子的速度 */ public static void updateV() { for(Particle particle:particles) { for(int i=0;i<particle.dimension;i++) { double v = w*particle.V[i]+c1*rand()*(particle.pbest[i]-particle.X[i])+c2*rand()*(gbest[i]-particle.X[i]); if(v>particle.Vmax) v = particle.Vmax; else if(v<-particle.Vmax) v = -particle.Vmax; particle.V[i] = v;//更新Vi } } } /** * 更新每個粒子的位置和pbest */ public static void updateX() { for(Particle particle:particles) { for(int i=0;i<particle.dimension;i++) { particle.X[i] = particle.X[i] + particle.V[i]; } double newFitness = particle.calculateFitness();//新的適應值 //如果新的適應值比原來的小則跟新fitness和pbest if(newFitness<particle.fitness) { particle.pbest = particle.X.clone(); particle.fitness = newFitness; } } } /** * 演算法主要流程 */ public static void process() { int n = 0; initialParticles(); updateGbest(); while(n++<N) { updateV(); updateX(); updateGbest(); System.out.println(n+".當前gbest:("+gbest[0]+","+gbest[1]+") fitness="+gbest_fitness); } } /** * 返回一個0~1的隨機數 * @return */ public static double rand() { return new Random().nextDouble(); } public static void main(String[] args) { process(); }}
基本PSO演算法實現(Java)