zoukankan      html  css  js  c++  java
  • 普通粒子群算法和优化方法

    粒子群优化(PSO, particle swarm optimization) 是由Kennedy和Eberhart在1995年提出的一 种群智能优化方法。

    优点:好理解容易实现,适合解决极值问题

    缺点:容易过早收敛,容易陷入局部最优解,(如果初始点选的不好,可能就会被某个粒子带偏了= =/)

    (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 }
    粒子类
    算法类
    针对缺点,提出了 Multi-start PSO 算法,即每迭代若干次后,都保留历史优粒子,粒子全部初始化,以提高粒子的多样性,扩大搜索 空间。又提出了一种动态惯性权重的粒子群优化算法,惯性权重随着迭代次数的增加而降低,在开始阶段具有较强的全局搜索能力,而在后期以 较小的惯性权重能够收敛到优解。 
      1 package pso;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 import java.util.Random;
      6 
      7 public class NormalPSO {
      8 
      9     private static double[] gbest;// 全局最优位置
     10     private static double gbest_fitness = -0x3f3f3f;// 全局最优位置对应的fitness
     11     private static int particle_num = 10;// 粒子数
     12     private static int N = 100;// 迭代次数
     13     private static int c1, c2 = 2;
     14     private static double w = 1.4;// 惯性因子
     15     private static List<Particle> particles = new ArrayList<Particle>();// 粒子群
     16 
     17     /**
     18      * 初始化所有粒子
     19      */
     20     public static void initialParticles() {
     21         for (int i = 0; i < particle_num; i++) {
     22             Particle particle = new Particle();
     23             particle.initialX();
     24             particle.initialV();
     25             particle.fitness = particle.calculateFitness();
     26             particles.add(particle);
     27         }
     28     }
     29 
     30     /**
     31      * 更新 gbest
     32      */
     33     public static void updateGbest() {
     34         double fitness = -0x3f3f3f;
     35         int index = 0;
     36         for (int i = 0; i < particle_num; i++) {
     37             if (particles.get(i).fitness > fitness) {
     38                 index = i;
     39                 fitness = particles.get(i).fitness;
     40             }
     41         }
     42         if (fitness > gbest_fitness) {
     43             gbest = particles.get(index).pbest.clone();
     44             gbest_fitness = fitness;
     45         }
     46     }
     47 
     48     /**
     49      * 更新每个粒子的速度
     50      */
     51     public static void updateV() {
     52         for (Particle particle : particles) {
     53             for (int i = 0; i < particle.dimension; i++) {
     54                 double v = w * particle.V[i] + c1 * rand() * (particle.pbest[i] - particle.X[i])
     55                         + c2 * rand() * (gbest[i] - particle.X[i]);
     56                 if (v > particle.Vmax)
     57                     v = particle.Vmax * rand();
     58                 else if (v < -particle.Vmax)
     59                     v = -particle.Vmax * rand();
     60                 particle.V[i] = v;// 更新Vi
     61             }
     62         }
     63     }
     64 
     65     /**
     66      * 更新每个粒子的位置和pbest
     67      */
     68     public static void updateX() {
     69         for (Particle particle : particles) {
     70             for (int i = 0; i < particle.dimension; i++) {
     71                 particle.X[i] = particle.X[i] + particle.V[i];
     72                 if (particle.X[i] > particle.Xmax[i])
     73                     particle.X[i] = new Random().nextDouble() * (particle.Xmax[i] - particle.Xmin[i])
     74                             + particle.Xmin[i];
     75                 if (particle.X[i] < particle.Xmin[i])
     76                     particle.X[i] = new Random().nextDouble() * (particle.Xmax[i] - particle.Xmin[i])
     77                             + particle.Xmin[i];
     78             }
     79             double newFitness = particle.calculateFitness();// 新的适应值
     80             if (newFitness > particle.fitness) {
     81                 particle.pbest = particle.X.clone();
     82                 particle.fitness = newFitness;
     83             }
     84         }
     85     }
     86 
     87     /**
     88      * 算法主要流程
     89      */
     90     public static void process() {
     91         int n = 0;
     92         initialParticles();
     93         updateGbest();
     94         while (n++ < N) {
     95             /*
     96              * Multi-start PSO 算法,即每迭代若干次后,都保留历史优粒子, 粒子全部初始化,以提高粒子的多样性,扩大搜索 空间。
     97              */
     98             if (n == N / 2) {
     99                 initialParticles();
    100                 updateGbest();
    101             }
    102             updateV();
    103             updateX();
    104             updateGbest();
    105             w -= 0.01; // 动态惯性权重
    106             System.out.println(n + ". 当前gbest:(" + gbest[0] + "," + gbest[1] + ")  fitness = " + gbest_fitness);
    107         }
    108     }
    109 
    110     public static double rand() {
    111         return new Random().nextDouble();
    112     }
    113 
    114     public static void main(String[] args) {
    115         process();
    116     }
    117 }
    改进后的PSO

    改进后,虽然有一定的效果,但是效果不太明显。

    后来又提出许多混合粒子群算法,比如遗传粒子群(BPSO)、免疫粒子群(IPSO)、混沌粒子群等(CPSO),针对不同的领域,需选用适合的优化算法。

     

  • 相关阅读:
    洛谷 P2058 海港(模拟)
    LA 3708 墓地雕塑(模拟)
    Uva 11300 Spreading the Wealth(贪心)
    UVA 11729 Commando War (贪心)
    【洛谷习题】Likecloud-吃、吃、吃
    【洛谷习题】多米诺骨牌
    【洛谷习题】相似基因
    【NOI1995】石子合并
    【洛谷习题】尼克的任务
    【NOIP2004】合唱队形
  • 原文地址:https://www.cnblogs.com/flyuz/p/9210777.html
Copyright © 2011-2022 走看看