本文介绍了jMetalPy,一个基于Python的采用元启发技术的面向对象的多目标优化框架。在著名的jMetal框架的经验基础上开发了一个新的多目标优化软件平台,其目的不仅是在不同的编程语言中复制前者,而且还利用了Python的全部功能,包括其快速原型设计的设施和大量可用的数据处理、数据分析、数据可视化和高性能计算的库。因此,jMetalPy提供了一个解决多目标优化问题的环境,不仅关注传统的元启发式方法,还关注支持偏好衔接、受限和动态问题的技术,以及与从生成的结果中自动生成统计数据有关的丰富功能,以及由算法产生的帕累托前沿近似的实时和交互式可视化。我们包括一些用例来探索jMetalPy的主要功能并说明如何使用它。
jMetalPy: A Python framework for multi-objective optimization with metaheuristics
https://juejin.cn/post/7161453210815692808
多目标优化问题广泛存在于许多学科中[1,2],包括工程、经济、物流、运输或能源等等。它们的特点是有两个或更多相互冲突的目标函数,必须同时达到最大化或最小化,其最佳状态由一组被称为帕累托最优集的折衷方案组成。除了有几个目标外,其他因素也会使这一系列的优化问题特别难以用精确的技术来处理和解决,如欺骗性、外显性、NP-hard复杂性或高维度[3]。因此,处理复杂的多目标优化问题的最流行的技术是元启发式算法[4],这是一个非精确的算法系列,包括进化算法和群集智能方法(如蚁群优化或粒子群优化)。
点燃元启发式算法广泛采用的一个重要因素是软件工具的出现,使其在实际设置中的实施、执行和部署更加容易。在多目标优化的背景下,最被认可的框架之一是jMetal[5],这个项目始于2006年,此后一直在不断发展,包括在2015年从头开始的全面重新设计[6]。
在本文中,我们介绍了jMetalPy,一个用Python编写的新的多目标优化框架。我们开发jMetalPy的动机源于我们过去使用jMetal的经验,也源于如今Python已经成为一种非常突出的编程语言,具有大量有趣的功能。它可以通过其庞大的生态系统来实现快速的原型设计,包括数值和科学计算(NumPy[7],Scipy[8])、数据分析(Pandas)、机器学习(Scikit-learn[9])、可视化(Matplotlib[10],Plotly[11])、大规模处理(Dask[12],PySpark[13])等等。我们的目标不仅仅是用Python重写jMetal,而是主要关注Python可以帮助填补Java没有覆盖的空白的方面。特别是,我们对优化算法提供的结果分析、实时和交互式可视化、支持决策的偏好阐述以及解决受限和动态问题感兴趣。此外,由于Python可以被认为是一个更敏捷的编程环境,用于原型设计新的多目标求解器,jMetalPy还包含了一整套统计学意义测试和相关工具,以便在多目标元启发之间进行原则性的比较。
jMetalPy是由计算机科学工程师和科学家开发的,以支持元启发式多目标优化的研究,并利用所提供的算法来解决实际问题。
遵循与jMetal相同的开源理念,jMetalPy是在MIT许可下发布的。该项目正在持续开发中,其源代码托管在GitHub。
jMetalPy的主要特点总结如下。
-jMetalPy是用Python(3.6以上版本)实现的,其面向对象的架构使其具有灵活性和可扩展性。
-它提供了一套最先进的代表性多目标元启发法(包括NSGA-II [14], NSGA-III [15], GDE3 [16], SMPSO [17], OMOPSO [18], MOCell [19], IBEA [20], SPEA2 [21], HypE [22], MOEA/D-DE [23], MOEA/DRA [24])和用于基准测试的标准问题系列(ZDT [25], DTLZ [26], WFG [2] 和 LZ09 [27])。
-所包含的大多数算法都可以使用NSGA-II中应用的约束处理方法解决经典的基准约束问题。此外,最近的提议,如MOEA/D-IEpsilon算法和LIR-CMOP测试套件[28],也被包括在内。
-支持动态多目标优化,包括实现NSGA-II和SMPSO的动态版本,以及FDA[29]问题系列。
-还提供了基于参考点的偏好衔接算法,如SMPSO/RP[30]以及NSGA-II和GDE3的版本。
-它实现了多目标优化的质量指标,如Hypervolume[31]、Additive Epsilon[32]和Inverted Generational Distance[33]。
-它提供了可视化组件,在解决有两个目标(散点图)、三个目标(散点图3D)和多目标问题(平行坐标图和定制版的和弦图)时显示帕累托前沿的近似值。
-支持比较研究,包括大量的统计测试和工具(如非参数测试、事后检验、boxplots、CD plot),包括自动生成LATEX表格(平均值、标准差、中位数、四分位数范围)和不同格式的数字。
-jMetalPy可以和jMetal一起合作工作。后者可以用来运行算法和计算质量指标,而后处理的数据分析可以用jMetalPy进行。
-支持基于Apache Spark[34]和Dask[12]的并行计算。这包括一个评估器组件,它可以被生成的元启发式算法用来评估与Spark并行的解决方案(同步并行),以及一个基于Dask的NSGA-II的并行版本(异步并行)。
-支持性文件。一个网站3为开发者维护着用户手册和API规范。该网站还包含一系列的Jupyter笔记本4,其中有使用案例和实验及可视化的例子。
本文的目的是描述jMetalPy,并说明对解决多目标优化问题的元启发式方法感兴趣的社区成员可以如何使用它。为此,我们包括了一些基于NSGA-II的实现用例,以探索jMetalPy中考虑的主要变体,从标准版本(生成和稳定状态),到动态、基于参考点、并行和分布式的这种求解器。还描述了一个实验用例,以说明jMetalPy中包含的统计测试和可视化工具如何用于后处理和深入分析获得的结果。关于多目标优化的背景概念和正式定义,我们参考了我们以前在文献中的工作。[5].
本文的其余部分组织如下。在第2节中,对相关的算法软件平台进行了回顾,以使人们了解jMetalPy的主要区别和贡献的理由。第3节深入探讨了jMetalPy的架构和它的主要组成部分。第4节解释了一个实施的用例。第5节描述了可视化设施,而第6节解释了统计程序实验的使用案例。最后,第7节介绍了结论,并概述了在不久的将来计划开展的进一步相关工作。
在过去的二十年中,有许多专门用于实现多目标元启发式算法的软件框架被贡献给了社区,如用Java编写的ECJ[41]、EVA[42]、JCLEC-MO[43]、jMetal[5,6]、MOEA框架[44]和Opt4J[45];用C/C++开发的ParadisEO-MOEO[46]和PISA[47];以及用Matlab实现的PlatEMO[48]。它们都有一个共同点,就是包含了最新的代表性算法、基准问题和性能评估的质量指标。
正如介绍中提到的,科学界对用Python实现的软件框架的兴趣越来越大,因为这种语言提供了一个庞大的库生态系统,其中大部分是用于数据分析、数据处理和可视化。在谈到优化算法时,表1列出了一组有代表性的Python框架,根据它们的算法领域、维护状态、Python版本和许可,以及它们目前提供的特色变体、后处理设施和算法进行了分析。除了Inspyred框架之外,它们都是活跃的项目(即它们的公共源代码在过去六个月内至少更新过一次),并且只需一个简单的pip命令就可以开箱工作。所有这些框架都支持Python 3.x。
表1. 用Python编写的最流行的优化框架。
Name | Status | Python version | License | Parallel processing | Dynamic optimization | Constrained optimization | Decision making | Post-processing facilities | Algorithms |
---|---|---|---|---|---|---|---|---|---|
DEAP 1.2.2 [35] | Active | ≥2.7 | LGPL-3.0 | ✓ | ✓ | Statistics | GA, GP, CMA-ES, NSGA-II, SPEA2, MO-CMA-ES | ||
Geatpy 1.1.5 [36] | Active | ≥3.5 | MIT | GA, MOEA | |||||
Inspyred 1.0.1 [37] | Inactive | ≥2.6 | MIT | ✓ | GA, ES, PSO, ACO, SA, PAES, NSGA-II | ||||
PyGMO 2.10 [38] | Active | 3.x | GPL-3.0 | ✓ | ✓ | Visualization, statistics | GA, DE, PSO, SA, ABC, IHS, MC, CMA-ES, NSGA-II, MOEA/D | ||
Platypus 1.0.3 [39] | Active | 3.6 | GPL-3.0 | ✓ | ✓ | Visualization, statistics | CMA-ES, NSGA-II, NSGA-III, GDE3, IBEA, MOEA/D, OMOPSO, EpsMOEA, SPEA2 | ||
Pymoo 0.2.4 [40] | Active | 3.6 | Apache 2.0 | ✓ | Visualization, statistics | GA, DE, NSGA-II, NSGA-III, U-NSGA-III, reference point (R-NSGA-III) | |||
jMetalPy 1.5.0 | Active | ≥3.6 | MIT | ✓ | ✓ | ✓ | ✓ | Visualization, statistics | GA, EA, SPEA2, NSGA-II, NSGA-III, SMPSO, GDE3, OMOPSO, HypE, IBEA, MOCell MOEA/D-DE, MOEA/D-DRA,constrained (MOEA/D-IEpsilon) reference point (G-NSGA-II, SMPSO/RP, G-GDE3), dynamic (NSGA-II, SMPSO, GDE3) |
DEAP和Inspyred并不以多目标优化为中心,而且它们包含的已实现的算法数量较少。Pagmo/PyGMO、Platypus和Pymoo提供了更多的功能和算法变体,包括用于统计后处理和结果可视化的方法。特别是,Pagmo/PyGMO包含一些单目标/多目标算法的实现,包括混合变体,以及用于竞赛算法的统计方法、质量指标和健身景观分析。Platypus支持解决方案评估阶段的并行处理,而Pymoo则相当专注于提供基于参考点的偏好衔接方法。
我们在本文中提出的jMetalPy框架也是一个活跃的开源项目,它主要专注于多目标优化(尽管包括一些单目标算法),提供越来越多的算法和现代方法用于统计后处理和结果的可视化。它提供了算法的变体,有平行处理和基于参考点的偏好衔接的方法,以提供决策支持。此外,jMetalPy纳入了动态问题优化的算法和机制,这是其他相关框架所不具备的额外功能。这样一来,所提出的框架试图涵盖尽可能多的优化功能,以支持研究和工业界的实验和决策。除了这些功能,jMetalPy的一个重要设计目标是使代码易于理解(特别是算法的实现),易于重用和扩展,这在接下来的两节中有所说明。
jMetalPy的架构采用了面向对象的设计,使其具有灵活性和可扩展性(见图1)。核心类定义了jMetalPy的基本功能:一个算法通过使用一些操作者实体来解决一个问题,这些操作者实体操作一组解决方案对象。接下来我们将详细介绍这些类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WhNgAe6m-1667405784105)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fc4756ac3980442ea93e1a267cef1fcc~tplv-k3u1fbpfcp-watermark.image?)]
图1. jMetalPy的UML类图。
算法类包含一个解决方案的列表(即进化算法中的种群或群智能技术中的群)和一个实现通用元启发式行为的run()方法(为了简单起见,省略了代码的全部细节)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i0K3In6l-1667405784106)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8c9ec8b9818d439abb15f0dfd85bc513~tplv-k3u1fbpfcp-watermark.image?)]
在上面的代码中,我们注意到创建初始解集的步骤,它们的评估,以及算法的主循环,它执行了一些步骤,直到满足停止条件。算法的状态变量的初始化和每一步结束时的更新,分别在init_progress()
和update_progress()
方法中进行。为了允许在运行过程中交流算法的状态,我们采用了观察者模式
[49],因此任何算法都是一个可观察的实体,它向注册的观察者通知一些事先指定的信息(例如,当前的评估数、运行时间或当前的解决方案列表),通常在 update_progress()
方法中进行。通过这种方式,我们提供了一种结构化的方法,例如,实时显示当前的帕累托前沿近似值或将其存储在一个文件中。
一个问题的创建和评估,需要决策变量的数量、目标函数和约束条件。如果约束条件的数量大于0,则假定evaluate()
方法也会评估约束条件是否得到满足。问题的子类包括额外的信息,取决于假定的解决方案编码;因此,FloatProblem(用于数值优化)
或IntegerProblem(用于组合优化)
需要指定决策变量的下限和上限。
操作符,如Mutation, Crossover, 和 Selection,有一个execute(source)
方法,给定一个源对象,产生一个结果。变异对一个解决方案进行操作,并返回一个由修改原始解决方案产生的新的解决方案。相反,交叉操作者接收一个解决方案的列表(即父母),并产生另一个解决方案的列表(相应地,后代)。选择运算符通常接收一个解决方案的列表,并返回其中的一个或一个子列表。
解决方案类是jMetalPy中的一个关键组件,因为它被用来表示可用的解决方案编码,这些编码与问题类型和可用于解决该问题的运算符相关。每个解决方案都由一个变量列表、一个目标值列表和一组以键值对字典形式实现的属性组成。属性可以用来分配,例如,人口的解决方案的等级或约束的违反程度。根据变量的类型,我们有Solution的子类,如 FloatSolution
、IntegerSolution
、BinarySolution
或 PermutationSolution
。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CKdJLYXG-1667405784107)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7e2dadd3546a48cbad70a9c89afcbede~tplv-k3u1fbpfcp-watermark.image?)]
动态问题(DynamicProblem)类扩展了问题的方法,以查询问题是否有任何改变,并清除该状态。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BxsH5Okb-1667405784107)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e8a9c61adaae4604b72fcb1dd40ac2e4~tplv-k3u1fbpfcp-watermark.image?)]
值得一提的是,根据观察者模式
,动态问题也是一个观察者实体。其基本思想是,在jMetalPy中,假定动态问题的变化是由外部实体产生的,即问题被注册的可观察对象。
为了说明jMetalPy的基本用途,在这一节中,我们描述了著名的NSGA-II算法的实现[14],以及它的一些变体(稳态、动态、有偏好衔接、并行和分布式)。
NSGA-II是一种遗传算法,它是进化算法的一个子类。在jMetalPy中,我们为后者提供了一个抽象类,为前者提供了一个默认实现。进化算法是一种元启发式算法,其中step()方法包括应用一系列的选择、繁殖和替换方法,如下面的代码片段所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oXwYOf9W-1667405784109)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f95d9b9c8c7a493aa40b7c0f3fe448e4~tplv-k3u1fbpfcp-watermark.image?)]
在每一步,选择运算符被用来(第27行)从算法的解决方案列表(群体)中检索交配池。交配池中的解决方案被用于繁殖(第28行),从而产生一个新的解决方案列表,称为子代。这个后代群体的解决方案必须被评估(第29行),然后应用一个替换策略来更新群体(第30行)。我们可以看到,评估计数器分别在init_progress()(第23行)和update_progress(第32行)中被初始化和更新。
进化算法(EvolutionaryAlgorithm)类是非常通用的。我们提供了一个完整的遗传算法的实现,这是一种进化算法,其繁殖是由交叉和变异算子组合而成。接下来我们将部分地说明这个实现。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z316hDvf-1667405784110)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3c40bc7ba55f47f19adee9697e9715a2~tplv-k3u1fbpfcp-watermark.image?)]
这里有一些有趣的特点需要指出。
从已经实现的GeneticAlgorithm类出发,我们已经准备好实现标准的NSGA-II算法和一些变体,这些将在接下来的小节中描述。我们将报告在MacBook Pro上运行该算法解决ZDT1基准问题[25]的计算时间,MacOS Mojave,2.2 GHz Intel Core i7处理器(涡轮增压至3.4 GHz),16 GB 1600 MHz DDR3内存,Python 3.6.7。Anaconda。
NSGA-II是一种世代遗传算法,因此种群和子代种群的规模相同。它的主要特点是使用非支配性排序对种群中的解进行排序以促进收敛,以及使用拥挤距离密度估计器来促进多样性[14]。这些机制被应用于替换方法中,如以下片段所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VG3Hr8l5-1667405784111)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3da08870cf2c48b8a2628a34347f8b47~tplv-k3u1fbpfcp-watermark.image?)]
不需要更多的代码。为了配置和运行该算法,我们包括一些例子,如以下代码。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5yWGzOpN-1667405784112)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6ed5291b617e4c4cab1d27bd20725f12~tplv-k3u1fbpfcp-watermark.image?)]
这段代码描述了NSGA-II的标准配置,以解决ZDT1基准问题。请注意,我们可以定义一个优势比较器(第13行),默认情况下,它是NSGA-II标准实现中使用的一个。
如前所述,任何算法都是一个可观察的实体,所以观察者可以注册到它。在这段代码中,我们注册了一个进度条观察器(在终端显示一个指示算法进度的条形图)和一个可视化观察器(显示一个绘制当前种群的图,即当前帕累托前沿近似值)。图2是NSGA-II运行的屏幕截图。在我们的目标笔记本电脑上,NSGA-II的这种配置的计算时间约为9.2秒。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-suSXKXHy-1667405784112)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c32adacc6d1b45fba9fe6982404d7c98~tplv-k3u1fbpfcp-watermark.image?)]
图2. jMetalPy对ZDT1基准问题运行NSGA-II的截图,显示了进度和帕累托前沿近似值。
NSGA-II的稳态版本可以通过使用相同的代码进行配置,但只是将子代种群大小设置为1。与以前的研究报告[50]中的标准NSGA-II相比,该版本在产生的帕累托前沿近似方面产生了更好的性能,但代价是更高的计算时间,提高到了190秒。
在解决ZDT1基准问题时,这个版本的NSGA-II发现了一个帕累托前沿近似的例子,如图3-中心所示。正如文献所预期的那样,它与标准NSGA-II产生的近似值相比更胜一筹(图3-left)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8KN3jP3t-1667405784113)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/754954d701c84b2a95e77415d57189c2~tplv-k3u1fbpfcp-watermark.image?)]
图3. 用标准NSGA-II算法(左)、稳态版本(中)和G-NSGA-II(使用参考点[f1, f2] = [0.5, 0.5],以红色显示)求解ZDT1时的帕累托前沿近似值。(关于本图例中对颜色的解释,请读者参考本文的网络版)
jMetalPy中的NSGA-II实现可以很容易地扩展,以纳入一个偏好衔接方案。具体来说,我们开发了一个基于g-dominance的比较器,考虑到文献[51]中描述的g-dominance概念。[51],其中感兴趣的区域可以通过定义一个参考点来划定。如果我们希望将搜索集中在参考点划定的兴趣区域,例如[f1, f2] = [0.5, 0.5],我们可以将NSGA-II与该比较器配置如下。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YjqD8CD5-1667405784113)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e27b8f02046242ae9d0df7e4e6296f29~tplv-k3u1fbpfcp-watermark.image?)]
如上所示,在每个迭代结束时,将对问题的变化进行检查。如果发生了变化,就会调用重启方法,根据实施的策略,重启方法将从群体中移除一些解决方案,并创建新的解决方案来取代它们。由此产生的群体将被评估,问题对象的clear_changed()方法将被调用。与标准的NSGA-II不同,停止条件方法的调用并不是为了停止算法,而是为了通知注册的观察者(例如,一个可视化工具),新的结果群体已经产生。然后,算法通过调用restart()和init_progress()方法再次启动。值得注意的是,原始NSGA-II实现的大部分代码被重新使用,只有一些方法需要重写。
为了说明动态问题的实现,我们接下来展示FDA抽象类的代码,它是构成FDA基准的五个问题的基类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-psuBO1ZX-1667405784113)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d7024b8c223b4b02835e6073becdbc08~tplv-k3u1fbpfcp-watermark.image?)]
这个类的关键点是update()方法,当它被一个可观察的实体(例如前面提到的TimeCounter类的一个实例)调用时,将problem_modified标志设置为True。我们可以观察到,这个标志可以被查询和重置。
接下来介绍的代码显示了如何配置和运行动态NSGA-II算法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-drSVXoY4-1667405784114)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1e56cbbac05c4f53996543c424f6a31f~tplv-k3u1fbpfcp-watermark.image?)]
在创建了FDA2基准问题[29]和时间计数器类的实例后,前者被注册在后者中,后者在一个并发的线程中运行。动态NSGA-II设置了停止条件,每25,000次函数评估返回一个帕累托前沿近似值。图4显示了动态NSGA-II算法在解决FDA2问题时的运行实例。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-axgumvi8-1667405784114)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/212ae1e2fc0645dbae5495c7a15a8d55~tplv-k3u1fbpfcp-watermark.image?)]
图4. 用NSGA-II的动态版本解决动态FDA2问题时的帕累托前沿近似值。
为了评估一个群体,NSGA-II(以及一般来说,jMetalPy中的任何生成算法)可以使用一个评估器对象。默认的评估器以顺序方式运行,但如果问题的评估方法是线程安全的,则可以对解决方案进行并行评估。jMetalPy包括一个基于Apache Spark的评估器,因此解决方案可以按照文献[52]中提出的方案在各种并行系统(多核、集群)中进行评估。[52]. 这个评估器可以被用来作为下一步的例子。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xa7boEia-1667405784114)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0e73f79116484ea0bde762f96f38c1f0~tplv-k3u1fbpfcp-watermark.image?)]
由此产生的并行NSGA-II算法结合了并行和顺序阶段,因此不能期望速度的提高是线性的。在我们的目标笔记本电脑上进行的试点测试表明,提速系数在2.7左右。然而,这里值得注意的是,NSGA-II不需要任何改变,它的行为与顺序版本相同,所以获得的时间减少是免费的。
本文介绍的NSGA-II的最后一个变体是基于用Dask[12]实现的异步并行模型的分布式版本,Dask是一个并行和分布式的Python系统,包括一套广泛的并行编程模型,包括使用期货的异步并行性。
分布式NSGA-II采用了文献[50]中研究的一种并行方案。[50]. 该方案基于稳态NSGA-II和Dask的期货的使用,其方式是每当需要评估一个新的解决方案时,就会创建一个任务并提交给Dask,后者会返回一个期货。当一个任务完成后,其相应的未来会返回一个已评估的解决方案,并将其插入子代群体。然后,在执行替换、选择和繁殖阶段后,会产生一个新的解决方案,再次被送去进行评估。这样一来,目标集群的所有处理器/处理器在大部分时间内都会很忙。
在我们的目标多核笔记本电脑上的初步结果表明,在进行模拟的系统的8个核心中,可以获得大约5.45的速度提升。我们将在下一小节中讨论这种缺乏可扩展性的问题和这个用例的其他方面。
在本节中,我们介绍了NSGA-II的五个不同版本,其中大部分(除了分布式变体)需要对实现NSGA-II的基类进行小的改动。并非所有的算法都能以同样的方式进行调整,但NSGA-II的一些变体可以以一种直接的方式实现。因此,我们在jMetalPy中包含了一些动态的、基于偏好的和并行的算法的例子,如SMPSO、GDE3和OMOPSO。
我们想再次强调代码的可读性,凭借这些代码,算法的所有步骤都可以被清楚地识别出来。一些用户可能会觉得进化算法→遗传算法→NSGAII的类层次结构很繁琐,他们更喜欢将NSGA-II的所有代码放在一个类中。然而,这种替代性的设计方法会阻碍当前实现的灵活性,并且在开发算法变体时需要复制大部分的代码。
就并行算法而言,详尽的性能评估已经超出了本文的范围。由于用于进行实验的笔记本电脑处理器的Turbo Boost功能,报告的速度并不显著,但它们给出了一个概念,即在使用现代多核计算机时可以实现时间的减少。
使用Python(而不是Java)的一个优势是它的可视化功能,这要归功于图形绘制库的可用性,如Matplotlib或Plotly。
jMetalPy利用这些库,包括三种类型的可视化图表:静态、互动和流式。表2总结了这些实现方式。静态图表可以显示在屏幕上,存储在文件中,或包含在Jupyter笔记本中(通常在一个算法的执行结束时使用)。同样,交互式图表是在算法返回帕累托前沿近似值时生成的,但与静态图表不同,用户可以交互式地操作它们。有两种交互式图表:一种是产生一个包括图表的HTML页面(允许应用诸如缩放、选择图表的一部分或点击某个点以查看其目标值等操作),另一种是诸如和弦图的图表,允许将鼠标悬停在图表上并可视化目标值之间的关系。最后,在算法的执行过程中,流式图表实时地描述了图表(它们也可以包含在Jupyter笔记本中);这对于观察算法产生的当前帕累托前沿近似值的演变是非常有用的。
表2. jMetalPy中包含的主要可视化内容。
Name | Type | Backend | Description |
---|---|---|---|
Plot | Static | Matplotlib | 2D, 3D, p-coords |
Interactive | Plotly | 2D, 3D, p-coords | |
Streaming plot | Streaming | Matplotlib | 2D, 3D |
Chord plot | Interactive | Matplotlib | For statistical purposes |
Box plot | Interactive | Matplotlib | For statistical purposes |
CD plot | Static | Matplotlib | Demsar’s critical distance plot |
Posterior plot | Static | Matplotlib | Bayesian posterior analysis |
图5显示了三个基于Plotly的交互式绘图的例子。目标问题是DTLZ1[26],当问题被定义为2、3和5个目标时,用SMPSO算法解决。对于任何有3个以上目标的问题,都会生成一个平行坐标图。图6显示了一个有5个目标的问题的和弦图的例子;每个描述的和弦都代表了获得的帕累托前沿的一个解决方案,并将其目标值联系在一起。当悬停在某个目标fi的扇形框上时,该图只显示那些fi值落在由扇形框的极值划定的该目标的价值支持范围内的解决方案。最后,图表的外部分割环代表了每个目标在获得的帕累托前沿中所涵盖的值的柱状图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gde5Th1s-1667405784114)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c582be6043024928a46c513702328531~tplv-k3u1fbpfcp-watermark.image?)]
图5. 使用SMPSO解决DTLZ1问题时产生的交互图的例子,其中有2个(顶部),3个(中间)和5个(底部)目标。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-40uU9KLF-1667405784115)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/57208a0da9b84322ab0739dd3f8b11fd~tplv-k3u1fbpfcp-watermark.image?)]
图6. 当解决一个有5个目标的问题时,SMPSO得到的正面和弦图的例子。
在前几节中,我们展示了jMetalPy中的一些元启发式算法所产生的帕累托前沿近似的例子。在这一节中,我们描述了我们的框架如何被用来进行严格的实验研究,基于对一些算法的比较来确定哪种算法呈现出最佳的整体性能。
实验比较需要一些步骤。
确定要比较的算法和要使用的基准问题。
对每个算法-问题配置进行若干次独立运行,并得到产生的前沿。
将质量指标应用于前沿(例如,Hypervolume、Epsilon等)。
应用一些统计测试来评估基准中所考虑的算法之间的性能差异的统计学意义。
前三个步骤可以用jMetalPy完成,也可以用jMetal甚至是手动完成(比如用脚本运行算法)。jMetalPy脱颖而出的一点是第四步,因为它包含了大量的统计功能,为用户提供了一套广泛的工具来分析比较研究产生的结果。所有这些功能都是从头开始编程的,并嵌入到jMetalPy的核心。具体来说,jMetalPy中包含的统计测试如下。
一套多样化的非参数空假设显著性检验,即Wilcoxon秩和检验、Sign检验、Friedman检验、Friedman排列秩检验和Quade检验。这些测试在传统上被社区使用,通过检查从其分数中计算出的统计量来阐明其比较性能。
贝叶斯检验(符号检验和签名等级检验),最近被认为是为了克服性能评估中无效假设重要性检验的缺点[53]。这些测试由巴里中心坐标的后验图来补充,以比较贝叶斯方法下的一对算法,同时也考虑到可能的统计联系。
用于比较多种算法的事后检验,可以是单对单(Bonferroni-Dunn, Holland, Finner, and Hochberg)或全对全(Li, Holm, Shaffer)。
这些测试的结果默认显示在屏幕上,其中大部分可以导出为LATEX表格。此外,还可以生成boxplot图。最后,包含均值和中位数(以及它们分别对应的标准差和四分位数范围内的分散度量)的LATEX表格会自动生成。
jMetalPy有一个实验室模块,包含用于定义实验的工具,它需要三个列表:要比较的算法(必须正确配置),要解决的基准问题,以及用于性能评估的质量指标。其他参数是独立运行的数量和输出目录。
一旦实验被执行,就会产生一个CSV文件形式的总结。这个文件包含了每个配置和运行的质量指标值的所有信息。该文件的每一行都有以下模式。算法、问题、指标、ExecutionId、指标值。其内容的一个例子如下。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-blxA8IdR-1667405784115)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ef458b6f40ce4f42833c489800e8c20a~tplv-k3u1fbpfcp-watermark.image?)]
在这里,我们可以看到带有列名的标题,接着是四行,对应的是NSGA-II算法在解决ZDT1问题时的三次运行的Epsilon指标值。文件的末尾显示了解决ZDT6问题时MOCell三次运行的IGD+指标值。该文件包含的行数与算法、问题、质量指标和独立运行数的乘积相同。
该摘要文件是所有统计测试的输入,因此它们可以应用于任何具有适当格式的有效文件。这对于结合jMetal和jMetalPy来说特别有意思。jMetal的最后几个版本在实验研究中运行一组算法后会生成一个摘要文件,所以这时我们可以利用jMetal(提供许多算法和基准问题,与Python相比,Java的执行速度更快)和jMetalPy(对数据分析和可视化的更好支持)的特点。我们在下一节中详细介绍结合这两个框架的例子。
让我们考虑以下案例研究。我们有兴趣评估五种元启发式方法(GDE3、MOCell、MOEA/D、NSGA-II和SMPSO)在解决ZDT系列连续问题(ZDT1-4、ZDT6)时的表现。要计算的质量指标被设定为加法Epsilon(EP)、Spread(SPREAD)和Hypervolume(HV),它们分别给出了收敛性、多样性和这两种特性的测量。每种算法的独立运行数量被设定为25。
我们在jMetal中用这些信息配置一个实验,在运行算法和应用质量指标后,得到了摘要文件。然后,通过将该文件作为jMetalPy统计分析模块的输入,我们得到一组LATEX文件和输出目录中的数字,以及屏幕上显示的信息。接下来我们分析一下获得的结果。
表3、表4、表5显示了三个选定质量指标的中位数和四分位数范围。为了便于分析这些表格,一些单元格的背景是灰色的。使用两种灰色水平,即深色和浅色,分别突出产生最佳和次佳指标值的算法(注意,这是由jMetalPy自动执行的)。从表中我们可以看到,SMPSO是总体表现最好的算法,在四个问题中取得了最佳指标值,并取得了1个s最佳值。
Table 3. Median and Interquartile Range of the EP quality indicator.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CzJvRo7Y-1667405784116)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9a565bdb63c643a3a18837bb6af4a02f~tplv-k3u1fbpfcp-zoom-1.image)]
Table 4. Median and Interquartile Range of the SPREAD quality indicator.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ggYH8x0y-1667405784117)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/814907bb80ee4b60bd64d12ab1872869~tplv-k3u1fbpfcp-zoom-1.image)]
Table 5. Median and Interquartile Range of the HV quality indicator.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lREsz8Iw-1667405784117)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/01fd3fa0cd62469bbec1f8e05cddb068~tplv-k3u1fbpfcp-zoom-1.image)]
然而,众所周知,只考虑算法排名的中值并不能确保其差异具有统计学意义。如果我们打算在全球范围内考虑所有的问题,对算法性能进行排名,也需要统计学上的排名。最后,在涉及大量问题的研究中(为了简单起见,我们只用了五个问题),中位数的视觉分析可能非常复杂,所以需要收集所有信息的统计图。这就是为什么jMetalPy还可以生成第二套LATEX表格,以视觉直观的方式汇编所有算法在某一质量指标上运行的非参数空假设显著性测试的结果。表6、表7、表8是这些表格的三个例子,分别是在EP、SPREAD和HV指标的每一对算法之间使用Wilcoxon秩和检验(在5%的显著性水平上)计算的。在每个单元格中,5个数据集的结果用三个符号表示:如果单元格的行和列所代表的算法之间没有统计学意义;▿如果标记列的方法在统计学上优于行的算法;以及▴如果行的算法明显优于列的方法。
表6. EP质量指标的Wilcoxon值(ZDT1、ZDT2、ZDT3、ZDT4、ZDT6)。
Empty Cell | SMPSO | MOEAD | GDE3 | MOCell |
---|---|---|---|---|
NSGAII | ▴ ▴ ▴ ▴ ▴ | ▿ ▿ ▿ ▿ ▴ | – – ▴ ▿ ▴ | ▴ ▴ ▴ ▴ ▴ |
SMPSO | ▿ ▿ ▿ ▿ ▿ | ▿ ▿ ▿ ▿ ▿ | ▿ ▿ – ▿ ▿ | |
MOEAD | ▴ ▴ ▴ ▿ ▿ | ▴ ▴ ▴ ▴ ▿ | ||
GDE3 | ▴ ▴ ▴ ▴ ▴ |
表7. SPREAD质量指标的Wilcoxon值(ZDT1, ZDT2, ZDT3, ZDT4, ZDT6)。
Empty Cell | SMPSO | MOEAD | GDE3 | MOCell |
---|---|---|---|---|
NSGAII | ▴ ▴ ▴ ▴ ▴ | ▿ ▴ ▿ ▿ ▴ | – ▴ ▴ ▿ ▿ | ▴ ▴ ▴ ▴ ▴ |
SMPSO | ▿ ▿ ▿ ▿ ▿ | ▿ ▿ ▿ ▿ ▿ | – ▿ ▴ ▿ ▿ | |
MOEAD | ▴ ▿ ▴ ▴ ▿ | ▴ ▴ ▴ ▴ ▴ | ||
GDE3 | ▴ ▴ ▴ ▴ ▴ |
表8. HV质量指标的Wilcoxon值(ZDT1, ZDT2, ZDT3, ZDT4, ZDT6)。
Empty Cell | SMPSO | MOEAD | GDE3 | MOCell |
---|---|---|---|---|
NSGAII | ▿ ▿ ▿ ▿ ▿ | ▴ ▴ ▴ ▴ ▿ | ▿ ▿ ▿ ▴ ▿ | ▿ ▿ – ▿ ▿ |
SMPSO | ▴ ▴ ▴ ▴ ▴ | ▴ ▴ – ▴ ▴ | ▴ ▴ ▴ ▴ ▴ | |
MOEAD | ▿ ▿ ▿ ▴ ▴ | ▿ ▿ ▿ ▿ ▴ | ||
GDE3 | ▿ ▿ ▴ ▿ – |
通过检查算法获得的质量指标值的分布,可以支持从上述表格中得出的结论。图7显示了在解决ZDT6问题时用jMetalPy通过Hypervolume值得到的boxplots。每当方框不相互重叠时,我们可以说应该有统计学上的信心,即性能差距是相关的(例如,SMPSO和其他算法之间),但当它们重叠时(正如我们在GDE3和MOCell中看到的),我们不能辨别哪种算法表现最好。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wq3CkQu6-1667405784118)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e67ea550b4064d58adf705b0bc5ed639~tplv-k3u1fbpfcp-watermark.image?)]
图7. ZDT6问题的HV指标的图示。
此前描述的列表和表格允许观察结果的分散性以及异常值的存在,但它们不允许对所有问题中算法的性能有一个全面的认识。这就促使我们在不同的问题实例上采用有原则的方法来比较多种技术,例如Demsar[54]在分类问题和机器学习模型方面提出的方法。如前所述,我们开发的框架包括临界距离(CD)图(图8,针对HV指标的计算)和后验图(图9,同样针对HV指标)。前者用于描述在所考虑的问题上计算出的算法的平均排名,因此图表中用粗线连接那些排名差异小于所谓临界距离的算法。这个临界距离是问题数量、被比较的技术数量和一个临界值的函数,这个临界值是由Studentized范围统计和一个指定的置信度产生的。如图8所示,SMPSO、MOCell、GDE3和NSGA-II在统计学上的表现相当,这与之前讨论的表组的结论相冲突,因为计算临界距离的统计数字相对更严格。在这种比较方法下,需要更多的问题来宣布统计学意义。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MJedU9iP-1667405784118)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cb4f00c271914837b6b69158da551247~tplv-k3u1fbpfcp-watermark.image?)]
图8. 高压指标的CD图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BsXnJWza-1667405784118)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/071eaa24a7ac4668966f19e44a848d47~tplv-k3u1fbpfcp-watermark.image?)]
图 9. 使用贝叶斯符号检验的HV指标的后验图。
𝜃𝑟≥max(𝜃𝑒,𝜃𝑙),
θr≥max(θe,θl),
最后,我们通过展示后验图来结束我们的实验用例,该图允许使用贝叶斯符号检验来比较一对算法(图9)。当依靠贝叶斯假设检验时,我们可以从可用的质量指标值直接评估假设的后验概率,这使得我们能够更直观地了解所考虑的算法的比较性能。此外,可以定义一个实际等值区域(也表示为绳索),以说明所考虑的多目标求解器之间的联系。图9中的图实质上是后验概率的一个arycentric投影:例如,图表右下方的区域划定了以下区域。
(1)
θr = P(z > r), θe = P(-r ≤ z ≤ r), θl = P(z < - r), 而z表示右边和左边算法的指标值之间的差异(按这个顺序)。基于这个符号,图中显示,在我们的案例中,对于r=0.002,在大多数情况下z=HV(NSGA-II)-HV(SMPSO)满足θl≥max(θe,θr),也就是说,平均来说,SMPSO的HV值比NSGA-II的更有可能。特别是这些概率可以通过计算落在三个区域中每一个区域的点的数量来估计,由此我们得出结论:在这个用例中,1)SMPSO实际上比NSGA-II好,概率为0.918;2)两种算法表现相当,概率为0.021;3)NSGA-II比SMPSO优越,概率为0.061。
在本文中,我们介绍了jMetalPy,一个基于Python的多目标优化与元启发式算法的框架。它是在MIT许可下发布的,并在GitHub上免费提供给社区。我们已经详细介绍了它的核心架构,并描述了NSGA-II及其一些变体的实现,作为如何使用该框架的说明性例子。
jMetalPy提供了对动态优化、并行性和决策的支持。其他突出的特点包括针对多目标和多目标问题的可视化(静态、流式和交互式图形),以及用于性能评估的一大套统计测试。值得注意的是,jMetalPy仍然是一个年轻的研究项目,其目的是为对元启发式多目标优化感兴趣的研究团体提供帮助。因此,预计它将快速发展,纳入开发团队和外部贡献者的新算法和问题。
未来工作的具体方向包括评估集群中的并行和分布式元启发式算法的性能,以及应用它们来解决新的现实世界问题。此外,我们计划通过包括不同的输入数据格式来开放jMetalPy的分析和可视化功能,以促进其他外部框架的使用。
鸣谢
这项工作得到了TIN2017-86049-R资助(西班牙教育和科学部)的部分资助。José García-Nieto是马拉加大学 "Captación de Talento para la Investigación "计划的博士后奖学金的获得者。Javier Del Ser和Izaskun Oregui接受巴斯克政府通过EMAITEK计划(西班牙)提供的资金支持。
参考文献