本文主要介绍了对python遗传算法geatpy的深入理解,主要是从geatpy中的各种数据结构一步步学习,有一定的参考价值。有兴趣的可以看看。
:
目录
1.geatpy 2的安装。geatpy的基本数据结构2.1群体染色体2.2群体表型2.3目标函数值2.4个体适应度2.5违反度矩阵2.6解码矩阵2.7进化跟踪器3。全球人口结构3.1人口类别3.2心理人口类别4。求解标准测试函数——McCormick函数5。参考文章。今天,我们将学习遗传算法在python中的应用。我们在这里使用geatpy的包来学习。这个博客主要是一步步学习geatpy中的各种数据结构。请耐心看完。
其实我之前学过遗传算法,但主要是用matlab编程。后来觉得matlab太麻烦,用python更方便,就开始学习。
1. geatpy的安装
第一步是安装geatpy,这可以通过使用pip3命令来完成:
pip3安装geatpy
出现以下提示时,安装成功:
2. geatpy的基础数据结构
geatpy中的大部分数据都是使用numpy数组存储和计算的。下面,我将介绍遗传算法中的概念是如何用numpy数据表示的,以及行和列的含义。
2.1 种群染色体
遗传算法中最重要的是个体的染色体表示。在geatpy中,群体染色体用chrom表示,chrom是一个二维数组,其中每一行对应一个个体的染色体代码。chrom的结构如下:lind代表代码的长度,Nind代表种群的大小(个体的数量)。
2.2 种群表现型
群体表型是指通过解码群体的染色体矩阵chrom得到的基因表型矩阵phen。每行对应一个人,每列对应一个决策变量。phen的结构如下:Nvar代表变量个数。
Phen的值与所采用的解码方法有关。Geatpy提供了二进制/格雷码编码到十进制整数或实数的解码方法。另外,不需要解码的“实值编码”人群也可以用在Geatpy中。该群体染色体的每一位对应决策变量的实际值,即该编码模式下的Phen等价chrom。
2.3 目标函数值
Geatpy使用numpy的数组类型矩阵来存储群体的目标函数值。一般命名为ObjV,每一行对应每一个个体,所以和Chrom有相同的行数;每一列对应一个目标函数,所以对于单个目标函数,ObjV中只会有一列;但是对于多目标函数,会有多列ObjV,ObjV的表达式如下:
2.4 个体适应度
Geatpy使用列向量存储种群的个体适应度(由适应度函数计算)。一般命名为FitnV,也是numpy的数组类型,每行对应人口矩阵的每个个体。所以它的行数和Chrom一样,FitnV的格式如下:
注意:GEAT PY中的适应度遵循“最小适应度为0”的约定。
2.5 违反约束程度矩阵
Geatpy使用numpy的数组CV(约束违反值)来存储个体种群违反每个约束条件的程度。命名为CV,它的每一行对应于种群中的每一个个体,所以它的行数与Chrom相同;每列对应一个约束,所以如果有一个约束,CV矩阵就只有一列,如果有多个约束,CV矩阵就有多列。如果有num个约束,CV矩阵的结构如下图所示:
如果CV矩阵的某个元素小于等于0,则意味着该元素对应的个体满足相应的约束条件。如果大于0,说明违反了约束条件。如果大于0,值越大,违反个体约束的程度越高。Geatpy提供了两种处理约束的方法,一种是罚函数法,另一种是可行性法。在使用可行性法则处理约束条件时,我们需要使用CV矩阵。
2.6 译码矩阵
所谓解码矩阵,只是用来描述一个群体的染色体特征的矩阵,比如染色体中每个元素所表示的决策变量的范围,是否包含该范围的边界,是否使用二进制或格雷码,是否使用对数标度,染色体解码所表示的决策变量是连续变量还是离散变量等等。
当只使用工具箱的库函数而不使用Geatpy提供的面向对象进化算法框架时,可以单独使用解码矩阵。如果采用Geatpy提供的面向对象的进化算法框架,解码矩阵可以配合一个存储种群染色体编码方式的字符串编码使用。
目前,Geatpy中有三种编码,即:
BG:(二进制/格雷码)RI:((实整数编码,即实数和整数的混合编码)P:(置换编码,即染色体每一位的元素互不相同)
注:'RI ' '和' P '编码的染色体不需要解码,染色体上的每一位本身就代表决策变量的实值,所以“实整数编码”和“置换编码”可以统称为“实值编码”
以BG编码为例,我们来展示一下编译矩阵FieldD。FieldD的结构如下:
其中Lens、LB、UB、Codes、Scales、LBin、UBin、VARTypes都是行向量,它们的长度等于决策变量的个数。
透镜:代表每个染色体中每个子染色体的长度。Lb:代表每个变量的上界ub:代表每个变量的下界codes:代表染色体串的编码方式,[1,0,1]代表第一个变量的Gray编码,第二个变量的二进制编码,第三个变量的Gray编码。Scales:指示每个子字符串是使用算术标度还是对数标度。Scales[i]=0为算术标度,scales[i]=1为对数标度(对数标度很少使用,可以忽略。)lbin:表示变量的上界是否包含其范围边界。0表示否,1表示是。'['和'(' ubin的区别:表示变量的下界是否包含其范围边界。0表示否,1表示是。VarTypes:表示决策变量的类型;元素0表示相应位置的决策变量是连续变量;1表示它对应于一个离散变量。
例如,有以下解码矩阵
表明待解码群体的染色体矩阵chrom在解码后可以表示为三个决策变量,每个决策变量的取值范围分别为[1,10],[2,9]和[3,15]。第一和第二变量是二进制码,第三变量是格雷码,第一和第三决策变量是连续变量。第二个是离散变量。
#可以通过群体的染色体chrom和解码矩阵FieldD解码成群体表型矩阵。
将geatpy作为ea导入
Phen=ea.bs2ri(Chrom,FieldD)
2.7 进化追踪器
在使用Geatpy编写进化算法时,往往会设置一个进化跟踪器(如pop_trace)来记录种群进化过程中每一代的最优个体,特别是在不采用精英保留机制的情况下,进化跟踪器帮助我们记录种群进化过程中的最优个体。进化完成后,从进化跟踪器中选出“历史最佳”个体。这样的进化记录器有很多种,其中一种是numpy的数组类型,结构如下:其中MAXGEN是种群进化的代数(迭代次数)。
跟踪的每一列代表不同的指示器。例如,第一列记录每代群体的最佳目标函数值,第二列记录每代群体的平均目标函数值.跟踪的每一行对应于每一代,例如第一行代表第一代,第二行代表第二代.另一个演化记录器是一个列表,列表中的每个元素都是一个数据类型相同的数据。比如Geatpy的面向对象进化算法框架中的pop_trace就是一个列表,列表中的每一个元素都是一个历代的种群对象。
3. geatpy的种群结构
3.1 Population类
在Geatpy提供的面向对象进化算法框架中,种群类是存储与个体种群相关信息的类。它具有以下基本属性:
大小:群体间大小,即群体中个体的数量。chrom num:int-染色体数目,即每个个体有多少条染色体。编码:str-染色体编码法。Field:数组解码矩阵,可以是FieldD或FieldDR。Chrom:数组-群体染色体矩阵,每行对应一个个体的一条染色体。群体间染色体长度。ObjV:数组-群体目标函数值矩阵。群体个体适应度的数组列向量。CV:array——个体违反约束程度的矩阵。阵列-群体表型矩阵。
您可以直接从人口对象中提取个体和合并个体。例如,如果pop1和pop2是两个人口对象,您可以通过语句“pop3=pop1 pop2”合并这两个人口的个体,以获得一个新的人口。在合并的过程中,实际上是将种群的所有属性进行合并,然后由合并后的数据生成一个新的种群(详见Population.py)。比如执行语句“pop3=pop1[[0]]”,可以提取种群的第0个个体,得到一个只有一个个体的新种群对象pop3。值得注意的是,人口的这种单独提取操作要求下标必须是Numpy数组类型的列表或行向量,而不是标量(详见Population.py)。
3.2 PsyPopulation类
PsyPopulation类是Population的子类,它提供了Population类不支持的多染色体混合编码。它具有以下基本属性:
大小:群体间大小,即群体中个体的数量。chrom num:int-染色体数目,即每个个体有多少条染色体。编码:列表-存储每个染色体的编码方法列表。字段:列表-存储对应于每个染色体的解码矩阵列表。chroms:list-存储群体染色体矩阵的列表。列表——存储一个群体的染色体长度的列表。ObjV:数组-群体目标函数值矩阵。群体个体适应度的数组列向量。CV:array——个体违反约束程度的矩阵。阵列-群体表型矩阵。
可以看出,PsyPopulation类与Population类基本相同,只是分别使用了Lind、Encoding、field和chrome来存储多个Lind、Encoding、field和chrome。
PsyPopulation类的对象通常与带有单词“psy”的进化算法模板结合使用,以实现多染色体混合编码的进化优化。
4. 求解标准测试函数——McCormick函数
遗传算法求解下列函数中的最小值:
代码实现:
#-*-编码:utf-8-*-
将numpy作为np导入
将geatpy导入为ea#导入geatpy库
导入时间
''=================================================================='''
Def aim(Phen):#基因表型矩阵解码后的外来群体染色体矩阵
X1=Phen[:[0]]#取出第一列,得到所有个体的第一个自变量。
X2=Phen[:[1]]#取出第二列,得到所有个体的第二个自变量
返回NP . sin(x1 x2)(x1-x2)* * 2-1.5 * x1 2.5 * x2 1
''=================================================================''
X1=[-1.5,4]#第一个决定变量范围
X2=[-3,4]#第二个决定变量范围
B1=[1,1]#第一个决策变量的边界,1表示包含范围的边界,0表示不包含。
B2=[1,1]#第二个决策变量的边界,1表示包含范围的边界,0表示不包含。
#生成自变量的值域矩阵,使得第一个行为是所有决策变量的下界,第二个行为是上界。
ranges=np.vstack([x1,x2])。T
#生成独立变量的边界矩阵
borders=np.vstack([b1,b2])。T
VarTypes=np.array([0,0])#决策变量的类型,0表示连续,1表示离散。
' '=====================染色体编码设置===========================' '
Encoding='BG'#'BG '表示二进制/格雷编码。
Codes=[1,1]#决策变量的编码方式,两个1表示变量使用格雷编码。
Precision=[6,6] #决策变量的编码精度,这意味着解码后可以表示的决策变量的精度可以达到小数点后6位。
Scales=[0,0]#0表示算术标度,1表示对数标度#调用函数创建解码矩阵。
FieldD
nind=20 #群体中的个体数量
Max=100 #最大遗传代数
Maxormins=np.array([1])#表示目标函数最小化,元素-1表示对应的目标函数最大化。
SelectStyle='sus'#通过随机抽样选择。
RecStyle='xovdp'#采用两点相交。
MutStyle='mutbin'#二元染色体的变异算子
Lind=int(np.sum(FieldD[0,])#计算染色体长度
Pc=0.9#交叉概率
Pm=1/Lind#突变概率
Obj _ trace=np.zeros ((maxgen,2)) #定义目标函数值的记录器
Var _ trace=np.zeros ((maxgen,lind)) #染色体记录仪,记录历代最优秀个体的染色体。
=================================================' '
Start_time=time.time()#开始计时
Chrom=ea。crtpc (encoding,nind,fieldd) #生成群体染色体矩阵
Variable=ea.bs2ri (chrom,fieldd) #对初始群体进行解码
Obv=AIM(变量)#计算初始种群个体的目标函数值
Best_ind=np.argmin(ObjV)#计算当代最佳个人的序号
#开始进化
对于范围内的gen(MAXGEN):
fit=ea . ranking(maxormins * objv)#根据目标函数的大小分配适应值。
Sel=chrom [ea。选择(选择样式,适合NV,nind-1),] #选择
Sel=ea。重组(rec风格,selch,PC) #重组
Sel=ea.mutate (mut style,encoding,selch,pm) #突变
# #结合父代和子代精英个体的染色体,得到新一代种群。
Chrom=NP . v stack([Chrom[best _ ind,],SelCh])
Phen=ea.bs2ri(Chrom,FieldD)#对总体进行解码(二进制到十进制)
Obv=AIM (phen) #求个体群体的目标函数值
#记录
Best_ind=np.argmin(ObjV)#计算当代最佳个人的序号
Obj _ trace [gen,0]=np.sum (objv)/objv.shape [0] #记录当代人口目标函数的平均值
Obj _ trace [gen,1]=objv [best _ ind] #记录当代人口的最优个体目标函数值
Var _ trace [gen,=chrom [best _ ind,] #记录当代种群中最优秀个体的染色体
#进化完成
End_time=time.time()#结束计时
Ea.trcplot(obj_trace,[['个体种群的平均目标函数值','个体种群的最优目标函数值']]) #绘制图像
'======================================================================''
best_gen=np.argmin(obj_trace[:[1]])
Print('最优解的目标函数值:',obj_trace[best_gen,1])
variable=ea . bs2ri(var _ trace[[best _ gen],],fieldd) #解码得到表现型(即对应的决策变量值)
打印('最优解的决策变量值为:')
对于范围内的I(variable . shape[1]):
print('x' str(i) '=',变量[0,i])
打印(“经过时间:”、结束时间-开始时间,“秒”)
效果图:
结果如下:
5.参考文章
链接:geatpy文档。
这篇深入了解python遗传算法的geatpy的文章到此为止。有关python遗传算法的geatpy的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。