简单差分进化算法-python实现(学习笔记)

差分进化算法

1.1 概述

  • 差分进化算法(Differential Evolution, DE)是有Kenneth Price和Rainer Storn在尝试解决切比雪夫多项式拟合问题时提出的。

  • 是近年来最为流行的进化算法,性能非常优秀!在连续优化问题领域效果出类拔萃,而蚁群算法在组合问题、离散问题优化上极其优秀。

  • 在进化计算领域的知名学术会议IEEE CEC中的多节优化竞赛中,改进的DE算法排名前列。

1.2 算法步骤

  1. 变异操作

  2. 交叉操作

  3. 选择操作

变异操作生成变异个体,然后进行交叉操作生成实验个体,然后进行选择

  • 变异操作(DE区别于其他算法最重要的特征)

    • 是区别于其他进化算法的重要特征,生成变异个体V

    • DE/rand/1

      • V_i(t)=X_{r1}(t)+F \cdot (X_{r2}(t)-X_{r3}(t)),其中 X_{r2}(t)-X_{r3}(t) 为差分向量,角标r表示当前个体为随机个体,X_{r1}(t)为基向量,DE/rand/1 中的 1 表示只有一个差分向量

      • 将 r2 和 r3 向量做差,然后通过 F 进行缩放,将缩放后的向量差和基向量 r1 相加,生成变异个体 V

    • DE/rand/2

      • V_i(t)=X_{r1}(t)+F \cdot (X_{r2}(t)-X_{r3}(t))+F \cdot (X_{r4}(t)-X_{r5}(t)),其中 X_{r2}(t)-X_{r3}(t) 和 X_{r4}(t)-X_{r5}(t) 为差分向量,r为随机个体,基向量随机选,2表示有两个差分向量,多一个差分向量导致扰动更强,随机更好,全局搜索能力强

    • DE/best/1, 开采力强,局部搜索能力强

    • DE/best/2

    • DE/current-to-best/1

  • 交叉操作

    • 对目标个体和变异个体进行咋交,交换维度上的信息来生成实验个体 U,增加种群的多样性

    • 二项式交叉(简记为 bin)和指数较差(简记为 exp)

    • 二项式交叉(均匀交叉): U_{ij}(t)=\begin{cases} V_{ij}(t),& if \ rand_j < CR \ or \ j = j_{rand} \\ X_{ij}(t), & otherwise \end{cases},其中 CR 为交叉概率,表示 U 中某个基因来自于 V 的概率。二项式交叉要求保证 U 中至少有一个基因来自于 V,所以设置参数 j_{rand} 为 [0, D] 内的整数,其中 D 为个体基因维度,也就是向量的维度,使第 j 个基因必须来自于 V。

    • 指数交叉(不常用):U_{ij}(t)=\begin{cases} V_{ij}(t),& for \ j = \left<l\right>_D, \left<l+1\right>_D, ..., \left<l+L-1\right>_D \\ X_{ij}(t), & otherwise \end{cases}, <>表示求余操作

  • 选择操作

    • 从目标个体 X 和实验个体 U 中选出较优的一个进入下一代

    • 一对一选择(One-to-one selection)

  1.3 代码部分

1.3.1 规定模型基础参数

D = 2       # x 向量维度
F = 0.5     # 缩放率
CR = 0.9        # 变异率
LOW = [-3, -2]      # 上界
UP = [3, 2]     # 下界
PS = 30     # 种群大小
MaxFEs = 5E3        # ? 最大函数评估数

1.3.2 初始化种群

FEs = 0     # ? 当前函数评估数
pop :List[indi] = []        # 种群
for i in range(PS):     # 初始化种群
    x = np.random.rand(2)       # 生成当前个体的 x
    pop.append(indi(x, six_hump_camel_back(x)))     # 将当前个体的 fitness 求出,并将个体存入种群数组
FEs += PS   # ? 函数评估数加 PS

1.3.3 DE 算法迭代

while FEs<= MaxFEs:     # 当当前评估数不超过最大评估数时,进行差分进化算法
    for i in range(PS):     # 遍历整个种群
        trialindi = pop[i].clone()      # 将当前个体的深拷贝存储到变量中
        
        # * DE/rand/1
        r = random.sample(range(PS-1), 3)   # 随机选三个除了 i 以外的数字,作为选出的三个个体的索引
        for j in range(3):      # 选择方法使用 sample 先从 [0, PS-1) 中不重复的随机选择三个数字
            if r[j]>=i:     # 再将三个数字中,超过当前个体 i 的数字进行 +1
                r[j] += 1       # 实现避免选择到第 i 个个体的效果
        v = pop[r[0]].x + F * (pop[r[1]].x - pop[r[2]].x)       # * :math:`V_i(t)=X_{r1}(t)+F \cdot (X_{r2}(t)-X_{r3}(t))`
        
        # * bin
        jrand = random.randint(1, D)        # * 随机 [1, D] 的整数作为 rand_j,因为 bin 交叉必须保证 U 有至少一个基因来自于 V
        u = np.array([(pop[i].x[j], v[j])[random.random()<CR or jrand==j] for j in range(D)])       # 交叉操作,使用特殊的三目运算写法实现交叉
        
        # * selection
        u_fitness = six_hump_camel_back(u)      # 求出 U 的适应度
        if u_fitness<pop[i].fitness:        # 实验个体 U 和 当前个体 X 优胜劣汰
            pop[i] = indi(u, u_fitness)
    FEs += PS       # 评估数 +PS

1.3.4 寻找最优个体

# 找出 DE 算法后的种群内的最有适应度个体
best_index = 0
for i in range(PS):
    if pop[i].fitness < pop[best_index].fitness:
        best_index = i

1.4 代码完整链接

https://github.com/ky0ha/Evolutionary-Computation-test/blob/main/Differential-Evolution/DE.py 

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

虚叶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值