优化算法——差分进化算法(DE)

来源:互联网 发布:vb 中的structure 编辑:程序博客网 时间:2024/06/05 15:48

一、差分进化算法的介绍

   差分进化算法(Differential Evolution, DE)是一种基于群体差异的启发式随机搜索算法,该算法是由R.StornK.Price为求解Chebyshev多项式而提出的。DE算法也属于智能优化算法,与前面的启发式算法,如ABCPSO等类似,都属于启发式的优化算法。DE算法是我在一篇求解盒子覆盖问题论文中使用的一种优化算法。

二、差分进化算法的流程

  1. 初始化种群
  2. 变异
  3. 交叉
  4. 选择

(DE流程)

三、差分进化的具体步骤

   对于无约束优化问题

 

 

利用差分进化求解这样的优化问题,主要分为初始化、变异、交叉和选择等几项操作。

1、初始化

   如前面的的群智能优化算法一样,差分进化也需要初始化种群:

 

其中,是第个个体,表示第维。

 

其中,分别为第维的下界和上界,表示在区间上的随机数。

2、变异

       DE算法通过差分策略实现个体变异,常见的差分策略是随机选取种群中两个不同的个体,将其向量差缩放后与待变异个体进行向量合成。

 

其中,是三个随机数,区间为称为缩放因子,为一个确定的常数。表示第代。

3、交叉

   交叉操作的目的是随机选择个体,因为差分进化也是一种随机算法,交叉操作的方法是:

 

其中,称为交叉概率。通过概率的方式随机生成新的个体。

4、选择

   在DE中采用的是贪婪选择的策略,即选择较优的个体作为新的个体。

 

四、实际的优化问题

   求解优化问题:

 

 

一、Java实现

 

[java] view plain copy
  1. package org.zzy.de;  
  2.   
  3. import java.util.Random;  
  4.   
  5. public class Population {  
  6.     public static int NP = 1000;// 种群规模  
  7.     public static int size = 10;// 个体的长度  
  8.     public static int xMin = -10;// 最小值  
  9.     public static int xMax = 10;// 最大值  
  10.     public static double F = 0.5;// 变异的控制参数  
  11.     public static double CR = 0.8;// 杂交的控制参数  
  12.   
  13.     private double X[][] = new double[NP][size];// 个体  
  14.     private double XMutation[][] = new double[NP][size];  
  15.     private double XCrossOver[][] = new double[NP][size];  
  16.     private double fitness_X[] = new double[NP];// 适应值  
  17.   
  18.     public double[][] getX() {  
  19.         return X;  
  20.     }  
  21.   
  22.     /** 
  23.      * 矩阵的复制 
  24.      *  
  25.      * @param x把x复制给个体 
  26.      */  
  27.     public void setX(double x[][]) {  
  28.         for (int i = 0; i < NP; i++) {  
  29.             for (int j = 0; j < size; j++) {  
  30.                 this.X[i][j] = x[i][j];  
  31.             }  
  32.         }  
  33.     }  
  34.   
  35.     public double[] getFitness_X() {  
  36.         return fitness_X;  
  37.     }  
  38.   
  39.     public void setFitness_X(double[] fitness_X) {  
  40.         for (int i = 0; i < NP; i++) {  
  41.             this.fitness_X[i] = fitness_X[i];  
  42.         }  
  43.     }  
  44.   
  45.     public double[][] getXMutation() {  
  46.         return XMutation;  
  47.     }  
  48.   
  49.     public void setXMutation(double xMutation[][]) {  
  50.         for (int i = 0; i < NP; i++) {  
  51.             for (int j = 0; j < size; j++) {  
  52.                 this.XMutation[i][j] = xMutation[i][j];  
  53.             }  
  54.         }  
  55.     }  
  56.   
  57.     public double[][] getXCrossOver() {  
  58.         return XCrossOver;  
  59.     }  
  60.   
  61.     public void setXCrossOver(double xCrossOver[][]) {  
  62.         for (int i = 0; i < NP; i++) {  
  63.             for (int j = 0; j < size; j++) {  
  64.                 this.XCrossOver[i][j] = xCrossOver[i][j];  
  65.             }  
  66.         }  
  67.     }  
  68.   
  69.     /** 
  70.      * 适应值的计算 
  71.      *  
  72.      * @param XTemp根据个体计算适应值 
  73.      * @return返回适应值 
  74.      */  
  75.     public double CalculateFitness(double XTemp[]) {  
  76.         double fitness = 0;  
  77.         for (int i = 0; i < size; i++) {  
  78.             fitness += XTemp[i] * XTemp[i];// 做一个X的平方相加的函数  
  79.         }  
  80.         return fitness;  
  81.     }  
  82.   
  83.     /** 
  84.      * 初始化:随机初始化种群,计算个体的适应值 
  85.      */  
  86.     public void Initialize() {  
  87.         double XTemp[][] = new double[NP][size];  
  88.         double FitnessTemp[] = new double[NP];  
  89.         Random r = new Random();  
  90.         for (int i = 0; i < NP; i++) {  
  91.             for (int j = 0; j < size; j++) {  
  92.                 XTemp[i][j] = xMin + r.nextDouble() * (xMax - xMin);  
  93.             }  
  94.             // 计算适应值  
  95.             FitnessTemp[i] = CalculateFitness(XTemp[i]);  
  96.         }  
  97.   
  98.         this.setX(XTemp);  
  99.         this.setFitness_X(FitnessTemp);  
  100.     }  
  101.   
  102.     /******** 变异操作 ***********/  
  103.     public void Mutation() {  
  104.         double XTemp[][] = new double[NP][size];  
  105.         double XMutationTemp[][] = new double[NP][size];  
  106.         XTemp = this.getX();  
  107.         Random r = new Random();  
  108.         for (int i = 0; i < NP; i++) {  
  109.             int r1 = 0, r2 = 0, r3 = 0;  
  110.             while (r1 == i || r2 == i || r3 == i || r1 == r2 || r1 == r3  
  111.                     || r2 == r3) {// 取r1,r2,r3  
  112.                 r1 = r.nextInt(NP);  
  113.                 r2 = r.nextInt(NP);  
  114.                 r3 = r.nextInt(NP);  
  115.             }  
  116.             for (int j = 0; j < size; j++) {  
  117.                 XMutationTemp[i][j] = XTemp[r1][j] + F  
  118.                         * (XTemp[r2][j] - XTemp[r3][j]);  
  119.             }  
  120.         }  
  121.         this.setXMutation(XMutationTemp);  
  122.     }  
  123.   
  124.     /** 
  125.      * 交叉操作 
  126.      */  
  127.     public void CrossOver() {  
  128.         double XTemp[][] = new double[NP][size];  
  129.         double XMutationTemp[][] = new double[NP][size];  
  130.         double XCrossOverTemp[][] = new double[NP][size];  
  131.   
  132.         XTemp = this.getX();  
  133.         XMutationTemp = this.getXMutation();  
  134.         // 交叉操作  
  135.         Random r = new Random();  
  136.         for (int i = 0; i < NP; i++) {  
  137.             for (int j = 0; j < size; j++) {  
  138.                 double rTemp = r.nextDouble();  
  139.                 if (rTemp <= CR) {  
  140.                     XCrossOverTemp[i][j] = XMutationTemp[i][j];  
  141.                 } else {  
  142.                     XCrossOverTemp[i][j] = XTemp[i][j];  
  143.                 }  
  144.             }  
  145.         }  
  146.         this.setXCrossOver(XCrossOverTemp);  
  147.     }  
  148.   
  149.     /** 
  150.      * 选择操作:使用贪婪选择策略 
  151.      */  
  152.     public void Selection() {  
  153.         double XTemp[][] = new double[NP][size];  
  154.         double XCrossOverTemp[][] = new double[NP][size];  
  155.         double FitnessTemp[] = new double[NP];  
  156.         double FitnessCrossOverTemp[] = new double[NP];  
  157.           
  158.         XTemp = this.getX();  
  159.         XCrossOverTemp = this.getXCrossOver();// 交叉变异后的个体  
  160.         FitnessTemp = this.getFitness_X();  
  161.           
  162.         // 对群体进行重新设置  
  163.         for (int i = 0; i < NP; i++) {  
  164.             FitnessCrossOverTemp[i] = CalculateFitness(XCrossOverTemp[i]);  
  165.             if (FitnessCrossOverTemp[i] < FitnessTemp[i]) {  
  166.                 for (int j = 0; j < size; j++){  
  167.                     XTemp[i][j] = XCrossOverTemp[i][j];  
  168.                 }  
  169.                 FitnessTemp[i] = FitnessCrossOverTemp[i];  
  170.             }  
  171.         }  
  172.         this.setX(XTemp);  
  173.         this.setFitness_X(FitnessTemp);  
  174.     }  
  175.   
  176.     /** 
  177.      * 保存每一代的全局最优值 
  178.      */  
  179.     public void SaveBest() {  
  180.         double FitnessTemp[] = new double[NP];  
  181.         FitnessTemp = this.getFitness_X();  
  182.         int temp = 0;  
  183.         // 找出最小值  
  184.         for (int i = 1; i < NP; i++) {  
  185.             if (FitnessTemp[temp] > FitnessTemp[i]) {  
  186.                 temp = i;  
  187.             }  
  188.         }  
  189.         System.out.println(FitnessTemp[temp]);  
  190.     }  
  191. }  


测试

 

[java] view plain copy
  1. package org.zzy.test;  
  2.   
  3. import org.zzy.de.Population;  
  4.   
  5. public class DETest {  
  6.     public static void main(String args[]) {  
  7.         int gen = 0;  
  8.         int maxCycle = 1000;  
  9.         Population p = new Population();  
  10.         p.Initialize();// 初始化  
  11.         while (gen <= maxCycle) {  
  12.             p.Mutation();  
  13.             p.CrossOver();  
  14.             p.Selection();  
  15.             gen++;  
  16.             p.SaveBest();  
  17.         }  
  18.     }  
  19.   
  20. }  


二、收敛曲线