Pymoo学习 (2):带约束的双目标优化问题

1 优化目标

  多目标优化的标准形式如下:
min ⁡ f m ( x ) m = 1 , … , M  s.t.  g j ( x ) ≤ 0 j = 1 , … , J h k ( x ) = 0 k = 1 , … , K x i L ≤ x i ≤ x i U i = 1 , … , N x ∈ Ω \begin{array}{lll} \min & f_{m}(x) & m=1, \ldots, M \\ \text { s.t. } & g_{j}(x) \leq 0 & j=1, \ldots, J \\ & h_{k}(x)=0 & k=1, \ldots, K \\ & x_{i}^{L} \leq x_{i} \leq x_{i}^{U} & i=1, \ldots, N \\ & x \in \Omega & \end{array} min s.t. fm(x)gj(x)0hk(x)=0xiLxixiUxΩm=1,,Mj=1,,Jk=1,,Ki=1,,N
  一个示意如下:
min ⁡ f 1 ( x ) = 100 ( x 1 2 + x 2 2 ) max ⁡ f 2 ( x ) = − ( x 1 − 1 ) 2 − x 2 2  s.t.  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{aligned} \min & f_{1}(x)=100\left(x_{1}^{2}+x_{2}^{2}\right) \\ \max & f_{2}(x)=-\left(x_{1}-1\right)^{2}-x_{2}^{2} \\ \text { s.t. } & g_{1}(x)=2\left(x_{1}-0.1\right)\left(x_{1}-0.9\right) \leq 0 \\ & g_{2}(x)=20\left(x_{1}-0.4\right)\left(x_{1}-0.6\right) \geq 0 \\ &-2 \leq x_{1} \leq 2 \\ &-2 \leq x_{2} \leq 2 \\ & x \in \mathbb{R} \end{aligned} minmax s.t. f1(x)=100(x12+x22)f2(x)=(x11)2x22g1(x)=2(x10.1)(x10.9)0g2(x)=20(x10.4)(x10.6)02x122x22xR  该优化问题包含两个目标,其中 f 1 ( x ) f_1(x) f1(x)为最小化, f 2 ( x ) f_2(x) f2(x)反之;两个不等式约束,以及两个变量。
  
  注:该优化并不满足pymoo的输入要求,因为它不满足优化问题的标准形式。当然,该示意仅仅出于验证目的,并用于理解优化问题的设计过程与优化空间的映射。

2 Pareto最优解

   f 1 f_1 f1的最小值取于 ( 0 , 0 ) (0,0) (0,0) f 2 f_2 f2取于 ( 1 , 0 ) (1,0) (1,0)。由于这两个函数均为二次,最优解则由两个最优值之间的直线确定。在意味着忽略约束时,所有的Pareto最优解满足:
x 1 ∈ ( 1 , 0 ) , x 2 = 0 x_1\in(1,0), x_2=0 x1(1,0),x2=0  进一步,需要满足 g 1 g_1 g1时,有 x 1 ∈ ( 0.1 , 0.9 ) x_1\in(0.1,0.9) x1(0.1,0.9);满足 g 2 g_2 g2时,有 x 1 ∈ ( 0.4 , 0.6 ) x_1\in(0.4,0.6) x1(0.4,0.6)。这表明Pareto最优集合被给定为:
P S = { ( x 1 , x 2 ) ∣ ( 0.1 ≤ x 1 ≤ 0.4 ) ∨ ( 0.6 ≤ x 1 ≤ 0.9 ) ∧ x 2 = 0 } PS=\{(x_1,x_2)|(0.1\leq x_1\leq0.4)\vee(0.6\leq x_1\leq0.9)\wedge x^2=0\} PS={(x1,x2)(0.1x10.4)(0.6x10.9)x2=0}
T n = ⋃ B i ∈ T ∖ T + T_n = \bigcup B_i \in \mathcal{T}\setminus\mathcal{T}^+ Tn=BiTT+

  接下来可视化 P S PS PS,即图中橙色线条:

  代码如下:

import numpy as np
import matplotlib.pyplot as plt

# 变量的搜索空间
X1, X2 = np.meshgrid(np.linspace(-2, 2, 500),
                     np.linspace(-2, 2, 500))
# 目标函数
F1 = X1 ** 2 + X2 ** 2
F2 = (X1 - 1) ** 2 + X2 ** 2

# 约束条件所在直线
G1 = 2 * (X1[0] - 0.1) * (X1[0] - 0.9)
G2 = 20 * (X1[0] - 0.4) * (X1[0] - 0.6)

# 图像大小
plt.figure(figsize=(7, 5))
# 确定等高线的数量和位置
levels = [0.02, 0.1, 0.25, 0.5, 0.8]
# 绘制
CS = plt.contour(X1, X2, F1, levels, colors='black', alpha=0.5)
# 添加当前等高线的标签
CS.collections[0].set_label("$f_1(x)$")

CS = plt.contour(X1, X2, F2, levels, linestyles="dashed", colors='black', alpha=0.5)
CS.collections[0].set_label("$f_2(x)$")

# 约束条件G1
plt.plot(X1[0], G1, linewidth=2.0, color="green", linestyle='dotted')
plt.plot(X1[0][G1 < 0], G1[G1 < 0], label="$g_1(x)$", linewidth=2.0, color="green")

# 约束条件G2
plt.plot(X1[0], G2, linewidth=2.0, color="blue", linestyle='dotted')
plt.plot(X1[0][X1[0] > 0.6], G2[X1[0] > 0.6], label="$g_2(x)$", linewidth=2.0, color="blue")
plt.plot(X1[0][X1[0] < 0.4], G2[X1[0] < 0.4], linewidth=2.0, color="blue")

# 绘制解
plt.plot(np.linspace(0.1, 0.4, 100), np.zeros(100), linewidth=3.0, color="orange")
plt.plot(np.linspace(0.6, 0.9, 100), np.zeros(100), linewidth=3.0, color="orange")

plt.xlim(-0.5, 1.5)
plt.ylim(-0.5, 1)
plt.xlabel("$x_1$")
plt.ylabel("$x_2$")

# 添加标签
plt.legend(loc='upper center', bbox_to_anchor=(0.5, 1.12), ncol=4, fancybox=True, shadow=False)

# 减少图片边缘空白
plt.tight_layout()
plt.show()

3 Pareto前沿

  Pareto前沿反应了多个最优解 (Pareto最优) 下优化目标的变化情况。由于 x 2 = 0 x_2=0 x2=0,则 f 1 ( x ) = 100 x 1 2 f_1(x)=100x_1^2 f1(x)=100x12 f 2 ( x ) = − ( x 1 − 1 ) 2 f_2(x)=-(x_1-1)^2 f2(x)=(x11)2,最终 f 1 f_1 f1 f 2 f_2 f2的关系为:
f 2 = ( f 1 100 − 1 ) 2 f_2 = \left(\sqrt{\frac{f_1}{100}}-1\right)^2 f2=(100f1 1)2  通过计算,有 f 1 ∈ [ 1..16 ] f_1\in[1..16] f1[1..16] f 2 ∈ [ 36..81 ] f_2\in[36..81] f2[36..81],则该公式的可视化如下:

  代码如下:

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(7, 5))

# 两个目标函数的关系函数
f2 = lambda f1: - ((f1 / 100) ** 0.5 - 1) ** 2
F1_a, F1_b = np.linspace(1, 16, 300), np.linspace(36, 81, 300)
F2_a, F2_b = f2(F1_a), f2(F1_b)


plt.plot(F1_a, F2_a, linewidth=2.0, color="green", label="Pareto-front")
plt.plot(F1_b, F2_b, linewidth=2.0, color="green")

plt.xlabel("$f_1$")
plt.ylabel("$f_2$")


plt.legend(loc='upper center', bbox_to_anchor=(0.5, 1.10), ncol=4, fancybox=True, shadow=False)
plt.tight_layout()
plt.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值