遗传算法详解

您所在的位置:网站首页 蚁群算法能解决什么问题呢 遗传算法详解

遗传算法详解

2024-07-15 08:10:56| 来源: 网络整理| 查看: 265

1、遗传算法简介

  遗传算法(Genetic Algorithm,GA)最早是由美国的 John holland于20世纪70年代提出,该算法是用于解决最优化问题的一种搜索算法。它是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,通过数学的方式,利用计算机仿真运算,将问题的求解过程转换成类似生物进化中的染色体基因的交叉、变异等过程。其本质是一种高效、并行、全局搜索的方法,能在搜索过程中自动获取和积累有关搜索空间的知识,并自适应地控制搜索过程以求得最佳解。

2、问题引入

  遗传算法是用来解决最优化问题的,下面以求一个二元函数在 x∈[−3,3],y∈[−3,3] 范围里的最大值为例子来详细讲解遗传算法的每一步。选取的二元函数为:

def F(x,y): return 3*(1-x)**2*np.exp(-(x**2)-(y+1)**2)- 10*(x/5 - x**3 - y**5)*np.exp(-x**2-y**2)- 1/3**np.exp(-(x+1)**2 - y**2)

  将函数可视化,可视化代码和运行结果如下:

%matplotlib notebook # 为使结果图能旋转,本次使用的编辑器为jupyter notebook import numpy as np import matplotlib.pyplot as plt plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams["axes.unicode_minus"] = False def F(x,y): return 3*(1-x)**2*np.exp(-(x**2)-(y+1)**2)- 10*(x/5 - x**3 - y**5)*np.exp(-x**2-y**2)- 1/3**np.exp(-(x+1)**2 - y**2) x = np.arange(-3, 3, 0.01) # 可视化的 x 坐标范围 y = np.arange(-3, 3, 0.01) # 可视化的 y 坐标范围 # 生成 x-y 平面采样网格点,方便可视化 X,Y = np.meshgrid(x,y) Z = F(X,Y) # 计算网格点上的函数值 ax = plt.axes(projection='3d') ax.plot_surface(X,Y,Z,cmap='rainbow') # 3D 曲面图 ax.view_init(60, -30) ax.set_xlabel('x') ax.set_ylabel('y') plt.show()

在这里插入图片描述    可以很容易发现函数在这个局部的最大值大概在当x ≈ 0 , y ≈ 1.5 时,函数值取得最大值,而这里的 x , y 的取值就是我们最后想要得到的结果。

3、相关概念介绍以及实现代码

   为了更能方便理解遗传算法,这里需要引进几组概念。

基因型(genotype):性状染色体的内部表现; 表现型(phenotype):染色体决定的性状的外部表现,或者说,根据基因型形成的个体的外部表现; 进化(evolution):种群逐渐适应生存环境,品质不断得到改良。生物的进化是以种群的形式进行的。 适应度(fitness):度量某个物种对于生存环境的适应程度。 选择(selection): 以一定的概率从种群中选择若干个个体。一般,选择过程是一种基于适应度的优胜劣汰的过程。 复制(reproduction):细胞分裂时,遗传物质DNA通过复制而转移到新产生的细胞中,新细胞就继承了旧细胞的基因。 交叉(crossover):两个染色体的某一相同位置处DNA被切断,前后两串分别交叉组合形成两个新的染色体。也称基因重组或杂交; 变异(mutation):复制时可能(很小的概率)产生某些复制差错,变异产生新的染色体,表现出新的性状。 编码(coding):DNA中遗传信息在一个长链上按一定的模式排列。遗传编码可看作从表现型到基因型的映射。 解码(decoding):基因型到表现型的映射。 个体(individual):指染色体带有特征的实体; 种群(population):个体的集合,该集合内个体数称为种群的大小 3.1 种群和个体

   遗传算法是受进化理论启发而形成的。进化是由种群为单位的,种群在生物学上是指在一定空间范围内同时生活着的同种生物的全部个体。显然要想理解种群的概念,又先得理解个体的概念。在遗传算法里,个体通常为某个问题的一个解,并且该解在计算机中被编码为一个向量。例如,上面的例子中要求最大值,所以该问题的解为一组可能的 ( x , y ) 的取值。比如( x = 2.1 , y = 0.8 ) , ( x = − 1.5 , y = 2.3 ) . . . 就是求最大值问题的一个可能解,也就是遗传算法里的个体,把这样的一组一组的可能解的集合就叫做种群。比如在这个问题中设置100个这样的 x , y 的可能的取值对,那么这100个个体就构成了种群。

3.2 编码、解码与染色体

   在上面个体概念里提到个体(也就是一组可能解)在计算机程序中被编码为一个向量表示,而在我们这个问题中,个体是x , y 的取值,是两个实数,所以问题就可以转化为如何将实数编码为一个向量表示,编码是为了方便后续操作(交叉和变异)。在计算机中,将不同的实数用二进制串来表示就完成了编码,解码即为编码的逆行为。将个体(可能解)编码后的二进制串叫做染色体,染色体(或者有人叫DNA)就是个体(可能解)的二进制编码表示。   遗传算法中每一条染色体,对应着遗传算法的一个解决方案,一般用适应性函数(fitness function)来衡量这个解决方案的优劣。所以从一个基因组到其解的适应度形成一个映射,可以把遗传算法的过程看作是一个在多元函数里面求最优解的过程。

3.3 适应度和选择

   遗传算法是在得到一个种群后根据适者生存规则把优秀的个体保存下来,同时淘汰掉那些不适应环境的个体。那么,如何评价一个个体对环境的适应度?以求解上述函数最大值为例,这个衡量的标准比较容易制定:函数值的大小,即适应度函数直接返回函数值就行了。即直接用可能解(个体)对应的函数的函数值的大小来评估,这样可能解对应的函数值越大越有可能被保留下来。其求解函数最大值的python代码如下:

def get_fitness(pop): x,y = translateDNA(pop) pred = F(x, y) return (pred - np.min(pred)) + 1e-3 #减去最小的适应度是为了防止适应度出现负数,通过这一步fitness的范围为[0, np.max(pred)-np.min(pred)],最后在加上一个很小的数防止出现为0的适应度

pred是将可能解带入函数F中得到的预测值,因为后面的选择过程需要根据个体适应度确定每个个体被保留下来的概率,而概率不能是负值,所以所以最后加上了一个很小的正数。有了求最大值的适应度函数,求最小值适应度函数也就容易了,python代码如下:

def get_fitness(pop): x,y = translateDNA(pop) pred = F(x, y) return (pred - np.max(pred)) + 1e-3

.    有了评估的适应度函数,则可以根据适者生存法则将优秀者保留下来了。选择是根据新个体的适应度进行,但同时不意味着完全以适应度高低为导向(选择 k 个适应度最高的个体,容易陷入局部最优解,因为单纯选择适应度高的个体将可能导致算法快速收敛到局部最优解而非全局最优解,我们称之为早熟)作为折中,遗传算法依据原则:适应度越高,被选择的机会越高,而适应度低的,被选择的机会就低。常用的选择方法――轮盘赌(Roulette Wheel Selection)选择法。比如有5条染色体,他们所对应的适应度评分分别为:5,7,10,13,15,所以所以累计总适应度为: 在这里插入图片描述 则各个个体被选中的概率分别为: 在这里插入图片描述 可以想象一下,转动轮盘,轮盘停下来的时候,指针会随机地指向某一个个体所代表的区域,很明显,适应度评分越高的个体被选中的概率越大。

   遗传算法的选择在python中使用choice实现,np.random.choice函数是numpy库中用于生成随机样本的函数。它可以从一个给定的数组中随机抽取样本。该函数有三个必选参数: a、Size、p。其中a为数组,size为抽取样本的个数,p为每个元素被抽到的概率。还有其他可选参数如replace、weights、random_state等。代码如下:

def select(pop, fitness): # nature selection wrt pop's fitness idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True, p=(fitness)/(fitness.sum()) ) return pop[idx]

其中,参数p描述了从np.arange(POP_SIZE)里选择每一个元素的概率,概率越高约有可能被选中,最后返回被选中的个体即可。

3.4 交叉、变异

   通过选择得到了当前看来“还不错的基因”,但是这并不是最好的基因,需要通过繁殖后代(包含有交叉+变异过程)来产生比当前更好的基因,但是繁殖后代并不能保证每个后代个体的基因都比上一代优秀,这时需要继续通过选择过程来让试应环境的个体保留下来,从而完成进化,不断迭代上面这个过程种群中的个体就会一步一步地进化。具体地繁殖后代过程包括交叉和变异两步。

   交叉: 二进制编码的基因交换过程非常类似高中生物中所讲的同源染色体的联会过程――随机把其中几个位于同一位置的编码进行交换,产生新的个体。每一个个体是由父亲和母亲两个个体繁殖产生,子代个体的DNA(二进制串)获得了一半父亲的DNA,一半母亲的DNA,但是这里的一半并不是真正的一半,这个位置叫做交配点,是随机产生的,可以是染色体的任意位置。 在这里插入图片描述

   变异: 通过交叉子代获得了一半来自父亲一半来自母亲的DNA,但是子代自身可能发生变异,使得其DNA即不来自父亲,也不来自母亲,在某个位置上发生随机改变,通常就是改变DNA的一个二进制位(0变到1,或者1变到0)。例如下面这串二进制编码:

101101001011001

经过基因突变后,可能变成以下这串新的编码:

001101011011001

   需要说明的是交叉和变异不是必然发生,而是有一定概率发生。先考虑交叉,最坏情况,交叉产生的子代的DNA都比父代要差(这样算法有可能朝着优化的反方向进行,不收敛),如果交叉是有一定概率不发生,那么就能保证子代有一部分基因和当前这一代基因水平一样;而变异本质上是让算法跳出局部最优解,如果变异时常发生,或发生概率太大,那么算法到了最优解时还会不稳定。交叉概率,范围一般是0.6~1,突变常数(又称为变异概率),通常是0.1或者更小。对于这两个概率,我们一般管叫“步长”。一般来说步长越大,开始时进化的速度会比较快,但是后来比较难收敛到精确的点上。而小步长却能较精确的收敛到一个点上。所以很多时候为了加快遗传算法的进化速度,而又能保证后期能够比较精确地收敛到最优解上面,会采取动态改变步长的方法。这个过程与前面介绍的模拟退火过程比较相类似。

交叉和变异的实现代码如下:

def crossover_and_mutation(pop, CROSSOVER_RATE = 0.8): new_pop = [] for father in pop: #遍历种群中的每一个个体,将该个体作为父亲 child = father #孩子先得到父亲的全部基因(这里我把一串二进制串的那些0,1称为基因) if np.random.rand()


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭