Pymoo:使用多目标优化搜索解集的实现方法

Pymoo:使用多目标优化搜索解集的实现方法

      • 一、优化问题的数学表述
      • 二、Pymoo中求解最优化问题的实现
        • 2.1 问题的实现
        • 2.2 初始化算法(基于NSGA2遗传算法为例)
        • 2.3 定义终止准则
        • 2.4 优化计算
        • 2.5 结果可视化

  • Github 仓库: Pymoo: 基于 Python 的多目标优化仓库 (MOO, Multi-objective Optimization)。
  • Pymoo文档首页:Multi-objective Optimization in Python

注意:本文使用Pymoo版本为0.6.0

一、优化问题的数学表述

本文实现了一个具有两个约束的双目标优化问题,其数学定义如下所示:

m i n i m i z e f 1 ( x ) = 100 ( x 1 2 + x 2 2 ) m a x i m i z e f 2 ( x ) = − ( x 1 − 1 ) 2 − x 2 2 s u b j e c t   t o g 1 ( x ) = 2 ( x 1 − 0.1 ) ( x 1 − 0.9 ) ≤ 0 g 2 ( x ) = 20 ( x 1 − 0.4 ) ( x 1 − 0.6 ) ≥ 0 − 2 ≤ x 1 ≤ 2 − 2 ≤ x 2 ≤ 2 x ∈ R \begin{equation} \begin{aligned} {\rm minimize} \enspace &f_1(x) = 100(x_1^2 + x_2^2) \\ {\rm maximize} \enspace &f_2(x) = -(x_1 - 1)^2 - x_2^2 \\ {\rm subject \, to} \enspace &g_1(x) = 2(x_1 - 0.1)(x_1 - 0.9) \leq 0 \\ &g_2(x) = 20(x_1 - 0.4)(x_1 - 0.6) \geq 0 \\ &-2 \leq x_1 \leq 2 \\ &-2 \leq x_2 \leq 2 \\ &x \in \R \end{aligned} \end{equation} minimizemaximizesubjecttof1(x)=100(x12+x22)f2(x)=(x11)2x22g1(x)=2(x10.1)(x10.9)0g2(x)=20(x10.4)(x10.6)02x122x22xR

上面的问题并不是最优化问题的规范模型,为了使用Pymoo进行问题的求解,我们需要首先进行规范化处理。

最优化问题定义:
对于大部分的最优化框架,我们需要将问题的目标函数规范化为统一的最小化或最大化问题,同时约束也需要规范化为 ≤ \leq ≥ \geq 的约束。在Pymoo中,每一个目标函数是规范化为最小化问题,约束需要规范化为 ≤ 0 \leq 0 0的约束。

对公式(1)进行规范化处理得到如下的规范化最优化数学表达式:

m i n i m i z e f 1 ( x ) = 100 ( x 1 2 + x 2 2 ) m i n i m i z e f 2 ( x ) = ( x 1 − 1 ) 2 + x 2 2 s u b j e c t   t o g 1 ( x ) = 2 ( x 1 − 0.1 ) ( x 1 − 0.9 ) ≤ 0 g 2 ( x ) = − 20 ( x 1 − 0.4 ) ( x 1 − 0.6 ) ≤ 0 − 2 ≤ x 1 ≤ 2 − 2 ≤ x 2 ≤ 2 x ∈ R \begin{equation} \begin{aligned} {\rm minimize} \enspace &f_1(x) = 100(x_1^2 + x_2^2) \\ {\rm minimize} \enspace &f_2(x) = (x_1 - 1)^2 + x_2^2 \\ {\rm subject \, to} \enspace &g_1(x) = 2(x_1 - 0.1)(x_1 - 0.9) \leq 0 \\ &g_2(x) = - 20(x_1 - 0.4)(x_1 - 0.6) \leq 0 \\ &-2 \leq x_1 \leq 2 \\ &-2 \leq x_2 \leq 2 \\ &x \in \R \end{aligned} \end{equation} minimizeminimizesubjecttof1(x)=100(x12+x22)f2(x)=(x11)2+x22g1(x)=2(x10.1)(x10.9)0g2(x)=20(x10.4)(x10.6)02x122x22xR

二、Pymoo中求解最优化问题的实现

使用Pymoo求解最优化问题通常包括如下几个步骤:

  • 问题的实现
  • 初始化算法
  • 定义终止准则
  • 优化计算
  • 结果可视化

2.1 问题的实现

这里使用element-wise问题定义方式来定义最优化问题(2)。在继承了Pymoo中ElementwiseProblem类的基础上,自定义最优化问题时我们需要设置一些相应的类属性如下所示:

  • n_var:自变量个数,本文设置为2
  • n_obj:目标个数,本文设置为2
  • n_ieq_constr:不等式约束函数个数,本文设置为2
  • xl/xu:自变量的上/下限。

优化算法的计算过程是由_evaluate函数实现,该函数包括两个接口xout,对于element-wise实现过程,它们功能如下所示:

  • x:长度为n_var的一维Numpy数组,它表示要求解问题的一个解;
  • out:字典格式数据,长度为n_obj的Numpy数组列表的目标值写入到out["F"]中,长度为n_ieq_constr的约束函数写入到out["G"]中。在Pymoo定义最优化问题(1)的代码如下所示:
import numpy as np
from pymoo.core.problem import ElementwiseProblem

class MyProblem(ElementwiseProblem):

		def __init__(self):
				super().__init__(
						n_var=2,
						n_obj=2,
						n_ieq_constr=2,
						xl=np.array([-2, -2]),
						xu=np.array([2, 2])
				)

		def _evaluate(self, x, out, *args, **kwargs):
				f1 = 100 * (x[0]**2 + x[1]**2)
				f2 = (x[0]-1)**2 + x[1]**2

				g1 = 2*(x[0]-0.1) * (x[0]-0.9) / 0.18
				g2 = - 20*(x[0]-0.4) * (x[0]-0.6) / 4.8

				out["F"] = [f1, f2]
				out["G"] = [g1, g2]

problem = MyProblem()

注意,对于ElementwiseProblem问题定义方法的说明:
ElementwiseProblem问题定义方法意味着为每一个解x调用一次_evaluate函数。

2.2 初始化算法(基于NSGA2遗传算法为例)

Pymoo中封装了很多现成的优化问题求解算法,这些算法都是基于面向对象的方法/因此,我们使用它们的时候必须实例化一个算法对象,这里以NSGA2遗传算法为例。

Pymoo中对于NSGA2方法提供了很多可配置参数,本文用到的遗传算法参数及其配置如下所示:

  • pop_size:种群规模,对于简单的问题设置为40
  • n_offsprings:每一代的后代个数,这里设置为10
  • sampling:抽样算子,本文设置为随机抽样方法;
  • crossover:交叉算子,本文选用模拟二元交叉(SBX, Simulate Binary Crossover);
  • mutation:突变算子,本文选用多项式突变方式
  • eliminate_duplicates:种群个体重复检测,这里设置为True

Pymoo中初始化NSGA2的代码如下所示:

from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.operators.crossover.sbx import SBX
from pymoo.operators.mutation.pm import PM
from pymoo.operators.sampling.rnd import FloatRandomSampling

algorithm = NSGA2(
		pop_size=40,
		n_offsprings=10,
		sampling=FloatRandomSampling(),
		crossover=SBX(prob=0.9, eta=15),
		mutation=PM(eta=20),
		eliminate_duplicates=True
)

注意,对于优化算法参数设置的说明:
Pymoo中有很多优化计算方法,它们都有自己的默认超参数。通常我们可以使用默认的超参数,但是当算法能取得良好的收敛性的时候,我们可以很方便的配置其超参数。但是,我们需要深入理解每个算法的实现原理,并能够熟练应用Pymoo的各个模块。

2.3 定义终止准则

常见的终止准则是限制函数的迭代次数。此外,一些算法还实现了自己的终止算法,比如,单纯形(simplex)退化时的Nelder Mead算法,或使用CMA-ES算法。本文是一个简单的问题,所以这里设置终止条件为40次算法迭代,代码如下所示:

from pymoo.termination import get_termination

termination = get_termination("n_gen", 40)

✨ **注意,算法收敛性分析(Convergence Analysis)的说明:**收敛性分析能够显示算法在某个时刻算法取得的多大的优化程度。

2.4 优化计算

此时就可以使用上面定义的算法与终止条件对问题进行优化了。默认情况下minimize方法对算法和终止对象进行深度复制,以确保它们在函数调用的过程中不会被修改。当算法终止时,minimize函数会返回一个Result对象,代码如下所示:

from pymoo.optimize import minimize

res = minimize(
		problem,
		algorithm,
		save_hastory=True,
		verbose=True
)

X = res.X		# 最优解集
F = res.F		# 最优解

2.5 结果可视化

  • 1、绘制设计空间(自变量空间)的最优集可视化
import matplotlib.pyplot as plt

# 获得自变量而区间
xl, xu = problem.bounds()

# 绘制结果
plt.figure(figsize=(7, 5))
# 绘制最优解集的散点图
plt.scatter(X[:, 0], X[:, 1], s=30, facecolors="none", edgecolors="orange")
# 设置x、y周现实区间
plt.xlim(xl[0], xu[0])
plt.ylim(xl[1], xu[1])
plt.title("Design Space")
plt.show()

代码执行结果如下图所示:

Pymoo:使用多目标优化搜索解集的实现方法_第1张图片
  • 2、目标空间的最优解可视化(Pareto前沿)可视化
plt.figure(figsize=(7, 5))
plt.scatter(F[:, 0], F[:, 1], s=30, facecolors='none', edgecolors='blue')
plt.title("Objective Space")
plt.show()

代码执行结果如下图所示:

Pymoo:使用多目标优化搜索解集的实现方法_第2张图片

你可能感兴趣的:(python,最优化,pymoo)