算法 - 差分进化(DE)算法

简介

    差分进化算法(Differential Evolution,DE)由Storn和Price于1995年首次提出。主要用于求解实数优化问题。该算法是一类基于群体的自适应全局优化算法,属于演化算法的一种,由于其具有结构简单、容易实现、收敛快速、鲁棒性强等特点,因而被广泛应用在数据挖掘、模式识别、数字滤波器设计、人工神经网络、电磁学等各个领域。1996年在日本名古屋举行的第一届国际演化计算(ICEO)竞赛中,差分进化算法被证明是速度最快的进化算法。

1. 算法原理


    DE算法通过采用浮点矢量进行编码生成种群个体。在DE算法寻优的过程中,首先,从父代个体间选择两个个体进行向量做差生成差分矢量;其次,选择另外一个个体与差分矢量求和生成实验个体;然后,对父代个体与相应的实验个体进行交叉操作,生成新的子代个体;最后在父代个体和子代个体之间进行选择操作,将符合要求的个体保存到下一代群体中去。

2. 算法流程


假设优化模型如下:
min ⁡ f ( x 1 , x 2 , ⋯   , x D )  s.t  x j L ⩽ x j ⩽ x j U , j = 1 , 2 , ⋯   , D \begin{array}{l}{\min f\left(x_{1}, x_{2}, \cdots, x_{D}\right)} \\ {\text { s.t } \quad x_{j}^{L} \leqslant x_{j} \leqslant x_{j}^{U}, j=1,2, \cdots, D}\end{array} minf(x1,x2,,xD) s.t xjLxjxjU,j=1,2,,D
w h e r e where where,D是解空间的维度, x j L x_{j}^{L} xjL x j U x_{j}^{U} xjU分别表示第j个分量 x j x_{j} xj取值范围的上界和下界。

2.1 初始化种群

初始化种群为: { x i ( 0 ) ∣ x j , i L ⩽ x j , i ( 0 ) ⩽ x j , i v , i = 1 , 2 , ⋯   , N P ; j = 1 , 2 , ⋯   , D } \left\{x_{i}(0) | x_{j, i}^{L} \leqslant x_{j, i}(0)\leqslant x_{j, i}^{v}, i=1,2, \cdots, N P ; j=1,2, \cdots, D\right\} {xi(0)xj,iLxj,i(0)xj,iv,i=1,2,,NP;j=1,2,,D}
由下式随机生成各种群个体:
x j , i ( 0 ) = x j , i L + r a n d ( 0 , 1 ) ⋅ ( x j , i U − x j , i L ) x_{j, i}(0)=x_{j, i}^{L}+{rand}(0,1) \cdot\left(x_{j, i}^{U}-x_{j, i}^{L}\right) xj,i(0)=xj,iL+rand(0,1)(xj,iUxj,iL)
w h e r e where where x i ( 0 ) x_{i}(0) xi(0)表示种群中第0代的第i个个体, x j , i ( 0 ) x_{j, i}(0) xj,i(0)表示第0代的第i个个体的第j个基因。NP表示种群大小, r a n d ( 0 , 1 ) {rand}(0,1) rand(0,1)表示在(0,1)区间均匀分布的随机数。


在这里插入图片描述


2.2 变异

    差分进化算法与遗传算法最显著的区别在于DE的个体变异是通过差分策略实现的。

常用的差分策略如下:
ν i ( g + 1 ) = x i 1 ( g ) + F ⋅ ( x i ( g ) − x i j ( g ) ) i ≠ r 1 ≠ r 2 ≠ r 3 \begin{array}{c}{\nu_{i}(g+1)=x_{i_{1}}(g)+F \cdot\left(x_{i}(g)-x_{i j}(g)\right)} \\ {i \neq r_{1} \neq r_{2} \neq r_{3}}\end{array} νi(g+1)=xi1(g)+F(xi(g)xij(g))i=r1=r2=r3

w h e r e where where F {F} F为缩放因子, x i ( g ) x_{i}(g) xi(g)为第g代种群中第i个个体。

即通过随机选取种群中两个不同的个体,将其向量差缩放后与待变异个体进行向量合成。

    在进化过程中,必须保证新生成的解的有效性,因此必须判断生成的解是否满足边界条件,如果不满足,则需要重新生成(生成方案与初始种群相同)。

第g代种群: { x i ( g ) ∣ x j , i L ⩽ x j , i ( g ) ⩽ x j , i v , i = 1 , 2 , ⋯   , N P ; j = 1 , 2 , ⋯   , D } \left\{x_{i}(g) | x_{j, i}^{L} \leqslant x_{j, i}(g)\leqslant x_{j, i}^{v}, i=1,2, \cdots, N P ; j=1,2, \cdots, D\right\} {xi(g)xj,iLxj,i(g)xj,iv,i=1,2,,NP;j=1,2,,D}
变异后的中间体:第g代种群: { x i ( g + 1 ) ∣ x j , i L ⩽ x j , i ( g + 1 ) ⩽ x j , i v , i = 1 , 2 , ⋯   , N P ; j = 1 , 2 , ⋯   , D } \left\{x_{i}(g+1) | x_{j, i}^{L} \leqslant x_{j, i}(g+1)\leqslant x_{j, i}^{v}, i=1,2, \cdots, N P ; j=1,2, \cdots, D\right\} {xi(g+1)xj,iLxj,i(g+1)xj,iv,i=1,2,,NP;j=1,2,,D}


在这里插入图片描述


2.3 交叉

    使用第g代种群和其变异中间体进行交叉:

u j , i ( g + 1 ) = { v j , i ( g + 1 ) ,  if  rand ⁡ ( 0 , 1 ) ⩽ C R  or  j = j rand x j , i ( g ) ,  otherwise  \begin{aligned} u_{j, i}(g+1) =\left\{\begin{array}{ll}{v_{j, i}(g+1),} & {\text { if } \operatorname{rand}(0,1) \leqslant C R \text { or } j=j_{\text {rand}}} \\ {x_{j, i}(g),} & {\text { otherwise }}\end{array}\right.\end{aligned} uj,i(g+1)={vj,i(g+1),xj,i(g), if rand(0,1)CR or j=jrand otherwise 
w h e r e where where,CR为交叉概率, j r a n d j_{rand} jrand为[1,2,……,D]的随机整数。

在这里插入图片描述
    上图为6个基因位的“染色体”或称为“个体”的交叉操作示意图。为了确保变异中间体{ v j , i ( g + 1 ) {v_{j, i}(g+1)} vj,i(g+1)}的每个“染色体”至少有一个“基因”遗传给下一代,第一个交叉操作的基因是随机选择 v j , i ( g + 1 ) {v_{j, i}(g+1)} vj,i(g+1)的第 j r a n d j_{rand} jrand作为交叉后的个体 u j , i ( g + 1 ) u_{j, i}(g+1) uj,i(g+1) j r a n d j_{rand} jrand位的等位基因。后续的交叉操作则是通过交叉概率CR来选取 x i ( g ) x_{i}(g) xi(g)还是 v i ( g + 1 ) v_{i}(g+1) vi(g+1)的等位基因作为 u i ( g + 1 ) u_{i}(g+1) ui(g+1)的等位基因。


在这里插入图片描述


2.4 选择

    采用贪婪算法来选择下一代种群个体:
x i ( g + 1 ) = { u i ( g + 1 ) ,  if  f ( u i ( g + 1 ) ) ⩽ f ( x i ( g ) ) x i ( g ) ,  otherwise  x_{i}(g+1)=\left\{\begin{array}{ll}{u_{i}(g+1),} & {\text { if } f\left(u_{i}(g+1)\right) \leqslant f\left(x_{i}(g)\right)} \\ {x_{i}(g),} & {\text { otherwise }}\end{array}\right. xi(g+1)={ui(g+1),xi(g), if f(ui(g+1))f(xi(g)) otherwise 

3. 算法代码

3.1 伪代码

在这里插入图片描述

3.2 matlab


4. 参数控制1

    DE算法主要的控制参数包括:种群规模(NP)、缩放因子(F)和交叉概率(CR)

4.1 参数说明

  • NP主要反映算法中种群信息量的大小,NP值越大种群信息包含的越丰富,但是带来的后果就是计算量变大,不利于求解。反之,使种群多样性受到限制,不利于算法求得全局最优解,甚至会导致搜索停滞。

  • CR主要反映的是在交叉的过程中,子代与父代、中间变异体之间交换信息量的大小程度。CR的值越大,信息量交换的程度越大。反之,如果CR的值偏小,将会使种群的多样性快速减小,不利于全局寻优。

  • 相对于CR,F对算法性能的影响更大,F主要影响算法的全局寻优能力。F越小,算法对局部的搜索能力更好,F越大算法越能跳出局部极小点,但是收敛速度会变慢。此外,F还影响种群的多样性

4.2 参数选择

  • M:一般介于5n到10n之间,但不能少于4,否则变异算则无法进行
  • F:一般在[0,2],通常取0.5
  • CR:[0,1],通常取0.3.CR越大,收敛速度越快,但易发生早熟现象。

5. 改进方法1

  • 基本DE算法在求解的过程中,随着进化代数的增加,会使种群的多样性变小,过早的收敛到局部极小点,或者致使算法停滞,这对依靠种群差异来进行进化的算法来说无疑是致命的,使算法的性能在进化的过程中变差。

  • 为了解决基本DE算法的上述缺陷,针对DE算法的特点,目前主要的改进方法是针对进化模式和控制参数的优化,还有一些改进方法是将DE算法与其他一些智能算法进行结合仲用。

5.1 自适应变异算子

    为了避免早熟,增加自适应变异算子。算子算法如下:
λ = e 1 − G m G m + 1 − G F = F 0 ⋅ 2 2 \begin{array}{l}{\lambda=e^{1-\frac{G_{m}}{G_{m}+1-G}}} \\ {F=F_{0} \cdot 2^{2}}\end{array} λ=e1Gm+1GGmF=F022
w h e r e where where F 0 F_{0} F0为变异算子; G m G_{m} Gm为最大进化代数; G G G为当前进化代数。

    算法开始时,自适应算子 F = F 0 F= F_{0} F=F0~ 2 F 0 2F_{0} 2F0。具有较大值时,初期保持个体多样性,避免早熟,随着算法进度的不断变化,变异算子的值逐步降低,后期变异率接近 F 0 F_{0} F0,保留优良信息,避免最优解遭到破坏,增加搜索到全局最优解的概率。


  1. https://baike.baidu.com/item/%E5%B7%AE%E5%88%86%E8%BF%9B%E5%8C%96%E7%AE%97%E6%B3%95/10052475?fr=aladdin ↩︎ ↩︎

### 回答1: DE(Differential Evolution,差分进化算法是一种常用的全局优化算法,其基本思想是利用种群中个体的差异性进行搜索。 以下是使用Python实现DE算法的完整代码: ```python import numpy as np class DE: def __init__(self, func, bounds, npop, F=0.8, CR=0.9, maxiter=1000, tol=1e-6): """ :param func: 目标函数 :param bounds: 参数边界 :param npop: 种群数量 :param F: 缩放因子 :param CR: 交叉概率 :param maxiter: 最大迭代次数 :param tol: 收敛容差 """ self.func = func self.bounds = bounds self.npop = npop self.F = F self.CR = CR self.maxiter = maxiter self.tol = tol def optimize(self): nparams = len(self.bounds) # 初始化种群 pop = np.random.rand(self.npop, nparams) for i in range(nparams): pop[:, i] = self.bounds[i][0] + pop[:, i] * (self.bounds[i][1] - self.bounds[i][0]) # 计算初始适应度 fitness = np.array([self.func(p) for p in pop]) # 记录最优解 best_params = pop[np.argmin(fitness)] best_fitness = np.min(fitness) # 开始迭代 for i in range(self.maxiter): new_pop = np.zeros((self.npop, nparams)) for j in range(self.npop): # 随机选择3个个体 idxs = np.random.choice(self.npop, 3, replace=False) x1, x2, x3 = pop[idxs] # 生成变异个体 v = x1 + self.F * (x2 - x3) # 交叉操作 u = np.zeros(nparams) jrand = np.random.randint(nparams) for k in range(nparams): if np.random.rand() < self.CR or k == jrand: u[k] = v[k] else: u[k] = pop[j, k] # 边界处理 u = np.clip(u, self.bounds[:, 0], self.bounds[:, 1]) # 选择操作 new_fitness = self.func(u) if new_fitness < fitness[j]: new_pop[j] = u fitness[j] = new_fitness if new_fitness < best_fitness: best_params = u best_fitness = new_fitness else: new_pop[j] = pop[j] # 判断是否收敛 if np.max(np.abs(new_pop - pop)) < self.tol: break pop = new_pop return best_params, best_fitness ``` 使用方法: ```python # 定义目标函数 def func(x): return np.sum(x ** 2) # 定义参数边界 bounds = np.array([[-5.12, 5.12]] * 10) # 定义DE算法对象 de = DE(func, bounds, npop=50, F=0.8, CR=0.9, maxiter=1000, tol=1e-6) # 开始优化 best_params, best_fitness = de.optimize() # 输出最优解和最优适应度 print("最优解:", best_params) print("最优适应度:", best_fitness) ``` 注:上述代码中的目标函数为简单的二次函数,实际使用时需要根据具体问题定义相应的目标函数。 ### 回答2: DE(差分进化算法是一种全局优化算法,用于解决连续优化问题。其完整的代码如下所示: 1. 导入所需的Python库: ```python import random import numpy as np ``` 2. 定义DE算法的主要函数: ```python def differential_evolution(cost_func, bounds, pop_size, F, CR, max_iter): # 初始化种群 n_params = len(bounds) population = np.zeros((pop_size, n_params)) for i in range(pop_size): for j in range(n_params): population[i, j] = random.uniform(bounds[j][0], bounds[j][1]) # 迭代优化 for i in range(max_iter): for j in range(pop_size): # 选择三个不同的个体 candidates = [k for k in range(pop_size) if k != j] a, b, c = random.sample(candidates, 3) # 生成新个体 mutant = population[a] + F * (population[b] - population[c]) mutant = np.clip(mutant, bounds[:, 0], bounds[:, 1]) # 交叉操作 cross_points = np.random.rand(n_params) < CR if not np.any(cross_points): cross_points[np.random.randint(0, n_params)] = True trial = np.where(cross_points, mutant, population[j]) # 评估新个体的适应度 cost_trial = cost_func(trial) cost_current = cost_func(population[j]) # 更新种群 if cost_trial < cost_current: population[j] = trial # 返回最优个体和最优适应度 best_index = np.argmin([cost_func(ind) for ind in population]) best_individual = population[best_index] best_fitness = cost_func(best_individual) return best_individual, best_fitness ``` 3. 定义一个优化问题的目标函数,示例为Rastringin函数: ```python def rastringin(x): return sum([(xi**2 - 10 * np.cos(2 * np.pi * xi) + 10) for xi in x]) ``` 4. 设置问题的边界和其他参数: ```python bounds = [(-5.12, 5.12)] * 10 # 问题的边界 pop_size = 50 # 种群大小 F = 0.5 # 缩放因子 CR = 0.7 # 交叉概率 max_iter = 100 # 最大迭代次数 ``` 5. 调用DE算法进行优化,得到最优解和最优适应度: ```python best_individual, best_fitness = differential_evolution(rastringin, bounds, pop_size, F, CR, max_iter) print("最优解:", best_individual) print("最优适应度:", best_fitness) ``` 这段代码实现了DE算法的基本框架和一个示例目标函数的优化。可以根据实际问题进行适当的修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值