前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >优化算法——差分进化算法(DE)

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

作者头像
felixzhao
发布2018-03-19 10:51:36
2.8K0
发布2018-03-19 10:51:36
举报
文章被收录于专栏:null的专栏null的专栏

一、差分进化算法的介绍

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

二、差分进化算法的流程

  1. 初始化种群
  2. 变异
  3. 交叉
  4. 选择
(DE流程)
(DE流程)

三、差分进化的具体步骤

   对于无约束优化问题

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

4、选择

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

四、实际的优化问题

   求解优化问题:

一、Java实现

代码语言:javascript
复制
package org.zzy.de;

import java.util.Random;

public class Population {
	public static int NP = 1000;// 种群规模
	public static int size = 10;// 个体的长度
	public static int xMin = -10;// 最小值
	public static int xMax = 10;// 最大值
	public static double F = 0.5;// 变异的控制参数
	public static double CR = 0.8;// 杂交的控制参数

	private double X[][] = new double[NP][size];// 个体
	private double XMutation[][] = new double[NP][size];
	private double XCrossOver[][] = new double[NP][size];
	private double fitness_X[] = new double[NP];// 适应值

	public double[][] getX() {
		return X;
	}

	/**
	 * 矩阵的复制
	 * 
	 * @param x把x复制给个体
	 */
	public void setX(double x[][]) {
		for (int i = 0; i < NP; i++) {
			for (int j = 0; j < size; j++) {
				this.X[i][j] = x[i][j];
			}
		}
	}

	public double[] getFitness_X() {
		return fitness_X;
	}

	public void setFitness_X(double[] fitness_X) {
		for (int i = 0; i < NP; i++) {
			this.fitness_X[i] = fitness_X[i];
		}
	}

	public double[][] getXMutation() {
		return XMutation;
	}

	public void setXMutation(double xMutation[][]) {
		for (int i = 0; i < NP; i++) {
			for (int j = 0; j < size; j++) {
				this.XMutation[i][j] = xMutation[i][j];
			}
		}
	}

	public double[][] getXCrossOver() {
		return XCrossOver;
	}

	public void setXCrossOver(double xCrossOver[][]) {
		for (int i = 0; i < NP; i++) {
			for (int j = 0; j < size; j++) {
				this.XCrossOver[i][j] = xCrossOver[i][j];
			}
		}
	}

	/**
	 * 适应值的计算
	 * 
	 * @param XTemp根据个体计算适应值
	 * @return返回适应值
	 */
	public double CalculateFitness(double XTemp[]) {
		double fitness = 0;
		for (int i = 0; i < size; i++) {
			fitness += XTemp[i] * XTemp[i];// 做一个X的平方相加的函数
		}
		return fitness;
	}

	/**
	 * 初始化:随机初始化种群,计算个体的适应值
	 */
	public void Initialize() {
		double XTemp[][] = new double[NP][size];
		double FitnessTemp[] = new double[NP];
		Random r = new Random();
		for (int i = 0; i < NP; i++) {
			for (int j = 0; j < size; j++) {
				XTemp[i][j] = xMin + r.nextDouble() * (xMax - xMin);
			}
			// 计算适应值
			FitnessTemp[i] = CalculateFitness(XTemp[i]);
		}

		this.setX(XTemp);
		this.setFitness_X(FitnessTemp);
	}

	/******** 变异操作 ***********/
	public void Mutation() {
		double XTemp[][] = new double[NP][size];
		double XMutationTemp[][] = new double[NP][size];
		XTemp = this.getX();
		Random r = new Random();
		for (int i = 0; i < NP; i++) {
			int r1 = 0, r2 = 0, r3 = 0;
			while (r1 == i || r2 == i || r3 == i || r1 == r2 || r1 == r3
					|| r2 == r3) {// 取r1,r2,r3
				r1 = r.nextInt(NP);
				r2 = r.nextInt(NP);
				r3 = r.nextInt(NP);
			}
			for (int j = 0; j < size; j++) {
				XMutationTemp[i][j] = XTemp[r1][j] + F
						* (XTemp[r2][j] - XTemp[r3][j]);
			}
		}
		this.setXMutation(XMutationTemp);
	}

	/**
	 * 交叉操作
	 */
	public void CrossOver() {
		double XTemp[][] = new double[NP][size];
		double XMutationTemp[][] = new double[NP][size];
		double XCrossOverTemp[][] = new double[NP][size];

		XTemp = this.getX();
		XMutationTemp = this.getXMutation();
		// 交叉操作
		Random r = new Random();
		for (int i = 0; i < NP; i++) {
			for (int j = 0; j < size; j++) {
				double rTemp = r.nextDouble();
				if (rTemp <= CR) {
					XCrossOverTemp[i][j] = XMutationTemp[i][j];
				} else {
					XCrossOverTemp[i][j] = XTemp[i][j];
				}
			}
		}
		this.setXCrossOver(XCrossOverTemp);
	}

	/**
	 * 选择操作:使用贪婪选择策略
	 */
	public void Selection() {
		double XTemp[][] = new double[NP][size];
		double XCrossOverTemp[][] = new double[NP][size];
		double FitnessTemp[] = new double[NP];
		double FitnessCrossOverTemp[] = new double[NP];
		
		XTemp = this.getX();
		XCrossOverTemp = this.getXCrossOver();// 交叉变异后的个体
		FitnessTemp = this.getFitness_X();
		
		// 对群体进行重新设置
		for (int i = 0; i < NP; i++) {
			FitnessCrossOverTemp[i] = CalculateFitness(XCrossOverTemp[i]);
			if (FitnessCrossOverTemp[i] < FitnessTemp[i]) {
				for (int j = 0; j < size; j++){
					XTemp[i][j] = XCrossOverTemp[i][j];
				}
				FitnessTemp[i] = FitnessCrossOverTemp[i];
			}
		}
		this.setX(XTemp);
		this.setFitness_X(FitnessTemp);
	}

	/**
	 * 保存每一代的全局最优值
	 */
	public void SaveBest() {
		double FitnessTemp[] = new double[NP];
		FitnessTemp = this.getFitness_X();
		int temp = 0;
		// 找出最小值
		for (int i = 1; i < NP; i++) {
			if (FitnessTemp[temp] > FitnessTemp[i]) {
				temp = i;
			}
		}
		System.out.println(FitnessTemp[temp]);
	}
}

测试

代码语言:javascript
复制
package org.zzy.test;

import org.zzy.de.Population;

public class DETest {
	public static void main(String args[]) {
		int gen = 0;
		int maxCycle = 1000;
		Population p = new Population();
		p.Initialize();// 初始化
		while (gen <= maxCycle) {
			p.Mutation();
			p.CrossOver();
			p.Selection();
			gen++;
			p.SaveBest();
		}
	}

}

二、收敛曲线

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、差分进化算法的介绍
  • 二、差分进化算法的流程
  • 三、差分进化的具体步骤
    • 4、选择
    • 四、实际的优化问题
      • 一、Java实现
        • 二、收敛曲线
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档