geatpy遗传算法包使用介绍

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Geatpy是国内几所高校做的一个开源遗传算法包,是一个高性能实用型进化算法工具箱,提供许多已实现的进化算法中各项重要操作的库函数,并提供一个高度模块化、耦合度低的面向对象的进化算法框架,利用“定义问题类 + 调用算法模板”的模式来进行进化优化,可用于求解单目标优化、多目标优化、复杂约束优化、组合优化、混合编码进化优化等。

Geatpy是国内几所高校做的一个开源遗传算法包,是一个高性能实用型进化算法工具箱,提供许多已实现的进化算法中各项重要操作的库函数,并提供一个高度模块化、耦合度低的面向对象的进化算法框架,利用“定义问题类 + 调用算法模板”的模式来进行进化优化,可用于求解单目标优化、多目标优化、复杂约束优化、组合优化、混合编码进化优化等。

基础问题求解

该算法包寻找最优解的基本分两步:第一步,搭建问题框架,编写目标函数、约束函数等;第二步;问题求解。简单介绍一个单目标问题求解的样例。

编写问题框架

#定义问题importnumpyasnpimportgeatpyasea"""max f = x * np.sin(10 * np.pi * x) + 2.0s.t.-1 <= x <= 2"""classMyProblem(ea.Problem):  # 继承Problem父类def__init__(self):
name='MyProblem'# 初始化name(函数名称,可以随意设置)M=1# 初始化M(目标维数)maxormins= [-1]  # 初始化maxormins(目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标)Dim=1# 初始化Dim(决策变量维数)varTypes= [0] *Dim# 初始化varTypes(决策变量的类型,元素为0表示对应的变量是连续的;1表示是离散的)lb= [-1]  # 决策变量下界ub= [2]  # 决策变量上界lbin= [1] *Dim# 决策变量下边界(0表示不包含该变量的下边界,1表示包含)ubin= [1] *Dim# 决策变量上边界(0表示不包含该变量的上边界,1表示包含)# 调用父类构造方法完成实例化ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin)
defevalVars(self, x):  # 目标函数f=x*np.sin(10*np.pi*x) +2.0returnf

问题求解

"""该案例展示了一个简单的连续型决策变量最大化目标的单目标优化问题的求解。问题的定义详见MyProblem.py。"""if__name__=='__main__':
# 实例化问题对象problem=MyProblem()
# 构建算法algorithm=ea.soea_SEGA_templet(problem,
ea.Population(Encoding='RI', NIND=10),#编码规则、种群个数MAXGEN=25,  # 最大进化代数。logTras=5,  # 表示每隔多少代记录一次日志信息,0表示不记录。trappedValue=1e-6,  # 单目标优化陷入停滞的判断阈值。maxTrappedCount=10)  # 进化停滞计数器最大上限值。# 求解res=ea.optimize(algorithm, verbose=True, drawing=1, outputMsg=True, drawLog=False, saveFlag=True)
print(res)

其结果很清晰地展示了求解过程,每一代的平均值、最大值、最小值等。以上是一个简单的函数最大值求解案例。

更常见的单目标问题求解:

importnumpyasnpimportgeatpyasea"""    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"""classMyProblem(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)
defevalVars(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)])
returnf, CVdefcalReferObjV(self):  # 设定目标数参考值(本问题目标函数参考值设定为理论最优值)referenceObjV=np.array([[2.5]])
returnreferenceObjV"""    该案例展示了一个带等式约束的连续型决策变量最大化目标的单目标优化问题的求解。"""if__name__=='__main__':
# 实例化问题对象problem=MyProblem()
# 构建算法algorithm=ea.soea_DE_rand_1_bin_templet(problem,
ea.Population(Encoding='RI', NIND=100),
MAXGEN=500,  # 最大进化代数。logTras=100)  # 表示每隔多少代记录一次日志信息,0表示不记录。algorithm.mutOper.F=0.5# 差分进化中的参数Falgorithm.recOper.XOVR=0.7# 重组概率# 求解res=ea.optimize(algorithm, verbose=True, drawing=1, outputMsg=True, drawLog=False, saveFlag=True)
print(res)

TSP问题求解

Geatpy提供了TSP问题求解的建模方法,同样是先建模,再求解的步骤。

importnumpyasnpimportgeatpyaseaimportmatplotlib.pyplotasplt"""    有十座城市:A, B, C, D, E, F, G, H, I, J,坐标如下:        X      Y    [[0.4,  0.4439],     [0.2439,0.1463],     [0.1707,0.2293],     [0.2293,0.761],     [0.5171,0.9414],     [0.8732,0.6536],     [0.6878,0.5219],     [0.8488,0.3609],     [0.6683,0.2536],     [0.6195,0.2634]]    某旅行者从A城市出发,想逛遍所有城市,并且每座城市去且只去一次,最后要返回出发地,而且需要从G地拿重要文件到D地,另外要从F地把公司的车开到E地,那么他应该如何设计行程方案,才能用最短的路程来满足他的旅行需求?    分析:在这个案例中,旅行者从A地出发,把其他城市走遍一次后回到A地,因此我们只需要考虑中间途径的9个城市的访问顺序即可。这9个城市需要排列组合选出满足约束条件的最优的排列顺序作为最终的路线方案。"""classMyProblem(ea.Problem):  # 继承Problem父类def__init__(self):
name='MyProblem'# 初始化name(函数名称,可以随意设置)M=1# 初始化M(目标维数)maxormins= [1]  # 初始化maxormins(目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标)Dim=9# 初始化Dim(决策变量维数)varTypes= [1] *Dim# 初始化varTypes(决策变量的类型,元素为0表示对应的变量是连续的;1表示是离散的)lb= [1] *Dim# 决策变量下界ub= [9] *Dim# 决策变量上界lbin= [1] *Dim# 决策变量下边界(0表示不包含该变量的下边界,1表示包含)ubin= [1] *Dim# 决策变量上边界(0表示不包含该变量的上边界,1表示包含)# 调用父类构造方法完成实例化ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin)
# 新增一个属性存储旅行地坐标self.places=np.array([[0.4, 0.4439],
                                [0.2439, 0.1463],
                                [0.1707, 0.2293],
                                [0.2293, 0.761],
                                [0.5171, 0.9414],
                                [0.8732, 0.6536],
                                [0.6878, 0.5219],
                                [0.8488, 0.3609],
                                [0.6683, 0.2536],
                                [0.6195, 0.2634]])
defevalVars(self, x):  # 目标函数# 添加从0地出发且最后回到出发地X=np.hstack([np.zeros((x.shape[0], 1)), x, np.zeros((x.shape[0], 1))]).astype(int)
ObjV= []  # 存储所有种群个体对应的总路程foriinrange(X.shape[0]):
journey=self.places[X[i], :]  # 按既定顺序到达的地点坐标distance=np.sum(np.sqrt(np.sum(np.diff(journey.T) **2, 0)))  # 计算总路程ObjV.append(distance)
f=np.array([ObjV]).T# 找到违反约束条件的个体在种群中的索引,保存在向量exIdx中(如:若0、2、4号个体违反约束条件,则编程找出他们来)exIdx1=np.where(np.where(x==3)[1] -np.where(x==6)[1] <0)[0]
exIdx2=np.where(np.where(x==4)[1] -np.where(x==5)[1] <0)[0]
exIdx=np.unique(np.hstack([exIdx1, exIdx2]))
CV=np.zeros((x.shape[0], 1))
CV[exIdx] =1# 把求得的违反约束程度矩阵赋值给种群pop的CVreturnf, CV"""    该案例展示了一个带约束的单目标旅行商问题的求解。"""if__name__=='__main__':
# 实例化问题对象problem=MyProblem()
# 构建算法algorithm=ea.soea_SEGA_templet(problem,
ea.Population(Encoding='P', NIND=50),
MAXGEN=200,  # 最大进化代数logTras=50)  # 表示每隔多少代记录一次日志信息,0表示不记录。algorithm.mutOper.Pm=0.5# 变异概率# 求解res=ea.optimize(algorithm, verbose=True, drawing=1, outputMsg=True, drawLog=False, saveFlag=True)
# 绘制路线图ifres['success']:
print('最短路程为:%s'%res['ObjV'][0][0])
print('最佳路线为:')
best_journey=np.hstack([0, res['Vars'][0, :], 0])
foriinrange(len(best_journey)):
print(int(best_journey[i]), end=' ')
print()
# 绘图plt.figure()
plt.plot(problem.places[best_journey.astype(int), 0], problem.places[best_journey.astype(int), 1], c='black')
plt.plot(problem.places[best_journey.astype(int), 0], problem.places[best_journey.astype(int), 1], 'o',
c='black')
foriinrange(len(best_journey)):
plt.text(problem.places[int(best_journey[i]), 0], problem.places[int(best_journey[i]), 1],
chr(int(best_journey[i]) +65), fontsize=20)
plt.grid(True)
plt.xlabel('x')
plt.ylabel('y')
plt.savefig('roadmap.svg', dpi=600, bbox_inches='tight')
plt.show()
else:
print('没找到可行解。')

用遗传算法聚类

geatpy也可以解决聚类问题。

"""该案例展示了如何利用进化算法进行仿k-means聚类(可称之为EA-KMeans算法)。问题的定义详见MyProblem.py。本案例采用与k-means类似的聚类方法,采用展开的聚类中心点坐标作为染色体的编码,基本流程大致如下:1) 初始化种群染色体。2) 迭代进化(循环第3步至第6步),直到满足终止条件。3) 重组变异,然后根据得到的新染色体计算出对应的聚类中心点。4) 计算各数据点到聚类中心点的欧式距离。5) 把与各中心点关联的数据点的坐标平均值作为新的中心点,并以此更新种群的染色体。6) 把各中心点到与其关联的数据点之间的距离之和作为待优化的目标函数值。注意:导入的数据是以列为特征的,即每一列代表一个特征(如第一列代表x,第二列代表y......)。"""importmatplotlib.pyplotaspltimportnumpyasnpimportgeatpyaseaclassMyProblem(ea.Problem):  # 继承Problem父类def__init__(self):
# 目标函数计算中用到的一些数据self.datas=np.loadtxt('data.csv', delimiter=',')  # 读取数据self.k=4# 分类数目# 问题类设置name='MyProblem'# 初始化name(函数名称,可以随意设置)M=1# 初始化M(目标维数)maxormins= [1]  # 初始化maxormins(目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标)Dim=self.datas.shape[1] *self.k# 初始化DimvarTypes= [0] *Dim# 初始化varTypes(决策变量的类型,元素为0表示对应的变量是连续的;1表示是离散的)lb=list(np.min(self.datas, 0)) *self.k# 决策变量下界ub=list(np.max(self.datas, 0)) *self.k# 决策变量上界lbin= [1] *Dim# 决策变量下边界(0表示不包含该变量的下边界,1表示包含)ubin= [1] *Dim# 决策变量上边界(0表示不包含该变量的上边界,1表示包含)# 调用父类构造方法完成实例化ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin)
defaimFunc(self, pop):  # 目标函数centers=pop.Phen.reshape(int(pop.sizes*self.k), int(pop.Phen.shape[1] /self.k))  # 得到聚类中心dis=ea.cdist(centers, self.datas, 'euclidean')  # 计算距离dis_split=dis.reshape(pop.sizes, self.k, self.datas.shape[0])  # 分割距离矩阵,把各个聚类中心到各个点之间的距离的数据分开labels=np.argmin(dis_split, 1)[0]  # 得到聚类标签值uni_labels=np.unique(labels)
foriinrange(len(uni_labels)):
centers[uni_labels[i], :] =np.mean(self.datas[np.where(labels==uni_labels[i])[0], :], 0)
# 直接修改染色体为已知的更优值,加快收敛pop.Chrom=centers.reshape(pop.sizes, self.k*centers.shape[1])
pop.Phen=pop.decoding()  # 染色体解码(要同步修改Phen,否则后面会导致数据不一致)dis=ea.cdist(centers, self.datas, 'euclidean')
dis_split=dis.reshape(pop.sizes, self.k, self.datas.shape[0])
pop.ObjV=np.sum(np.min(dis_split, 1), 1, keepdims=True)  # 计算个体的目标函数值defdraw(self, centers):  # 绘制聚类效果图dis=ea.cdist(centers, self.datas, 'euclidean')
dis_split=dis.reshape(1, self.k, self.datas.shape[0])
labels=np.argmin(dis_split, 1)[0]
colors= ['r', 'g', 'b', 'y']
fig=plt.figure()
ax=fig.add_subplot(111, projection='3d')
foriinrange(self.k):
idx=np.where(labels==i)[0]  # 找到同一类的点的下标datas=self.datas[idx, :]
ax.scatter(datas[:, 0], datas[:, 1], datas[:, 2], c=colors[i])
if__name__=='__main__':
# 实例化问题对象problem=MyProblem()
# 构建算法algorithm=ea.soea_DE_rand_1_bin_templet(problem,
ea.Population(Encoding='RI', NIND=10),
MAXGEN=20,  # 最大进化代数。logTras=5,  # 表示每隔多少代记录一次日志信息,0表示不记录。trappedValue=1e-4,  # 单目标优化陷入停滞的判断阈值。maxTrappedCount=20)  # 进化停滞计数器最大上限值。# 求解res=ea.optimize(algorithm, verbose=True, drawing=1, outputMsg=True, drawLog=False, saveFlag=True)
# 检验结果ifres['success']:
print('最优的聚类中心为:')
Vars=res['Vars'][0, :]
centers=Vars.reshape(problem.k, int(len(Vars) /problem.k))  # 得到最优的聚类中心print(centers)
"""=================================检验结果==============================="""problem.draw(centers)

以上都是geapty官方的案例,其还可以实现多目标优化、并行计算等功能,感兴趣的可去其官网查看相关文档。

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
机器学习/深度学习 自然语言处理 算法
|
21天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
数据结构与算法系列学习之串的定义和基本操作、串的储存结构、基本操作的实现、朴素模式匹配算法、KMP算法等代码举例及图解说明;【含常见的报错问题及其对应的解决方法】你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
|
21天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习(8)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
21天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
21天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
21天前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
21天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
21天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
21天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构的基本概念;算法的基本概念、特性以及时间复杂度、空间复杂度等举例说明;【含常见的报错问题及其对应的解决方法】
|
1月前
|
算法 API 计算机视觉
人脸识别笔记(一):通过yuface调包(参数量54K更快更小更准的算法) 来实现人脸识别
本文介绍了YuNet系列人脸检测算法的优化和使用,包括YuNet-s和YuNet-n,以及通过yuface库和onnx在不同场景下实现人脸检测的方法。
39 1