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

164 阅读1分钟

1 优化目标

  多目标优化的标准形式如下:

image.png

  一个示意如下:

image.png   
该优化问题包含两个目标,其中f1(x)f_1(x)为最小化,$$f_2(x)反之;两个不等式约束,以及两个变量。   注:该优化并不满足pymoo的输入要求,因为它不满足优化问题的标准形式。当然,该示意仅仅出于验证目的,并用于理解优化问题的设计过程与优化空间的映射。

2 Pareto最优解

f1f_1的最小值取于(0,0)(0,0) f2f_2取于(1,0)(1,0)。由于这两个函数均为二次,最优解则由两个最优值之间的直线确定。在意味着忽略约束时,所有的Pareto最优解满足:

x1(1,0),x2=0x_1\in(1,0), x_2=0 进一步,需要满足g1g_1时,有x1(0.1,0.9)x_1\in(0.1,0.9);满足g2g_2时,有x1(0.4,0.6)x_1\in(0.4,0.6)。这表明Pareto最优集合被给定为:

PS={(x1,x2)(0.1x10.4)(0.6x10.9)x2=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\}
Tn=BiTT+T_n = \bigcup B_i \in \mathcal{T}\setminus\mathcal{T}^+

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

  代码如下:

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()

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950

3 Pareto前沿

  Pareto前沿反应了多个最优解 (Pareto最优) 下优化目标的变化情况。由于x 2 = 0 x_2=0x2​=0,则f 1 ( x ) = 100 x 1 2 f_1(x)=100x_1^2f1​(x)=100x12​且f 2 ( x ) = − ( x 1 − 1 ) 2 f_2(x)=-(x_1-1)^2f2​(x)=−(x1​−1)2,最终f 1 f_1f1​与f 2 f_2f2​的关系为:
f 2 = ( f 1 100 − 1 ) 2 f_2 = \left(\sqrt{\frac{f_1}{100}}-1\right)^2f2​=(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()