admin管理员组文章数量:1596326
文章目录
- 1 双目标优化
- 2 Python求解
- 2.1 初始化
- 2.2 终止条件
- 2.3 优化
- 2.4 可视化
- 3 完整代码
1 双目标优化
示意如下:
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)=−(x1−1)2−x22g1(x)=2(x1−0.1)(x1−0.9)≤0g2(x)=20(x1−0.4)(x1−0.6)≥0−2≤x1≤2−2≤x2≤2x∈R 首先需要将其转换为优化问题的标准形式:
1)
−
f
2
(
x
)
-f_2(x)
−f2(x)替换
f
2
(
x
)
f_2(x)
f2(x);
2)不等式约束均转换为
≤
0
\leq0
≤0的形式,即
−
g
2
(
x
)
≤
0
-g_2(x)\leq0
−g2(x)≤0;
3)标准化变量,使得其重要性等同,即
g
1
(
x
)
/
(
2
∗
(
−
0.1
)
∗
(
−
0.9
)
)
g_1(x)/(2*(-0.1)*(-0.9))
g1(x)/(2∗(−0.1)∗(−0.9)),
g
2
(
x
)
/
(
20
∗
(
−
0.4
)
∗
(
−
0.6
)
)
g_2(x)/(20*(-0.4)*(-0.6))
g2(x)/(20∗(−0.4)∗(−0.6))。转换结果如下:
min
f
1
(
x
)
=
100
(
x
1
2
+
x
2
2
)
min
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.18
≤
0
g
2
(
x
)
=
−
20
(
x
1
−
0.4
)
(
x
1
−
0.6
)
/
4.8
≤
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) \\ \min & 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)/0.18 \leq 0 \\ & g_{2}(x)=-20\left(x_{1}-0.4\right)\left(x_{1}-0.6\right)/4.8 \leq 0 \\ &-2 \leq x_{1} \leq 2 \\ &-2 \leq x_{2} \leq 2 \\ & x \in \mathbb{R} \end{aligned}
minmin s.t. f1(x)=100(x12+x22)f2(x)=(x1−1)2+x22g1(x)=2(x1−0.1)(x1−0.9)/0.18≤0g2(x)=−20(x1−0.4)(x1−0.6)/4.8≤0−2≤x1≤2−2≤x2≤2x∈R
2 Python求解
本小节使用element-wise求解,其是三种问题解决方案之一 :
import numpy as np
from pymoo.core.problem import ElementwiseProblem
class MyProblem(ElementwiseProblem):
def __init__(self):
super(MyProblem, self).__init__(
n_var=2, # 变量数量
n_obj=2, # 优化目标的数量
n_constr=2, # 约束的数量
xl=np.array([-2, -2]), # 变量的下限
xu=np.array([2, 2]) # 变量的上限
)
def _evaluate(self, x, out, *args, **kwargs):
"""
:param x: 1D向量,长度为n_var
:param out:
:param args:
:param kwargs:
:return:
"""
# 目标函数
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]
注:三种问题求解方式如下:
1)element-wise:每次为
x
x
x调用_evaluate;
2)vectorized:
x
x
x表示求解方案的集合;
3)functional:将每个目标和约束作为函数提供。
2.1 初始化
示意中的优化问题很简单,只有两个目标和两个约束,以下为使用著名多目标算法NSGA-II的初始化:
from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.factory import get_sampling, get_crossover, get_mutation
algorithm = NSGA2(
pop_size=40, # 种群数量
n_offsprings=10, # 后代数量
sampling=get_sampling("real_random"), # 采样的方式,如随机采样
crossover=get_crossover("real_sbx", prob=0.9, eta=15), # 交配方式,如模拟二进制
mutation=get_mutation("real_pm", eta=20), # 变异方式,多项式变异
eliminate_duplicates=True # 确保后代的目标值不同
)
2.2 终止条件
在优化之前需要定义终止条件。常见方法包括:
1)限制函数评估的总数;
2)限制算法的迭代次数;
3)定制:一些算法实现了自己的终止条件,例如单纯形退化时的Nelder-Mead或使用供应商库的CMA-ES。
由于本例较简单,使用40次迭代作为终止条件:
from pymoo.factory import get_termination
termination = get_termination("n_gen", 40)
2.3 优化
最小化方法如下:
from pymoo.optimize import minimize
res = minimize(
problem=MyProblem(),
algorithm=algorithm,
termination=termination,
seed=1,
save_history=True,
verbose=True # 输出控制变量
)
# 存储可行解
X = res.X
# 存储目标值
F = res.F
输出如下,每一列分别表示:
1)迭代次数;
2)评估次数;
3)总体最小约束违规;
4)总体平均约束违规;
5)非支配解决方案的数量;
6)和7)搜索空间中运动相关指标。
=====================================================================================
n_gen | n_eval | cv (min) | cv (avg) | n_nds | eps | indicator
=====================================================================================
1 | 40 | 0.00000E+00 | 2.36399E+01 | 1 | - | -
2 | 50 | 0.00000E+00 | 1.15486E+01 | 1 | 0.00000E+00 | f
3 | 60 | 0.00000E+00 | 5.277918607 | 1 | 0.00000E+00 | f
4 | 70 | 0.00000E+00 | 2.406068542 | 2 | 1.000000000 | ideal
5 | 80 | 0.00000E+00 | 0.908316880 | 3 | 0.869706146 | ideal
6 | 90 | 0.00000E+00 | 0.264746300 | 3 | 0.00000E+00 | f
7 | 100 | 0.00000E+00 | 0.054063822 | 4 | 0.023775686 | ideal
8 | 110 | 0.00000E+00 | 0.003060876 | 5 | 0.127815454 | ideal
9 | 120 | 0.00000E+00 | 0.00000E+00 | 6 | 0.085921728 | ideal
10 | 130 | 0.00000E+00 | 0.00000E+00 | 7 | 0.015715204 | f
11 | 140 | 0.00000E+00 | 0.00000E+00 | 8 | 0.015076323 | f
12 | 150 | 0.00000E+00 | 0.00000E+00 | 7 | 0.026135665 | f
13 | 160 | 0.00000E+00 | 0.00000E+00 | 10 | 0.010026699 | f
14 | 170 | 0.00000E+00 | 0.00000E+00 | 11 | 0.011833783 | f
15 | 180 | 0.00000E+00 | 0.00000E+00 | 12 | 0.008294035 | f
16 | 190 | 0.00000E+00 | 0.00000E+00 | 14 | 0.006095993 | ideal
17 | 200 | 0.00000E+00 | 0.00000E+00 | 17 | 0.002510398 | ideal
18 | 210 | 0.00000E+00 | 0.00000E+00 | 20 | 0.003652660 | f
19 | 220 | 0.00000E+00 | 0.00000E+00 | 20 | 0.010131820 | nadir
20 | 230 | 0.00000E+00 | 0.00000E+00 | 21 | 0.005676014 | f
21 | 240 | 0.00000E+00 | 0.00000E+00 | 25 | 0.010464402 | f
22 | 250 | 0.00000E+00 | 0.00000E+00 | 25 | 0.000547515 | f
23 | 260 | 0.00000E+00 | 0.00000E+00 | 28 | 0.001050255 | f
24 | 270 | 0.00000E+00 | 0.00000E+00 | 33 | 0.003841298 | f
25 | 280 | 0.00000E+00 | 0.00000E+00 | 37 | 0.006664377 | nadir
26 | 290 | 0.00000E+00 | 0.00000E+00 | 40 | 0.000963164 | f
27 | 300 | 0.00000E+00 | 0.00000E+00 | 40 | 0.000678243 | f
28 | 310 | 0.00000E+00 | 0.00000E+00 | 40 | 0.000815766 | f
29 | 320 | 0.00000E+00 | 0.00000E+00 | 40 | 0.001500814 | f
30 | 330 | 0.00000E+00 | 0.00000E+00 | 40 | 0.014706442 | nadir
31 | 340 | 0.00000E+00 | 0.00000E+00 | 40 | 0.003554320 | ideal
32 | 350 | 0.00000E+00 | 0.00000E+00 | 40 | 0.000624123 | f
33 | 360 | 0.00000E+00 | 0.00000E+00 | 40 | 0.000203925 | f
34 | 370 | 0.00000E+00 | 0.00000E+00 | 40 | 0.001048509 | f
35 | 380 | 0.00000E+00 | 0.00000E+00 | 40 | 0.001121103 | f
36 | 390 | 0.00000E+00 | 0.00000E+00 | 40 | 0.000664461 | f
37 | 400 | 0.00000E+00 | 0.00000E+00 | 40 | 0.000761066 | f
38 | 410 | 0.00000E+00 | 0.00000E+00 | 40 | 0.000521906 | f
39 | 420 | 0.00000E+00 | 0.00000E+00 | 40 | 0.004652095 | nadir
40 | 430 | 0.00000E+00 | 0.00000E+00 | 40 | 0.000287847 | f
2.4 可视化
可视化以更好地展示求解结果:
import matplotlib.pyplot as plt
problem = MyProblem()
xl, xu = problem.bounds()
plt.figure(figsize=(7, 5))
plt.scatter(X[:, 0], X[:, 1], s=30, facecolors='none', edgecolors='r')
plt.xlim(xl[0], xu[0])
plt.ylim(xl[1], xu[1])
plt.title("Search space")
plt.show()
plt.figure(figsize=(7, 5))
plt.scatter(F[:, 0], F[:, 1], s=30, facecolors='none', edgecolors='blue')
plt.title("Objective Space")
plt.show()
输出如下:
3 完整代码
import numpy as np
from pymoo.core.problem import ElementwiseProblem
from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.factory import get_sampling, get_crossover, get_mutation
from pymoo.factory import get_termination
from pymoo.optimize import minimize
class MyProblem(ElementwiseProblem):
def __init__(self):
super(MyProblem, self).__init__(
n_var=2, # 变量数量
n_obj=2, # 优化目标的数量
n_constr=2, # 约束的数量
xl=np.array([-2, -2]), # 变量的下限
xu=np.array([2, 2]) # 变量的上限
)
def _evaluate(self, x, out, *args, **kwargs):
"""
:param x: 1D向量,长度为n_var
:param out:
:param args:
:param kwargs:
:return:
"""
# 目标函数
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]
algorithm = NSGA2(
pop_size=40, # 种群数量
n_offsprings=10, # 后代数量
sampling=get_sampling("real_random"), # 采样的方式,如随机采样
crossover=get_crossover("real_sbx", prob=0.9, eta=15), # 交配方式,如模拟二进制
mutation=get_mutation("real_pm", eta=20), # 变异方式,多项式变异
eliminate_duplicates=True # 确保后代的目标是不同
)
termination = get_termination("n_gen", 40)
res = minimize(
problem=MyProblem(),
algorithm=algorithm,
termination=termination,
seed=1,
save_history=True,
verbose=True # 输出控制变量
)
# 存储可行解
X = res.X
# 存储目标值
F = res.F
import matplotlib.pyplot as plt
problem = MyProblem()
xl, xu = problem.bounds()
plt.figure(figsize=(7, 5))
plt.scatter(X[:, 0], X[:, 1], s=30, facecolors='none', edgecolors='r')
plt.xlim(xl[0], xu[0])
plt.ylim(xl[1], xu[1])
plt.title("Search space")
plt.show()
plt.figure(figsize=(7, 5))
plt.scatter(F[:, 0], F[:, 1], s=30, facecolors='none', edgecolors='blue')
plt.title("Objective Space")
plt.show()
版权声明:本文标题:Pymoo学习 (3):使用多目标优化找到最优解的集合 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1728257553a1151192.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论