Python实现遗传算法求解n-queens问题
本课程将对遗传算法进行简单讲解,通过使用python实现简单的遗传算法求解函数极值以及通过实例了解Pyevolve的使用方法。非常适合熟悉Python基础,对算法较感兴趣的用户。 遗传算法(Genetic algorithm)属于演化计算( evolutionary computing),是随着人工智能领域发展而来的一种智能算法。正如它的名字所示,遗传算法是受达尔文进化论启发。简单来说,它是一种通过模拟自然进化过程搜索最优解的方法。
遗传算法入门
一,实验介绍
1.1 实验内容
遗传算法(Genetic algorithm)属于演化计算( evolutionary computing),是随着人工智能领域发展而来的一种智能算法。正如它的名字所示,遗传算法是受达尔文进化论启发。简单来说,它是一种通过模拟自然进化过程搜索最优解的方法。 本实验分两节:
- 第一节介绍遗传算法的理论知识并用Python实现简单遗传算法求解函数极值。
- 第二节利用pyevolve库解决一些复杂的优化问题。
1.2 实验知识点
通过本节学习,我们将学习到以下知识点:
- 关于遗传算法的理论知识
- 实现遗传算法的流程
- 数据的处理与可视化
1.3 实验环境
- Ubuntu 14.04.5
- Python2.7.6
- Xfce终端
1.4 适合人群
本课程难度为一般,属于初级级别课程。 比较适合以下用户:
- 熟悉Python基础的用户
- 对智能算法比较感兴趣的用户
- 对多维问题优化有兴趣的用户
1.5 代码获取
cd Codewget http://labfile.oss.aliyuncs.com/courses/776/Code_genetic.zipunzip Code_genetic.zip
1.6 实验效果
最优解值:
每代最优个体计划图:
![此处输入图片的描述](https://dn-anything-about-doc.qbox.me/document-uid268645labid2619timestamp1488643110102.png/wm)
运行实验代码之后的效果如下图:
二,开发准备
2.1 virtualenv环境配置
#安装virtualenvsudo pip install virtualenv#创建虚拟环境virtualenv genetic_python#cd genetic_python/bin/source ./activate
配置成功之后的效果图:
2.2 在新配置的Python环境中安装相关模块
$ sudo pip install numpy$ sudo apt-get install python-matplotlib
2.3 运行示例代码
cd Code/Code_geneticPython binary_genetic.py
三,实验步骤
3.1 了解理论知识
遗传学背景知识
- 种群(Population):生物的进化以群体的形式进行,这样的一个群体称为种群。
- 个体:组成种群的单个生物。
- 基因 ( Gene ) :一个遗传因子。
- 染色体 ( Chromosome ) :包含一组的基因。
- 生存竞争,适者生存:对环境适应度高的个体参与繁殖的机会比较多,后代就会越来越多。适应度低的个体参与繁殖的机会比较少,后代就会越来越少。
- 遗传与变异:新个体会遗传父母双方各一部分的基因,同时有一定的概率发生基因变异。
- 简单说来就是:繁殖过程,会发生基因交叉( Crossover ) ,基因突变 ( Mutation ) ,适应度( Fitness )低的个体会被逐步淘汰,而适应度高的个体会越来越多。那么经过N代的自然选择后,保存下来的个体都是适应度很高的,其中很可能包含产生的适应度最高的个体 历史:进化策略(ES)是在1965年由Rechenberg和Schwefel独立提出的。之后,进化策略的思想被其他研究者推广,John Holland和他的学生和同事在此基础上发明了遗传算法,与此同时Holland 的著作”Adaption in Natural and Artificial Systems“与1975年发布。
1993年,John Koza使用遗传算法写成演化程序来解决特定的问题。他称这种程序为遗传编程(GP)。使用的编程语言是LISP,因为这种编程语言可以用解析树(parse tree)的形式呈现,而解析树问题也是遗传算法的工作对象。
染色体(Chromosome):
所有的生物体都是由细胞组成,每一个细胞中都有一定数量的染色体。染色体是DNA的序列和遗传信息(基因)的主要载体。每一个基因对特定的蛋白质进行编码,通常来说就是每一个基因会控制一种特征,例如眼睛的颜色。用来控制同一个特征(蓝色或棕色)的基因被称为等位基因(alleles)。每一个基因在染色体上的位置是固定的,这个位置被称为基因座(locus). 完整的遗传物质(所有染色体)称为基因组。基因组中的特定基因称为基因型。基因型是个体表现型的有关基因组成,包括生理和心理特征,如眼睛颜色、智力等。
繁殖(Reproduction):
在繁殖过程中,首先发生的是重组(或交叉(crossover))。父母的基因在以某种方式形成了整个新染色体。新创建的后代可以突变。突变意味着DNA的组成基因有些变化。这种变化主要是由于父母复制基因的错误造成的。 个体的适应性是个体对于生存环境的适应程度决定。
搜索空间(search space):
如果我们解决一些问题,我们通常做的就是寻找它的解,并且力求找到最优解。一个问题的所有可能解称为搜索空间,搜索空间中的每一个点都代表一个可能解。一个可能解的可能程度是通过他所对应的计算值或适应度评估。
![此处输入图片的描述](https://dn-anything-about-doc.qbox.me/document-uid268645labid2619timestamp1488718504596.png/wm)
大多时候,我们所求的最优解是找寻搜索空间中函数极大值或极小值所对应的解。这个过程还是很复杂的,因为我们不知道从何搜起。现有一些找寻合适解的方法:爬山法(hill climbing),禁忌搜索(tabu search),模拟退火法(simulated annealing),遗传算法等。这些方法都是被认为比较好的方法,因为我们不需要证明所得到的解是最优的。
适应度函数(Fitness)
适应度用于评价个体的优劣程度,适应度越大个体越好,反之适应度越小则个体越差;根据适应度的大小对个体进行选择,以保证适应性能好的个体有更多的机会繁殖后代,使优良特性得以遗传.因此,遗传算法要求适应度函数值必须是非负数,而在许多实际问题中,求解的目标通常是费用最小,而不是效益最大,因此需要将求最小的目标根据适应度函数非负原则转换为求最大目标的形式。
3.2 二进制编码(Binary Encoding)
这里我要对代码中的一些变量进行说明:
popsize:每代的个体数
chrosize:变量编码长度
[xrangemin,xrangxmax] :变量取值范围
- crossrate:交叉率
- mutationrate :变异率
- generation:遗传代数
先导入需要用到的库:
from numpy import randomimport numpy as npimport matplotlib.pyplot as pltfrom math import pi,sinimport copy
二进制编码是最常用的的编码方式,每个个体都是由0,1组成。 表现型:一个具体的实数x 基因型:二进制编码(串长取决于求解精度) 我们可以随机生存0,1数组,然后在对随机数组对应到实数空间中进行解密。 编码长度越长,精度越高。如将6位二进制编码映射到$[-1,1]$内,则精度为:
,则先将二进制转化为十进制,如
,转化为$[-1,1]内为
。
初始化种群:
def initialpop(self): pop = random.randint(0,2,size =(self.popsize,self.chrosize)) return pop
初始化产生10个个体如下,其中黄色标记为最优个体,即对应实数的函数适应度最大:
![此处输入图片的描述](https://dn-anything-about-doc.qbox.me/document-uid268645labid2619timestamp1488643332848.png/wm)
对群组在实数空间内解码:
#对十进制进行转换到求解空间中的数值def