差分进化算法python_差分进化算法

原理

最近在学习演化算法(Evolutionary algorithm),粒子群算法和遗传算法已经很熟悉了,而差分进化算法我还没认真研究过,趁着暑期实训的机会打算把差分进化算法做个总结,最后再将这三种算法做个比较。

差分进化算法是演化算法的一种,它的思想和遗传算法比较像,算法分为以下几个流程:

初始化

演化算法的初始化一般都是随机初始化,个体一般表示为一个多维向量[x1,x2,...,xn],xi∈[li,hi][x1​,x2​,...,xn​],xi​∈[li​,hi​],lili​和hihi​为第i维变量的范围。一般而言,对第i维而言,可以先产生一个0-1的随机数rr,然后xi=li+r∗(hi−li)xi​=li​+r∗(hi​−li​)。

评估

演化算法的个体的好坏是通过适应值函数来决定的,对于最小化问题而言,个体的适应值越小,则越有优势;最大化问题可以转换为最小化问题,毕竟maxf(x)=−min(−f(x))maxf(x)=−min(−f(x))

成熟&变异

差分进化算法的成熟和变异与遗传算法有些不同,对种群中的每一个个体,选出除该个体之外的另外三个个体a,b,c,新个体的产生方式如下:

mutant=a+mut∗(b−c)mutant=a+mut∗(b−c) mut为参数,一般取值为0.5-2。

新产生的个体还需要进行变异操作,对新个体的多维向量的每一维,以一定的概率进行变异得到新的值,变异的新数值一般是取[0,1]内的随机数,然后按照初始化中的操作将其变为范围位于[li,hi][li​,hi​]的值。变异之后,需要将该变异值与原个体值进行比较,取其中适应值更好的一个作为新个体值。再将该新个体值与种群中最优的个体进行比较,更新最优的个体值。

结束

进化算法的结束一般有两种,其一是设定循环的最大次数,达到最大次数后中止算法;其二是设定阈值,假定相邻的两次循环中最优个体的适应值差在阈值以内,则认为算法收敛并中止算法。最后的最优个体值即是本次算法求得的最优解。

实现

我利用python实现该算法并进行测试。代码如下:

import numpy as np

import matplotlib.pyplot as plt

def de(fobj, bounds, mut=0.8, crossp=0.7, popsize=20, its=1000):

dimensions = len(bounds)

pop = np.random.rand(popsize, dimensions)

min_b, max_b = np.asarray(bounds).T

diff = np.fabs(min_b - max_b)

pop_denorm = min_b + pop * diff

fitness = np.asarray([fobj(ind) for ind in pop_denorm])

best_idx = np.argmin(fitness)

best = pop_denorm[best_idx]

for i in range(its):

for j in range(popsize):

idxs = [idx for idx in range(popsize) if idx != j]

a, b, c = pop[np.random.choice(idxs, 3, replace = False)]

mutant = np.clip(a + mut * (b - c), 0, 1)

cross_points = np.random.rand(dimensions) < crossp

if not np.any(cross_points):

cross_points[np.random.randint(0, dimensions)] = True

trial = np.where(cross_points, mutant, pop[j])

trial_denorm = min_b + trial * diff

f = fobj(trial_denorm)

if f < fitness[j]:

fitness[j] = f

pop[j] = trial

if f < fitness[best_idx]:

best_idx = j

best = trial_denorm

yield best, fitness[best_idx]

def fitness(x):

return np.sum(x**2)/len(x)

bound=[(-100,100)]*20

results=de(fitness,bound)

x,f=zip(*results)

plt.plot(f)

plt.show()1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

上述代码参考自这位大佬,他的代码写的很简洁,我没有改动就直接拿上来了。

最后的效果如下:

效果

一般而言,当问题的维度比较小时,大概几十维的时候,演化算法的效果还是很可以的;当问题的维度变得很大,一般是几百维甚至上千维德时候,演化算法的效果就变得比较差了,需要较多的迭代次数才能得到一个较好的解,这也是"维数灾难"的一种体现。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值