目录
经过历代版本的更迭,Geatpy目前支持多种使用风格。分别为:“求解器模式”写法、“面向对象”写法、“面向过程”写法。 其中“求解器模式”是Geatpy2.7.0之后新增的写法。可以大大节省代码量、更加专注于问题的定义。
先以“求解器模式”为例来快速入门。帮助您掌握如何快速构建问题、定义算法以及求解问题。
案例一
1.问题
用增强精英保留策略的遗传算法求解以下问题:
2.代码
import geatpy as ea
import numpy as np
# 构建问题
r = 1 # 目标函数需要用到的额外数据
@ea.Problem.single
def evalVars(Vars): # 定义目标函数(含约束)
f = np.sum((Vars - r) ** 2) # 计算目标函数值
x1 = Vars[0]
x2 = Vars[1]
CV = np.array([(x1 - 0.5)**2 - 0.25,
(x2 - 1)**2 - 1]) # 计算违反约束程度
return f, CV
problem = ea.Problem(name='soea quick start demo',
M=1, # 目标维数
maxormins=[1], # 目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标
Dim=5, # 决策变量维数
varTypes=[0, 0, 1, 1, 1], # 决策变量的类型列表,0:实数;1:整数
lb=[-1, 1, 2, 1, 0], # 决策变量下界
ub=[1, 4, 5, 2, 1], # 决策变量上界
evalVars=evalVars)
# 构建算法
algorithm = ea.soea_SEGA_templet(problem,
ea.Population(Encoding='RI', NIND=20),
MAXGEN=50, # 最大进化代数。
logTras=1, # 表示每隔多少代记录一次日志信息,0表示不记录。
trappedValue=1e-6, # 单目标优化陷入停滞的判断阈值。
maxTrappedCount=10) # 进化停滞计数器最大上限值。
# 求解
res = ea.optimize(algorithm, seed=1,
verbose=True,
drawing=1, outputMsg=True, drawLog=False, saveFlag=True, dirName='result')
3.分析
- 从上述代码可见,我们可以先定义一个目标函数,然后创建问题,再是构建算法,最后调用optimize()函数求解。 在上面的例子中,我们在定义目标函数时,加了一个@ea.Problem.single的标记。它可以让目标函数evalVars()的传入参数是一个Numpy ndarray类型的一维数组,它的实际含义是种群的某个个体对应的决策变量。在evalVars()中,我们通过f=np.sum((Vars - r) ** 2)计算出这组决策变量对应的目标函数值。
- 然后通过CV = np.array([(x1 - 0.5)**2 - 0.25, (x2 - 1)**2 - 1])来计算违反约束程度值。这是因为该问题除了变量范围外,有2个不等式约束。如果(x1−0.5)2−0.25(x1−0.5)2−0.25的值大于0,就说明违反了(x1−0.5)2≤0.25(x1−0.5)2≤0.25的约束,并且(x1−0.5)2−0.25(x1−0.5)2−0.25的值越大,违反约束的程度就越大。我们把计算得到的两个约束的违反约束程度值拼合在一起组成一个一维数组,就得到一个数组表示这组决策变量所有的违反约束程度值。
- 代码的第15行,这里调用了Geatpy的Problem问题类的构造函数,得到一个问题对象。 其中maxormins是一个记录着各个目标函数是最小化抑或是最大化的Numpy array行向量,其中元素为1表示对应的目标是最小化目标;为-1表示对应的是最大化目标。例如M=3,maxormins=array([1,-1,1]),此时表示有三个优化目标,其中第一、第三个是最小化目标,第二个是最大化目标。varTypes是一个记录着决策变量类型的行向量,其中的元素为0表示对应的决策变量是连续型变量;为1表示对应的是离散型变量。
- 接着,第24行,我们实例化了Geatpy内置实现的一个进化算法类的对象。其中第25行定义了该进化算法用什么样的种群去进化。Encoding='RI'表示改种群的染色体是'RI'编码,即“实数整数混合编码”,简称“实整数编码”。类似的还有'P'编码(排列编码,可以让对应的变量互不相同)、'BG'编码(二进制/格雷码编码)。然后NIND=20设定了种群有20个个体。
- 最后,在第31行,调用geatpy的optimize()函数进行求解。其中seed=1表示设置随机数种子。如果不想设置随机数种子,则把它设为None,或者不把它传入到optimize()函数中。dirName='result'表示把求解结果以文件的形式保存在当前工作目录下的result文件夹中。如果不传入dirName或者设dirName为None,则默认会以求解的起始时间的信息作为文件夹,把结果保存在里面。optimize()函数的其他传入参数以及31行获得的返回值res(类型为python字典)的内容可以用help(ea.optimize)或跳转进入源码查看。例如res['ObjV']表示算法搜索到的最佳目标函数值(它是个Numpy ndarray二维数组,每一行表示一组目标函数值。);res['Vars']表示对应的决策变量值矩阵(Numpy ndarray二维数组,每一行表示一组决策变量值)。
4.官方函数说明文档
官方文档对上述所涉及函数说明
4.1 ea.Problem.single
Signature: ea.Problem.single(func) Docstring: 描述: 装饰器single。通过给目标函数添加装饰器,可以更专注于问题的模型本身。因为此时传入自定义目标函数的只有一个个体或一组决策变量。 用法: 1. 给aimFunc()加上single装饰器标记后,可以让aimFunc()的传入参数:种群对象pop只有一个个体。 2. 给evalVars()加上single装饰器标记后,可以让evalVars()的传入参数:Vars变成Numpy ndarray一维数组。即只传入一组决策变量。
4.2 ea.Problem
ea.Problem( name, M, maxormins, Dim, varTypes, lb, ub, lbin=None, ubin=None, aimFunc=None, evalVars=None, calReferObjV=None, ) Docstring: Problem : Class - 问题类 描述: 问题类是用来存储与待求解问题相关信息的一个类。 属性: name : str - 问题名称(可以自由设置名称)。 M : int - 目标维数,即有多少个优化目标。 maxormins : array - 目标函数最小最大化标记的Numpy ndarray一维数组,1表示最小化,-1表示最大化,例如: array([1,1,-1,-1]),表示前2个目标是最小化,后2个目标是最大化。 Dim : int - 决策变量维数,即有多少个决策变量。 varTypes : array - 连续或离散标记,是Numpy ndarray类型的一维数组, 0表示对应的决策变量是连续的;1表示对应的变量是离散的。 lb : array - 存储着各个变量的下界。 ub : array - 存储着各个变量的上界。 ranges : array - 决策变量范围矩阵,第一行对应决策变量的下界,第二行对应决策变量的上界。 borders : array - 决策变量范围的边界矩阵,第一行对应决策变量的下边界,第二行对应决策变量的上边界, 0表示范围中不含边界,1表示范围包含边界。 ReferObjV : array - 存储着目标函数参考值的矩阵,每一行对应一组目标函数参考值,每一列对应一个目标函数。 TinyReferObjV : array - 从ReferObjV中均匀抽取的数目更少的目标函数参考值矩阵。 函数: aimFunc(pop) : 目标函数,需要在继承类即自定义的问题类中实现,或是传入已实现的函数。 其中pop为Population类的对象,代表一个种群, pop对象的Phen属性(即种群染色体的表现型)等价于种群所有个体的决策变量组成的矩阵, 该函数根据该Phen计算得到种群所有个体的目标函数值组成的矩阵,并将其赋值给pop对象的ObjV属性。 若有约束条件,则在计算违反约束程度矩阵CV后赋值给pop对象的CV属性(详见Geatpy数据结构)。 该函数不返回任何的返回值,求得的目标函数值保存在种群对象的ObjV属性中。 例如:population为一个种群对象,则调用aimFunc(population)即可完成目标函数值的计算, 此时可通过population.ObjV得到求得的目标函数值,population.CV得到违反约束程度矩阵。 注意:在子类中,aimFunc()和evalVars()两者只能重写一个。 evalVars(v) : 用于直接传入决策变量矩阵来计算对应的目标函数矩阵和违反约束程度矩阵。该函数需要被子类重写。 evaluation(pop) : 调用aimFunc()或evalVars()计算传入种群的目标函数值和违反约束程度。 calReferObjV() : 计算目标函数参考值,需要在继承类中实现,或是传入已实现的函数。 getReferObjV() : 获取目标函数参考值。
4.3 ea.soea_SEGA_templet
ea.soea_SEGA_templet( problem, population, MAXGEN=None, MAXTIME=None, MAXEVALS=None, MAXSIZE=None, logTras=None, verbose=None, outFunc=None, drawing=None, trappedValue=None, maxTrappedCount=None, dirName=None, **kwargs, ) Docstring: soea_SEGA_templet : class - Strengthen Elitist GA Algorithm(增强精英保留的遗传算法类) 算法描述: 本算法类实现的是增强精英保留的遗传算法。算法流程如下: 1) 根据编码规则初始化N个个体的种群。 2) 若满足停止条件则停止,否则继续执行。 3) 对当前种群进行统计分析,比如记录其最优个体、平均适应度等等。 4) 独立地从当前种群中选取N个母体。 5) 独立地对这N个母体进行交叉操作。 6) 独立地对这N个交叉后的个体进行变异。 7) 将父代种群和交叉变异得到的种群进行合并,得到规模为2N的种群。 8) 从合并的种群中根据选择算法选择出N个个体,得到新一代种群。 9) 回到第2步。 该算法宜设置较大的交叉和变异概率,否则生成的新一代种群中会有越来越多的重复个体。
4.4 ea.optimize
ea.optimize( algorithm, seed=None, prophet=None, verbose=None, drawing=None, outputMsg=True, drawLog=True, saveFlag=True, dirName=None, **kwargs, ) Docstring: 描述: 该函数用于快速部署问题和算法,然后对问题进行求解。 输入参数: algorithm : <class: class> - 算法类的引用。 seed : int - 随机数种子。 prophet : <class: Population> / Numpy ndarray - 先验知识。可以是种群对象, 也可以是一组或多组决策变量组成的矩阵(矩阵的每一行对应一组决策变量)。 verbose : bool - 控制是否在输入输出流中打印输出日志信息。 该参数将被传递给algorithm.verbose。 如果algorithm已设置了该参数的值,则调用optimize函数时,可以不传入该参数。 drawing : int - 算法类控制绘图方式的参数, 0表示不绘图; 1表示绘制最终结果图; 2表示实时绘制目标空间动态图; 3表示实时绘制决策空间动态图。 该参数将被传递给algorithm.drawing。 如果algorithm已设置了该参数的值,则调用optimize函数时,可以不传入该参数。 outputMsg : bool - 控制是否输出结果以及相关指标信息。 drawLog : bool - 用于控制是否根据日志绘制迭代变化图像。 saveFlag : bool - 控制是否保存结果。 dirName : str - 文件保存的路径。当缺省或为None时,默认保存在当前工作目录的'result of job xxxx-xx-xx xxh-xxm-xxs'文件夹下。 输出参数: result : dict - 一个保存着结果的字典。内容为: {'success': True or False, # 表示算法是否成功求解。 'stopMsg': xxx, # 存储着算法停止原因的字符串。 'optPop': xxx, # 存储着算法求解结果的种群对象。如果无可行解,则optPop.sizes=0。optPop.Phen为决策变量矩阵,optPop.ObjV为目标函数值矩阵。 'lastPop': xxx, # 算法进化结束后的最后一代种群对象。 'Vars': xxx, # 等于optPop.Phen,此处即最优解。若无可行解,则Vars=None。 'ObjV': xxx, # 等于optPop.ObjV,此处即最优解对应的目标函数值。若无可行解,ObjV=None。 'CV': xxx, # 等于optPop.CV,此处即最优解对应的违反约束程度矩阵。若无可行解,CV=None。 'startTime': xxx, # 程序执行开始时间。 'endTime': xxx, # 程序执行结束时间。 'executeTime': xxx, # 算法所用时间。 'nfev': xxx, # 算法评价次数 'gd': xxx, # (多目标优化且给定了理论最优解时才有) GD指标值。 'igd': xxx, # (多目标优化且给定了理论最优解时才有) IGD指标值。 'hv': xxx, # (多目标优化才有) HV指标值。 'spacing': xxx} # (多目标优化才有) Spacing指标值。