用python实现遗传算法
Hello,大家好!最近事情比较多,一个月没有写公众号了,但也积累了些不错的内容可以分享,今天就给大家介绍的是遗传算法,并用python加以实现。
在遗传算法的学习过程中,在CSDN上看到一篇已有人分享的python代码,因此直接借鉴过来,并结合《数学建模与数学实验》进行补充。(电子书和原博主链接见文末)
遗传算法目录
- 遗传算法介绍
- 操作思路
- 初始化
- 编码
- 个体评价
- 选择
- 交叉
- 变异
- Python实现
- 初始化
- 编码
- 个体评价
- 选择
- 变异
- 交叉:单点交叉&两点交叉
- 参考资料
- 获得代码
遗传算法介绍
遗传算法(Genetic Algorithm),是由美国的J.Holland教授于1975年首先提出的,是受达尔文的进化论的启发,借鉴生物进化过程而提出的一种启发式搜索算法。
生存竞争,适者生存:对环境适应度高的个体参与繁殖的机会比较多,后代就会越来越多。适应度低的个体参与繁殖的机会比较少,后代就会越来越少。
简单来说就是一个繁殖的过程,会发生基因交叉(Crossover),基因突变(Mutation),适应度(Fitness)低的个体会被逐步淘汰,而适应度高的个体会越来越多。
操作思路
初始化
初始化进化代数计数器t←0,最大进化代数T(一般100500),初始化变异概率α(一般0.00010.2)、交叉概率β(一般0.40.99),随机生成M个(一般20100)个体作为初始群体P(t)。
编码
遗传算法中,首要问题就是如何对解进行编码(解的形式),编码影响到交叉、变异等运算,很大程度上决定了遗传算法的效率。
二进制编码:每个基因值为符号0和1所组成的二进制数;
格雷编码:与二进制编码类似,连续两个整数所对应编码仅一码之差;
实数编码:每个基因值用某一范围内的一个实数来表示;
符号编码:染色体编码串中的基因值取自一个无数值含义,而只有代码含义的符号集。
个体评价
计算P(t)中各个个体的适应度值。适应度函数:也称评价函数,是根据目标函数确定的用于区分群体中个体好坏的标准,适应度函数值的大小是对个体的优胜劣汰的依据。
选择
选择运算的作用是对个体进行优胜劣汰:从父代群体中选取一些适应度高个体遗传到下一代群体中。
轮盘赌法:又称比例选择算子,个体i被选中的概率Pi与其适应度成正比:
pi=fi∑i=1Nfip_i = \frac{f_i}{\sum_{i=1}^N f_i} pi=∑i=1Nfifi
两两竞争:从父代中随机地选取两个个体,比较适应度值,保存优秀个体,淘汰较差的个体
排序选择:根据各个体的适应度大小进行排序,然后基于所排序号进行选择。
交叉
是指对两个相互配对的染色体,依据交叉概率按某种方式相互交换其部分基因,从而形成两个新的个体。
变异
是对群体中的个体的某些基因座上的基因值作变动,模拟生物在繁殖过程,新产生的染色体中的基因会以一定的概率出错。
Python实现
初始化
DNA_SIZE = 24
POP_SIZE = 100
CROSSOVER_RATE = 0.8
MUTATION_RATE = 0.005
N_GENERATIONS = 100
编码
在遗传算法中,最常用的就是二进制编码,我们可以利用np.random.randint()来实现:
pop = np.random.randint(2, size = (POP_SIZE, DNA_SIZE*2))
参数说明:
numpy.random.randint(low, high=None, size=None, dtype=‘l’)
1、low:生成的数值最低要大于等于low;当hign = None时,生成的数值要在[0, low)区间内;
2、high:如果使用这个值,则生成的数值在[low, high)区间;
3、size:输出随机数的尺寸。默认是None的,仅仅返回满足要求的单一随机数;
4、dtype:想要输出的格式。如int64、int等等。
一般来说DNA长度越长,所包含的信息越多,结果就越精确,当然还得具体问题具体分析。
虽然二进制编码实现容易,便于操作,但是对于一些连续函数的优化问题,由于其随机性使得其局部搜索能力较差,当解迫近于最优解后,由于其变异后表现型变化很大,不连续,所以会远离最优解,达不到稳定。
格雷码的好处就在于能够提高遗传算法的局部搜索能力,相比二进制精度更高。
因此,给大家介绍如何把二进制转化为格雷码(原理大家自行查阅):
def BToG(pop):pop_g = []for i in pop:new = [i[0]]for j in range(1,len(i)):new.append(new[j-1]^i[j])pop_g.append(new)return np.array(pop_g)
参数说明:
“^”是按位异或运算符:当两对应的二进位相异时,结果为1,相同结果为0。
当然,对其进行编码后还需要再将其解码回二进制:
def jiema(pop_g):pop = []for i in pop_g:new = [i[0]]for j in range(1,len(i)):if i[j] == 0:new.append(new[j-1])else:if new[j-1] == 0:new.append(1)else:new.append(0)pop.append(new)return np.array(pop)
不同的编码,后续所对应的变换和突变也会有所不同,因为格雷码和二进制码比较相似,因此在这就先介绍这两种,其它编码欢迎加好友一起探讨学习。
个体评价
通常评价函数可以由目标函数直接或间接改造得到。比如,目标函数或目标函数的倒数/相反数经常被直接用作适应度函数。一般情况下,适应度是非负的,并且总是希望适应度越大越好。比较好的适应度函数应单值、连续、非负、最大化。
def get_fitness(pop): x1, x2 = translateDNA(pop)pred = F(x1, x2)return (pred - np.min(pred))
注:
translateDNA()是自定义的函数,用于将二进制码转换为数值,在测试部分会提到;F()是目标函数。
该评价函数是为了评价最大值的适应度,减去最小的结果是为了避免出现负数的情况;同理,如果我们想要最小值的适应度,就可以改成np.max (pred)-pred即可。
选择
两两竞争和排序选择都容易产生局部最优解的情况,因此遗传算法中更多使用的是轮盘赌法:
def select(pop, fitness):idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,p=(fitness)/(fitness.sum()))return pop[idx]
参数说明:
numpy.random.choice(a, size=None, replace=True, p=None)
1、从a(只要是ndarray都可以,但必须是一维的)中随机抽取数字,并组成指定大小(size)的数组;
2、replace:True表示可以取相同数字,False表示不可以取相同数字;
3、数组p:与数组a相对应,表示取数组a中每个元素的概率,默认为选取每个元素的概率相同。
变异
def mutation(child, MUTATION_RATE=0.003):if np.random.rand() < MUTATION_RATE:mutate_point = np.random.randint(0, DNA_SIZE)child[mutate_point] = child[mutate_point]^1
交叉:单点交叉&两点交叉
单点交叉:
def crossover_and_mutation(pop, CROSSOVER_RATE = 0.8):new_pop = []for father in pop: child = fatherif np.random.rand() < CROSSOVER_RATE:mother = pop[np.random.randint(POP_SIZE)]cross_points = np.random.randint(low=0, high=DNA_SIZE*2)child[cross_points:] = mother[cross_points:] mutation(child) new_pop.append(child)return new_pop
两点交叉:
def crossover_and_mutation(pop, CROSSOVER_RATE = 0.8):new_pop = []for father in pop: child = fatherif np.random.rand() < CROSSOVER_RATE: mother = pop[np.random.randint(POP_SIZE)]cross_points_1 = np.random.randint(low=0, high=DNA_SIZE*2)cross_points_2 = np.random.randint(low= cross_points_1, high=DNA_SIZE*2)child[cross_points_1: cross_points_2] = mother[cross_points_1:cross_points_2]mutation(child)new_pop.append(child)return new_pop
到此,遗传算法中所有的步骤我们均已实现,后面我们就以原博主所用的例子将所有步骤串起来,来进行测试。(此次测试与原博主不同的是采用格雷编码以及两点交叉遗传)
我们再拿原博主的代码跑一次做个对比。
从结果中可以看出,虽然我们用了新的编码和遗传形式进行计算,但结果并没有原博主的好,所以具体问题具体分析,用算法前得多加思考,多加尝试。
参考资料
1、https://blog.csdn.net/u014484715/article/details/40046307
2、《数学建模与数学实验》
获得代码
以下是我的个人公众号,本文完整代码已上传,关注公众号回复“遗传算法”,即可获得,回复“《数学建模与数学实验》”(注意要打“《》”),即可获得该书的电子版,谢谢大家支持。
用python实现遗传算法相关推荐
- Python实现遗传算法求函数最值
Python实现遗传算法求函数最值 详细源代码:GA.py 1.算法过程图解 2.详细过程举例说明 (1)待求解方程 (2)确定编码方案 主要是确定编码长度: def segment_length(s ...
- python实现遗传算法求解函数极值问题
python实现遗传算法求解函数极值问题 import random import numpy as np #定义染色体类 class chromosome:def __init__(self,chr ...
- 独家 | 基于Python的遗传算法特征约简(附代码)
作者:Ahmed Gad 翻译:张睿毅 校对:丁楠雅 本文4700字,建议阅读15分钟. 本教程主要使用numpy和sklearn来讨论如何使用遗传算法(genetic algorithm,GA)来减 ...
- python遗传算法_基于Python的遗传算法特征约简(附代码)
导言 在某些情况下,使用原始数据训练机器学习算法可能不是合适的选择.该算法在接受原始数据训练时,必须进行特征挖掘,以检测不同组之间的差异.但这需要大量的数据来自动执行特征挖掘.对于小数据集,数据科学家 ...
- 基于python实现遗传算法
一.研究背景 求解最优化问题的方法主要包括遗传算法.粒子群算法.蚁群算法等.与传统的搜索算法(牛顿法.斐波那契法.二分法等)相比,这三种算法具有高鲁棒性和求解高度复杂的非线性问题 的能力.本文主要针对 ...
- python mpi多线程_使用 MPI for Python 并行化遗传算法
前言 本文中作者使用MPI的Python接口mpi4py来将自己的遗传算法框架GAFT进行多进程并行加速.并对加速效果进行了简单测试. 项目链接: 正文 我们在用遗传算法优化目标函数的时候,函数通常都 ...
- Python—标准遗传算法求函数最大值代码实现
参考资料<智能优化算法及其matlab实例第二版> 第一次写博客,格式什么的不太清楚,大家见谅. 遗传算法 学习过程中,为了加深自己理解,在matlab源码的基础上采用Python进行改写 ...
- python实现遗传算法实例_基于Python的遗传算法特征约简(附代码)
作者:Ahmed Gad 翻译:张睿毅 校对:丁楠雅 本文4700字,建议阅读15分钟. 本教程主要使用numpy和sklearn来讨论如何使用遗传算法(genetic algorithm,GA)来减 ...
- Python实现遗传算法库
scikit-opt scikit-opt 这个库以很好用的方式实现了遗传算法的应用,是目前能找到的较好的遗传算法工具箱 目标函数 def demo_func(x):x1, x2, x3 = xret ...
- Python实现遗传算法(GA)+支持向量回归机(SVR)
本实验使用环境为Anaconda3 Jupyter,调用Sklearn包,请提前准备好. 1.引入一些常见包 主要包含pandas.numpy.绘图包.SVR.标准化.验证函数等包. from skl ...
最新文章
- 学好人工智能,其实不难,从以下几点开始
- 共识算法的比较:Casper vs Tendermint
- python基础代码事例-Python基础总结成千行代码,让Python入门更简单!
- Nginx Location配置总结
- 【企业管理】如何降低内部成本
- 巧妙解决element-ui下拉框选项过多的问题
- datagrid combobox 选择后显示valueField 而不是 textValue解决方法
- python pdf转html代码_Python3转换html到pdf的不同解决方案
- 如何在Kubernetes上部署图形数据库Nebula Graph
- 【逆向】【PE入门】使用PEView分析PE文件
- 总论点和分论点_将破坏性的论点变成富有成效的对话
- 比较好的java网站[推荐]
- luogu P4234 最小差值生成树
- 魏晋名士:骂人都不带脏字
- FMCW激光雷达科普(上):基本概念、技术路线、优势及争议和误解
- 不用PyScript,网页端运行的Python编辑器
- github 首页 html,GitHub - merrier/github-html-preview: 一个可以直接预览html页面的chrome插件...
- 计算机如果添加新用户名,怎么在电脑中创建新用户
- 毕业设计之 --- 在线考试系统
- OSPF邻居震荡抑制