基本PSO算法实现(Java)

一.算法流程

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();
    }

}

 

posted @ 2015-06-14 15:58  mrpod2g  阅读(3305)  评论(2编辑  收藏  举报