打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
进化策略

一、什么是进化策略
进化策略和遗传算法都使用到了遗传信息,比较DNA,然后繁衍变异,从而获取上一代没有的东西。然后通过适者生存不适者淘汰的这一套理论不断进化。
那下面来看下进化策略与遗传算法的不同。
就遗传算法来说,遗传算法使用的DNA是二进制编码的,爸妈的DNA交叉配对组成宝宝的DNA,宝宝也会再进行一定的变异获得新的属性,但是一般的进化策略却略有不同。


进化策略中,爸妈的DNA不再用01这种形式了,直接用实数来代替,这样就不会涉及二进制的转换问题了,从而能够解决实际生活中的很多由实数组成的真实问题,比如我有一个关于x的公式,而这个公式找那个其他参数都可以用DNA的实数来代替,然后进化我的DNA,也就是优化这个公式。那这个时候宝宝要如何变异呢?
进化策略中有一个因素可以帮我们进行宝宝变异,那就是变异强度,简单来说,我们将爸妈的遗传信息看成是正态分布的平均值,再在这个平均值上附加一个标准差,我们就能用正态分布产生一个相近的数,如下图:

比如途中8.8位置上的变异强度是1,我们就按照1的标准差和8.8的均值产生一个离8.8比较近的数,比如8.7,然后对宝宝每一位上的值进行同样的操作,就能产生稍微不同的宝宝DNA了,所以,变异强度也可以当成一组遗传信息从爸妈的DNA中遗传下来,甚至遗传为宝宝的变异强度基因也能变异。


所以,在进化策略中,可以将两种遗传信息传递给后代,一种是可以代表遗传信息所在位置的均值,另一种是记录这个均值的变异强度,有了这两组信息我们就可以自由的在实数区间进行变异繁衍啦。

二、代码实现进化策略
整个程序基本就是生孩子丢掉坏孩子的过程,每次就是生孩子然后将父母和孩子放在一起去计算他们的fitness,然后排序取前面一段作为新的population

import numpy as npimport matplotlib.pyplot as pltDNA_SIZE = 1             # DNA (real number)DNA_BOUND = [0, 5]       # solution upper and lower boundsN_GENERATIONS = 200POP_SIZE = 100           # population sizeN_KID = 50               # n kids per generationdef F(x): return np.sin(10*x)*x + np.cos(2*x)*x     # to find the maximum of this function# find non-zero fitness for selectiondef get_fitness(pred): return pred.flatten()#生宝宝def make_kid(pop, n_kid):    # generate empty kid holder    kids = {'DNA': np.empty((n_kid, DNA_SIZE))}    kids['mut_strength'] = np.empty_like(kids['DNA'])    for kv, ks in zip(kids['DNA'], kids['mut_strength']):        # crossover (roughly half p1 and half p2) 选择父亲和母亲        p1, p2 = np.random.choice(np.arange(POP_SIZE), size=2, replace=False)        cp = np.random.randint(0, 2, DNA_SIZE, dtype=np.bool)  # crossover points   选两个点        kv[cp] = pop['DNA'][p1, cp]        kv[~cp] = pop['DNA'][p2, ~cp]        ks[cp] = pop['mut_strength'][p1, cp]        ks[~cp] = pop['mut_strength'][p2, ~cp]        # mutate (change DNA based on normal distribution)        #让变异强度也进行变异,因为随着结果的慢慢收敛,我们也希望变异强度越来越小,这样才能更好更快的收敛        ks[:] = np.maximum(ks + (np.random.rand(*ks.shape)-0.5), 0.)    # must > 0        kv += ks * np.random.randn(*kv.shape)        kv[:] = np.clip(kv, *DNA_BOUND)    # clip the mutated value    return kids   将数据都控制在DNA范围内#丢掉坏宝宝def kill_bad(pop, kids):    # put pop and kids together    for key in ['DNA', 'mut_strength']:        pop[key] = np.vstack((pop[key], kids[key]))    fitness = get_fitness(F(pop['DNA']))            # calculate global fitness    idx = np.arange(pop['DNA'].shape[0])    good_idx = idx[fitness.argsort()][-POP_SIZE:]   # selected by fitness ranking (not value)    for key in ['DNA', 'mut_strength']:        pop[key] = pop[key][good_idx]    return pop#生成population,在这里我们不仅要生成DNA还要生成mutation strength变异强度pop = dict(DNA=5 * np.random.rand(1, DNA_SIZE).repeat(POP_SIZE, axis=0),   # initialize the pop DNA values           mut_strength=np.random.rand(POP_SIZE, DNA_SIZE))                # initialize the pop mutation strength valuesplt.ion()       # something about plottingx = np.linspace(*DNA_BOUND, 200)plt.plot(x, F(x))for _ in range(N_GENERATIONS):    # something about plotting    if 'sca' in globals(): sca.remove()    sca = plt.scatter(pop['DNA'], F(pop['DNA']), s=200, lw=0, c='red', alpha=0.5); plt.pause(0.05)    # ES part  整个进化的循环其实就是不断的生小孩和丢掉坏小孩的过程    kids = make_kid(pop, N_KID)    pop = kill_bad(pop, kids)   # keep some good parent for elitismplt.ioff(); 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
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
基因突变有哪些原因?
生物:《遗传与进化》必记知识点归纳学案
【生物】如何以问题形式记住生物易错知识点(下)
遗传变异和进化
病毒的起源与进化
高中生物必修2知识点:现代生物进化理论
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服