详述差分进化算法(DE)代码复现

本文详细介绍了差分进化算法(DE)的基本原理和步骤,包括种群初始化、变异、交叉和适应度函数选择。以求解二次函数最小值为例,展示了DE算法的Python实现过程,通过不断迭代和更新种群,最终找到最优解。DE算法适用于多维度复杂优化问题,具有较强的全局搜索能力。
摘要由CSDN通过智能技术生成

在这里插入图片描述

  申明!!本篇文章中所有的非代码性叙述和数学公式均摘录自差分进化算法(DE)详述

  差分进化算法(Differential Evolution Algorithm,DE)是基于群体智能理论的优化算法,它是通过群体内个体间的合作与竞争而产生的智能优化算法,字面意思即可看出它有别于遗传算法的自由组合自然选择,它更侧重的是个体与个体和个体与自身间的关系,包括合作与竞争。
  其主要步骤为:种群初始化,变异,交叉,适应度函数选择。
  为实现差分进化算法全过程,本文主要目标为:求解[-3,3]区间内, y = 2 x 2 + 3 x − 1 y=2x^2+3x-1 y=2x2+3x1最小值所对应的x值。

1.初始化

  • D为自变量维度,文章中D=1;
  • NP种群规模总数即个体总数,文章中NP=100;
  • 迭代次数100000;(由于种群中一次仅变异一个个体,所以迭代次数要多一些,可以设置种群中有若干个体均变异来降低迭代次数)
  • 交叉概率0.1
  • 确定自变量维度j的上下限,由于文章仅一个维度,因此j=1,上下限维度为-3,3;
  • 初始化种群:每个个体总服从上下限之间的均匀分布加标准正态分布的随机偏差。
             X i j , 0 = r a n f [ 0 , 1 ] ∗ ( X j ( U ) − X j ( L ) ) + X j ( L ) X_{ij,0}=ranf[0,1]*({X_{j}}^{(U)}-{X_{j}}^{(L)})+{X_{j}}^{(L)} Xij,0=ranf[0,1](Xj(U)Xj(L))+Xj(L)
    其中i=1,2,3…,NP;j=1,2,3,…,D
#### 初始化 ####
NP = 100 # 种群个体数
D = 1 #自变量维度  
iterate = 100000 #进化代数
x_l = -3 #上限
x_r = 3 #下限
CR = 0.1 # 交叉概率
#种群初始化:均分分布+标准正态分布的随机偏差
G = np.linspace(-3,3,100) + random.normalvariate(0,1)

2.变异

  个体图片在进入下一代时,需要从种群中随机选择三个互不相同的个体进行变异。
              v i , G + 1 = X r 1 , G + F ∗ X r 2 , G − X r 3 , G v_{i,G+1}=X_{r1,G}+F*{X_{r2,G}-X_{r3,G}} vi,G+1=Xr1,G+FXr2,GXr3,G

  其中v为变异后个体(v_new),r1,r2,r3代表与其互不相同的个体,缩放因子为F,其范围为[0,2],即2*random.random()

index = random.sample(range(0,NP),4) # 随机选择的变异个体
v_new =  G[index[1]] + 2*random.random()*(G[index[2]]-G[index[3]]) #变异

3.交叉

  利用交叉概率来判断其是否进行基因间的交叉。由于交叉是针对每个维度的自变量参数,因此本文没有交叉这一步骤。本文想要尽可能地还原交叉过程,因此本文将一个维度进行交叉,省略判断条件j=rnbr(i)。
v i j , G 0 + 1 = { v i j , G 0 + 1 r a n d b ( j ) < = C R    o r    j = r n b r ( i ) X i j , G 0 r a n d b ( j ) > C R    a n d    j ! = r n b r ( i ) v_{ij,G_{0+1}}=\left\{ \begin{aligned} v_{ij,G_{0+1}} \quad randb(j)<=CR\;or \; j=rnbr(i) \\ X_{ij,G_{0}} \quad randb(j)>CR\; and \; j!=rnbr(i) \end{aligned} \right. vij,G0+1={vij,G0+1randb(j)<=CRorj=rnbr(i)Xij,G0randb(j)>CRandj!=rnbr(i)

# G[index[0]] 为这一代发生变异的个体 
if random.random() <= CR : 
    #多维度判断应该如下所示
    #if random.random() <= CR or j == random.randint(0,D-1)
    v_new =  G[index[0]]+ 2*random.random()*(G[index[1]]-G[index[2]]) #变异
else:
    v_new = G[index[0]]

4.边界值处理

  因变异和交叉会导致新的个体的产生,所以有一些个体可能不满足约束,因此进行边界值处理。

  (1)取上下限内的随机数来代替新变量

v_new = random.random()*(x_r - x_l) + x_l

  (2)采用边界值吸收法处理

#边界值吸收法
if v_new <= x_l: 
    v_new = x_l 
if v_new >= x_r:
    v_new = x_r

5.适应度函数选择

  这一代产生的新的个体v_new与上一代的个体进行比较,如果这一代更适用于环境(此处为适应度函数值更小)则将这一代的新个体替换原个体。

# objective function
def objective_value(x):
    return 2*(x**2)+3*x-1   

if objective_value(v_new) < objective_value(G[index[0]]):
    G[index[0]] = v_new #新旧替换

  综上所述,全部代码如下。

import numpy as np 
import random
import math

#### 初始化 ####
NP = 100 # 种群个体数
iterate = 100000  #进化代数
x_l = -3 
x_r = 3 
CR = 0.1 # 交叉概率 

# objective function
def objective_value(x):
    return 2*(x**2)+3*x-1
# 初始化
G = np.linspace(-3,3,100) + random.normalvariate(0,1)

def Differential_Evolution(G):
    # 变异(随机选择一个当前个体与其他三个个体进行变异)
    index = random.sample(range(0,NP),4) # 随机选择的变异个体
    # 2*random.random() 为 F 缩放因子 
    # 交叉
    if random.random() <= CR :# j == random.randint(0,D-1)
        v_new =  G[index[1]] + 2*random.random()*(G[index[2]]-G[index[3]]) #变异
        if v_new <= x_l :
            # 任选其一
            v_new = random.random()*(x_r - x_l) + x_l  # 上下限之间取随机数来代替不在范围内的值
            v_new = x_l # 边界值吸收法
        if v_new >= x_r:
            v_new = random.random()*(x_r - x_l) + x_l
            v_new = x_r
    else:
        v_new = G[index[0]]
    
    # 适应度函数
    if objective_value(v_new) < objective_value(G[index[0]]):
        G[index[0]] = v_new 
        
            
for i in range(iterate):
    Differential_Evolution(G)
    
print("final iterating is ",G)

  补充一点:由于Differential_Evolution()函数中,只是选取这一代中的某一个个体变异,因此需要迭代10万次才能达到最小值结果。如果想要迭代次数降低则可以增加一次查分进化算法中种群中个体变异的个数,以达到迭代次数降低的目的。

  通过如下的运行结果显示,最终稳定在-0.75附近,即找到了二维曲线在[-3,3]中的最小值所对应的横坐标即x=-0.75。
在这里插入图片描述

  • 5
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Foneone

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值