python多目标优化工具包_Python遗传算法框架使用实例(二)多目标优化问题Geatpy for Python与Matlab的对比学习...

在前面几篇文章中,我们已经介绍了高性能Python遗传和进化算法框架——Geatpy的使用及一些案例。

详细的Geatpy官方教程文档在github可以查看:

也可以到官网上查看:

本篇就一个多目标优化实例进行展开讲述,并且与使用Matlab工具箱得到相近效果进行一些对比:

(注意:Geatpy已于2018.10.18更新至1.1.0版本,这是一个内核更新,新版本提供了一个新的数据结构:LegV,用于保存种群个体的可行性,即标记了哪些是可行解哪些是非可行解。并给出了求解约束优化问题两大基本方法。在多目标优化上,提供了新的内核函数redisNDSet,用于计算帕累托最优解集的拥挤距离,使得帕累托前沿点分布更加均匀。在单目标优化上,提供了新的内核函数sgaplot,可以绘制进化过程中的动态图)。因此需要执行以下命令更新:

pip install --upgrade geatpy

若在更新过程中遇到”utf8 decode”错误的问题,是windows下用pip进行安装时遇到的常见问题之一解决方法有很多。可以以管理员方式运行cmd并进行更新。

下面对一个两个目标的最小化问题进行求解:

先用Geatpy尝试求解,直接套用内置的nsga2_templet进化算法模板:

# -*- coding: utf-8 -*-

"""main.py"""

import numpy as np

import geatpy as ga

# 注意:不建议把目标函数放在执行脚本内,建议放在另一个文件中

def aimfuc(x,LegV): # 定义目标函数

x1 = x[:, 0]; x2 = x[:, 1]

fun1 = x1**4-10*x1**2+x1*x2+x2**4-x1**2*x2**2

fun2 = x2**4-x1**2*x2**2+x1**4+x1*x2

return [np.vstack([fun1, fun2]).T ,LegV] # 对矩阵进行转置使得目标函数矩阵符合Geatpy数据结构

if __name__ == "__main__":

AIM_M = __import__('main') # 获取函数接口所在文件的地址

# 变量设置

ranges = np.array([[-5, -5], [5, 5]]) # 生成自变量的范围矩阵

borders = np.array([[1, 1], [1, 1]]) # 生成自变量的边界矩阵(1表示变量的区间是闭区间)

precisions = [1, 1] # 根据crtfld的函数特性,这里需要设置精度为任意正值,否则在生成区域描述器时会默认为整数编码,并对变量范围作出一定调整

FieldDR = ga.crtfld(ranges, borders, precisions) # 生成区域描述器

# 调用编程模板

[ObjV, NDSet, NDSetObjV, times] = ga.moea_nsga2_templet(AIM_M, 'aimfuc', None, None, FieldDR, problem='R', maxormin = 1, MAXGEN = 500, MAXSIZE = 200, NIND = 25, SUBPOP = 1, GGAP = 1, selectStyle = 'tour', recombinStyle = 'xovdp', recopt = 0.9, pm = 0.6, distribute = True, drawing = 1)

执行结果:

这里设置了MAXSIZE为200,表示当搜索到的帕累托前沿点超过200个时就不再增长,而在后续的进化中算法执行的是让帕累托前沿点的分布性得到进一步提高。设置进化最大代数为1000,种群规模为25。实际上Geatpy的nsga2算法模板不需要很大的种群规模就可以搜索到很大规模的帕累托前沿点。并且,由于nsga2算法是将父子两代合并进行进化选择的,因此变异概率可以设置大一些,不会对影响算法的收敛性产生太大影响。

problem = ‘R’是moea_nsga2_templet算法模板的一个输入参数,表示当前问题是一个连续性问题;假若研究离散性问题,那么problem = ‘I’。maxormin也是一个输入参数,其值为1表示当前是最小化目标;若改成-1,则表示这是一个最大化目标的优化问题。最后的drawing = 1表示只输出最后结果的图片;若设为0,表示不进行绘图;若设为2,程序将绘制帕累托非支配解集的搜索过程的动画。

nsga2的算法模板源代码可以参见:

下面将用Matlab的遗传算法工具箱进行对比实验:

clc,clear

% 定义目标函数

fun1 = @(x) x(1)^4-10*x(1)^2+x(1)*x(2)+x(2)^4-x(1)^2*x(2)^2; %min f1(x1,x2)

fun2 = @(x) x(2)^4-x(1)^2*x(2)^2+x(1)^4+x(1)*x(2); %min f2(x1,x2)

aimfuc = @(x) [fun1(x) fun2(x)]; %获取目标函数句柄

nvars=2; %变量个数

lb=[-5,-5]; %下限

ub=[5,5]; %上限

A=[];b=[]; %线性不等式约束

Aeq=[];beq=[];%线性等式约束

tic %开始计时

options=gaoptimset('paretoFraction',1,'populationsize',200,'generations',1000,'stallGenLimit',200,'TolFun',1e-100);

[x,fval] = gamultiobj(aimfuc,nvars,A,b,Aeq,beq,lb,ub,options);

time = toc %结束计时

plot(fval(:,1),fval(:,2),'k.') %绘图

fprintf('找到的前沿点数: %d\n', size(fval,1));

fprintf('平均每秒找到的前沿点数: %f\n', size(fval,1)/time);

执行结果如下:

对比发现Geatpy的效率比Matlab高出不少。尝试增大所需要搜索的帕累托前沿点的数量,Matlab变慢了一个数量级,而Geatpy的耗时基本稳定。

在Matlab的遗传算法工具箱中,是通过种群规模和”paretoFraction”的参数来控制帕累托最优解的数量的。当需要搜索大量的帕累托最优解时,Matlab的遗传算法工具箱就会变得极慢。这是因为种群规模太大的缘故。而Geatpy很好地解决了这个问题。Geatpy的许多进化算法模板都是采用一个全局帕累托最优解集来指导搜索过程的,种群规模不会因需要搜索更多的解而爆炸性增长。

Geatpy内核调用的是高性能mkl矩阵库,因此执行速度极快。

除了nsga-II算法外,Geatpy还支持适应性权法重法(awGA)、随机权重法(rwGA)、基于快速非支配排序的多目标进化优化算法。相应的算法均整合在算法模板内,源代码参见:

仔细研究Geatpy的模板函数发现,这些内置的模板函数为了兼容多种情况,设置了较多的if语句去判定。因此,假如要达到更高的性能,可以模仿这些模板自定义一些新的模板。在前面的文章中我也初步谈到如何自定义进化算法模板。在下一篇,我将更加详细地讲解怎样实现基于网格化的多种群单目标进化优化,以及在含等式约束的优化问题中的应用:

欢迎继续跟进,感谢!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值