Python的geatpy库是一个高性能实用型的遗传算法(Genetic Algorithm)工具箱,由华南农业大学、暨南大学、华南理工等本硕博学生联合团队开发及维护。博主也是从3年前开始看着geatpy一点一点更新至2.7版本,在这里也是十分感谢开发团队的辛苦付出。较早版本的geatpy特别容易报错,且报错日志一致,很难针对性去纠错。新版本稳定性好了很多,作图更加精美,报错日志也更有针对性。本文就geatpy使用中的常见报错进行记录,该库的下载安装和使用方法可参考该篇博客,这里不再赘述。Python遗传和进化算法框架(一)Geatpy快速入门
本文引用的代码样例主要为geatpy中给出的soea_demo2
main.py
# -*- coding: utf-8 -*-
"""该案例展示了一个带等式约束的连续型决策变量最大化目标的单目标优化问题的求解。问题的定义详见MyProblem.py."""
from MyProblem import MyProblem # 导入自定义问题接口
import geatpy as ea # import geatpy
if __name__ == '__main__':
# 实例化问题对象
problem = MyProblem()
# 构建算法
algorithm = ea.soea_DE_rand_1_bin_templet(
problem,
ea.Population(Encoding='RI', NIND=100),
MAXGEN=500, # 最大进化代数。
logTras=1) # 表示每隔多少代记录一次日志信息,0表示不记录。
algorithm.mutOper.F = 0.5 # 差分进化中的参数F
algorithm.recOper.XOVR = 0.7 # 重组概率
# 求解
res = ea.optimize(algorithm,
verbose=True,
drawing=1,
outputMsg=True,
drawLog=False,
saveFlag=True)
print(res)
MyProblem.py
# -*- coding: utf-8 -*-
"""该目标函数存在多个欺骗性很强的局部最优点.
max f = 4*x1 + 2*x2 + x3
s.t.
2*x1 + x2 - 1 <= 0
x1 + 2*x3 - 2 <= 0
x1 + x2 + x3 - 1 == 0
0 <= x1,x2 <= 1
0 < x3 < 2
"""
import numpy as np
import geatpy as ea
class MyProblem(ea.Problem): # 继承Problem父类
def __init__(self):
name = 'MyProblem' # 初始化name(函数名称,可以随意设置)
M = 1 # 初始化M(目标维数)
maxormins = [-1] # 初始化maxormins(目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标)
Dim = 3 # 初始化Dim(决策变量维数)
varTypes = [0] * Dim # 初始化varTypes(决策变量的类型,元素为0表示对应的变量是连续的;1表示是离散的)
lb = [0, 0, 0] # 决策变量下界
ub = [1, 1, 2] # 决策变量上界
lbin = [1, 1, 0] # 决策变量下边界(0表示不包含该变量的下边界,1表示包含)
ubin = [1, 1, 0] # 决策变量上边界(0表示不包含该变量的上边界,1表示包含)
# 调用父类构造方法完成实例化
ea.Problem.__init__(self,
name,
M,
maxormins,
Dim,
varTypes,
lb,
ub,
lbin,
ubin)
def evalVars(self, Vars): # 目标函数
x1 = Vars[:, [0]]
x2 = Vars[:, [1]]
x3 = Vars[:, [2]]
f = 4 * x1 + 2 * x2 + x3
# 采用可行性法则处理约束
CV = np.hstack(
[2 * x1 + x2 - 1, x1 + 2 * x3 - 2, np.abs(x1 + x2 + x3 - 1)])
return f, CV
def calReferObjV(self): # 设定目标数参考值(本问题目标函数参考值设定为理论最优值)
referenceObjV = np.array([[2.5]])
return referenceObjV
这个问题是在定义问题类名的时候没有统一而产生的。geatpy常用代码框架分为两个.py文件,一个是main文件(算法运行主程序),一个是MyProblem文件(问题定义)。通过在MyProblem中描述问题,并定义类名,然后在main文件中引用类名来运行算法。如果出现以上问题,需要检查两个文件中的类名是否一一对应,主要包括MyProblem文件的文件名、以及其中
main文件中的
目标函数的设置不合法。原因是MyProblem中问题的目标函数维度不统一,需要检查该文件中以下两处代码的维度是否一致
下面给出M大于1时目标函数的表述,可以比较一下下面给出M大于1时目标函数的表述,可以比较一下:下面给出M大于1时目标函数的表述,可以比较一下:
从报错日志的提示可以看出,这个问题出在决策变量的矩阵维度不一致,需要检查MyProblem的
VarTypes是决策变量矩阵,用于定义变量的类型(离散 or 连续),geatpy中定义VarTypes必须是一维数组,因此需要检查MyProblem文件中VarTypes是决策变量矩阵,用于定义变量的类型(离散 or 连续),geatpy中定义VarTypes必须是一维数组,因此需要检查MyProblem文件中
诸如 VarTypes=3,VarTypes=[0,0]等表述都是错误的(前者不是数组或列表,后者维度与Dim不一致)。顺带一提,混合整数(例如2个整数变量、1个连续变量)的定义可用这样的表述
Dim1 = 2
Dim2 = 1
varTypes = [1] * Dim1 + [0] * Dim2
这类报错大多原因是geatpy更新后版本与原代码不兼容导致的,印象中只在2.4版本升级到2.7后出现过一次。解决方案是将geatpy升级,使用https://github.com/geatpy-dev/geatpy中的demo。
无法找到可行解。产生这个问题的原因有很多,本文列出一些比较常见的原因:
1、约束条件CV的设置不合理。geatpy中采用可行性法则构建约束条件的矩阵,如果约束条件输入有误,或者模型本身的约束条件互相冲突,都会导致算法找不到可行解。
2、模型规模大、迭代次数不够。对于许多大规模问题而言,可能难以在较少的迭代次数中找到可行解。如果检查过模型本身并不存在约束条件冲突的问题后仍然报错,可尝试在main文件中增大迭代次数、种群规模。
2.7版本的geatpy比较完善,不像先前版本有很多奇奇怪怪的bug,多数情况下只要你的建模本身没有问题,2.7版本都能统统拿下,因此古早版本的报错这里就不罗列了。本文总结的问题仅仅是冰山一角,以下网站还有更多问题的答疑:
GitHub上的issue:https://github.com/geatpy-dev/geatpy
geatpy大型交流平台,支持学者们在线答疑:https://app.gitter.im/#/room/#geatpy2_community:gitter.im
下一篇将分享一些geatpy中实用的改写细节(大概...)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。