关于 pymoo
pymoo 是用于 Python 优化任务的框架,侧重多目标问题,也支持单目标、约束及混合变量优化。它提供进化算法、基准问题、可定制算子和多准则决策方法,适合研究人员与工程师分析目标权衡。
主要功能
- 01支持单目标与多目标优化
- 02提供 NSGA-II、NSGA-III 和 MOEA/D
- 03处理约束与混合变量问题
- 04自定义遗传算子
- 05可视化 Pareto 前沿并辅助决策
适用场景
- 01分析相互冲突目标间的权衡
- 02在标准测试问题上比较算法
- 03对领域问题定义约束优化模型
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jackspace/ claudeskillz --skill pymoo安装后在 Claude Code 中输入/pymoo确认已加载。
附带文件SKILL.json
详细介绍
Pymoo - Python 多目标优化
概述
Pymoo 是一个功能全面的 Python 优化框架,侧重于多目标问题。使用先进算法(NSGA-II/III、MOEA/D)、基准问题(ZDT、DTLZ)、可自定义遗传算子和多准则决策方法,求解单目标和多目标优化问题。它擅长为目标相互冲突的问题寻找权衡解(帕累托前沿)。
何时使用此技能
在以下情况下应使用此技能:
- 求解单目标或多目标优化问题
- 寻找帕累托最优解并分析权衡关系
- 实现进化算法(GA、DE、PSO、NSGA-II/III)
- 处理约束优化问题
- 在标准测试问题(ZDT、DTLZ、WFG)上对算法进行基准测试
- 自定义遗传算子(交叉、变异、选择)
- 可视化高维优化结果
- 根据多个相互竞争的解做出决策
- 处理二进制、离散、连续或混合变量问题
核心概念
统一接口
Pymoo 使用一致的 minimize() 函数处理所有优化任务:
from pymoo.optimize import minimize
result = minimize(
problem, # What to optimize
algorithm, # How to optimize
termination, # When to stop
seed=1,
verbose=True
)
结果对象包含:
result.X:最优解的决策变量result.F:最优解的目标值result.G:约束违反情况(如果有约束)result.algorithm:包含历史记录的算法对象
问题类型
单目标: 一个需要最小化/最大化的目标
多目标: 2-3 个相互冲突的目标 → 帕累托前沿
多目标(4 个及以上): 4 个或更多目标 → 高维帕累托前沿
有约束: 目标 + 不等式/等式约束
动态: 随时间变化的目标或约束
快速入门工作流
工作流 1:单目标优化
适用情况: 优化一个目标函数
步骤:
- 定义或选择问题
- 选择单目标算法(GA、DE、PSO、CMA-ES)
- 配置终止条件
- 运行优化
- 提取最佳解
示例:
from pymoo.algorithms.soo.nonconvex.ga import GA
from pymoo.problems import get_problem
from pymoo.optimize import minimize
# Built-in problem
problem = get_problem("rastrigin", n_var=10)
# Configure Genetic Algorithm
algorithm = GA(
pop_size=100,
eliminate_duplicates=True
)
# Optimize
result = minimize(
problem,
algorithm,
('n_gen', 200),
seed=1,
verbose=True
)
print(f"Best solution: {result.X}")
print(f"Best objective: {result.F[0]}")
参见: scripts/single_objective_example.py,查看完整示例
工作流 2:多目标优化(2-3 个目标)
适用情况: 优化 2-3 个相互冲突的目标,需要帕累托前沿
算法选择: NSGA-II(双目标/三目标优化的标准算法)
步骤:
- 定义多目标问题
- 配置 NSGA-II
- 运行优化以获取帕累托前沿
- 可视化权衡关系
- 应用决策方法(可选)
示例:
from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.problems import get_problem
from pymoo.optimize import minimize
from pymoo.visualization.scatter import Scatter
# Bi-objective benchmark problem
problem = get_problem("zdt1")
# NSGA-II algorithm
algorithm = NSGA2(pop_size=100)
# Optimize
result = minimize(problem, algorithm, ('n_gen', 200), seed=1)
# Visualize Pareto front
plot = Scatter()
plot.add(result.F, label="Obtained Front")
plot.add(problem.pareto_front(), label="True Front", alpha=0.3)
plot.show()
print(f"Found {len(result.F)} Pareto-optimal solutions")
参见: scripts/multi_objective_example.py,查看完整示例
工作流 3:多目标优化(4 个及以上目标)
适用情况: 优化 4 个或更多目标
算法选择: NSGA-III(专为多目标优化设计)
主要区别: 必须提供用于引导种群的参考方向
步骤:
- 定义多目标问题
- 生成参考方向
- 使用参考方向配置 NSGA-III
- 运行优化
- 使用平行坐标图进行可视化
示例:
from pymoo.algorithms.moo.nsga3 import NSGA3
from pymoo.problems import get_problem
from pymoo.optimize import minimize
from pymoo.util.ref_dirs import get_reference_directions
from pymoo.visualization.pcp import PCP
# Many-objective problem (5 objectives)
problem = get_problem("dtlz2", n_obj=5)
# Generate reference directions (required for NSGA-III)
ref_dirs = get_reference_directions("das-dennis", n_dim=5, n_partitions=12)
# Configure NSGA-III
algorithm = NSGA3(ref_dirs=ref_dirs)
# Optimize
result = minimize(problem, algorithm, ('n_gen', 300), seed=1)
# Visualize with Parallel Coordinates
plot = PCP(labels=[f"f{i+1}" for i in range(5)])
plot.add(result.F, alpha=0.3)
plot.show()
参见: scripts/many_objective_example.py,查看完整示例
工作流 4:自定义问题定义
适用情况: 求解特定领域的优化问题
步骤:
- 扩展
ElementwiseProblem类 - 定义包含问题维度和边界的
__init__ - 实现用于计算目标(和约束)的
_evaluate方法 - 与任意算法配合使用
无约束示例:
from pymoo.core.problem import ElementwiseProblem
import numpy as np
class MyProblem(ElementwiseProblem):
def __init__(self):
super().__init__(
n_var=2, # Number of variables
n_obj=2, # Number of objectives
xl=np.array([0, 0]), # Lower bounds
xu=np.array([5, 5]) # Upper bounds
)
def _evaluate(self, x, out, *args, **kwargs):
# Define objectives
f1 = x[0]**2 + x[1]**2
f2 = (x[0]-1)**2 + (x[1]-1)**2
out["F"] = [f1, f2]
有约束示例:
class ConstrainedProblem(ElementwiseProblem):
def __init__(self):
super().__init__(
n_var=2,
n_obj=2,
n_ieq_constr=2, # Inequality constraints
n_eq_constr=1, # Equality constraints
xl=np.array([0, 0]),
xu=np.array([5, 5])
)
def _evaluate(self, x, out, *args, **kwargs):
# Objectives
out["F"] = [f1, f2]
# Inequality constraints (g <= 0)
out["G"] = [g1, g2]
# Equality constraints (h = 0)
out["H"] = [h1]
约束表达规则:
- 不等式:表示为
g(x) <= 0(≤ 0 时可行) - 等式:表示为
h(x) = 0(= 0 时可行) - 将
g(x) >= b转换为-(g(x) - b) <= 0
参见: scripts/custom_problem_example.py,查看完整示例
工作流 5:约束处理
适用场景: 问题存在可行性约束
可选方法:
1. 可行性优先(默认,推荐)
from pymoo.algorithms.moo.nsga2 import NSGA2
# Works automatically with constrained problems
algorithm = NSGA2(pop_size=100)
result = minimize(problem, algorithm, termination)
# Check feasibility
feasible = result.CV[:, 0] == 0 # CV = constraint violation
print(f"Feasible solutions: {np.sum(feasible)}")
2. 惩罚法
from pymoo.constraints.as_penalty import ConstraintsAsPenalty
# Wrap problem to convert constraints to penalties
problem_penalized = ConstraintsAsPenalty(problem, penalty=1e6)
3. 将约束作为目标
from pymoo.constraints.as_obj import ConstraintsAsObjective
# Treat constraint violation as additional objective
problem_with_cv = ConstraintsAsObjective(problem)
4. 专用算法
from pymoo.algorithms.soo.nonconvex.sres import SRES
# SRES has built-in constraint handling
algorithm = SRES()
参见: references/constraints_mcdm.md,了解全面的约束处理指南
工作流 6:根据 Pareto 前沿进行决策
适用场景: 已有 Pareto 前沿,需要选择首选解
步骤:
- 运行多目标优化
- 将目标归一化到 [0, 1]
- 定义偏好权重
- 应用 MCDM 方法
- 可视化选定的解
使用伪权重的示例:
from pymoo.mcdm.pseudo_weights import PseudoWeights
import numpy as np
# After obtaining result from multi-objective optimization
# Normalize objectives
F_norm = (result.F - result.F.min(axis=0)) / (result.F.max(axis=0) - result.F.min(axis=0))
# Define preferences (must sum to 1)
weights = np.array([0.3, 0.7]) # 30% f1, 70% f2
# Apply decision making
dm = PseudoWeights(weights)
selected_idx = dm.do(F_norm)
# Get selected solution
best_solution = result.X[selected_idx]
best_objectives = result.F[selected_idx]
print(f"Selected solution: {best_solution}")
print(f"Objective values: {best_objectives}")
其他 MCDM 方法:
- 折中规划:选择最接近理想点的解
- 膝点:寻找均衡的权衡解
- 超体积贡献:选择多样性最高的子集
参见:
scripts/decision_making_example.py,查看完整示例references/constraints_mcdm.md,了解详细的 MCDM 方法
工作流 7:可视化
根据目标数量选择可视化方式:
2 个目标:散点图
from pymoo.visualization.scatter import Scatter
plot = Scatter(title="Bi-objective Results")
plot.add(result.F, color="blue", alpha=0.7)
plot.show()
3 个目标:3D 散点图
plot = Scatter(title="Tri-objective Results")
plot.add(result.F) # Automatically renders in 3D
plot.show()
4 个或更多目标:平行坐标图
from pymoo.visualization.pcp import PCP
plot = PCP(
labels=[f"f{i+1}" for i in range(n_obj)],
normalize_each_axis=True
)
plot.add(result.F, alpha=0.3)
plot.show()
解的比较:花瓣图
from pymoo.visualization.petal import Petal
plot = Petal(
bounds=[result.F.min(axis=0), result.F.max(axis=0)],
labels=["Cost", "Weight", "Efficiency"]
)
plot.add(solution_A, label="Design A")
plot.add(solution_B, label="Design B")
plot.show()
参见: references/visualization.md,了解所有可视化类型及其用法
算法选择指南
单目标问题
| 算法 | 最适用于 | 主要特点 |
|---|---|---|
| GA | 通用场景 | 灵活,可自定义算子 |
| DE | 连续优化 | 全局搜索能力强 |
| PSO | 平滑景观 | 收敛速度快 |
| CMA-ES | 困难或含噪问题 | 自适应 |
多目标问题(2-3 个目标)
| 算法 | 最适用于 | 主要特点 |
|---|---|---|
| NSGA-II | 标准基准测试 | 快速、可靠、经过充分测试 |
| R-NSGA-II | 偏好区域 | 参考点引导 |
| MOEA/D | 可分解问题 | 标量化方法 |
多目标问题(4 个或更多目标)
| 算法 | 最适用于 | 主要特点 |
|---|---|---|
| NSGA-III | 4-15 个目标 | 基于参考方向 |
| RVEA | 自适应搜索 | 参考向量演化 |
| AGE-MOEA | 复杂景观 | 自适应几何 |
带约束的问题
| 方法 | 算法 | 适用场景 |
|---|---|---|
| 可行性优先 | 任意算法 | 可行区域较大 |
| 专用方法 | SRES、ISRES | 约束较多 |
| 惩罚法 | GA + 惩罚项 | 算法兼容性 |
参见: references/algorithms.md,了解全面的算法参考
基准问题
快速访问问题:
from pymoo.problems import get_problem
# Single-objective
problem = get_problem("rastrigin", n_var=10)
problem = get_problem("rosenbrock", n_var=10)
# Multi-objective
problem = get_problem("zdt1") # Convex front
problem = get_problem("zdt2") # Non-convex front
problem = get_problem("zdt3") # Disconnected front
# Many-objective
problem = get_problem("dtlz2", n_obj=5, n_var=12)
problem = get_problem("dtlz7", n_obj=4)
参见: references/problems.md,了解完整的测试问题参考
遗传算子自定义
标准算子配置:
from pymoo.algorithms.soo.nonconvex.ga import GA
from pymoo.operators.crossover.sbx import SBX
from pymoo.operators.mutation.pm import PM
algorithm = GA(
pop_size=100,
crossover=SBX(prob=0.9, eta=15),
mutation=PM(eta=20),
eliminate_duplicates=True
)
按变量类型选择算子:
连续变量:
- 交叉:SBX(模拟二进制交叉)
- 变异:PM(多项式变异)
二进制变量:
- 交叉:TwoPointCrossover、UniformCrossover
- 变异:BitflipMutation
排列(TSP、调度):
- 交叉:OrderCrossover(OX)
- 变异:InversionMutation
参见: references/operators.md,了解全面的算子参考
性能与故障排除
常见问题及解决方案:
问题:算法不收敛
- 增大种群规模
- 增加迭代代数
- 检查问题是否为多峰问题(尝试不同的算法)
- 确认约束的制定是否正确
问题:帕累托前沿分布不理想
- 对于 NSGA-III:调整参考方向
- 增大种群规模
- 检查是否消除了重复解
- 确认问题的缩放方式
问题:可行解较少
- 使用将约束作为目标的方法
- 应用修复算子
- 尝试使用 SRES/ISRES 求解带约束问题
- 检查约束的制定方式(应为 g <= 0)
问题:计算成本较高
- 减小种群规模
- 减少迭代代数
- 使用更简单的算子
- 启用并行化(如果问题支持)
最佳实践:
- 当目标的尺度差异显著时,对目标进行归一化
- 设置随机种子以确保结果可复现
- 保存历史记录以分析收敛情况:
save_history=True - 可视化结果以了解解的质量
- 如果有真实帕累托前沿,将结果与其进行比较
- 使用恰当的终止条件(迭代代数、评估次数、容差)
- 根据问题特征调整算子参数
资源
此技能包含全面的参考文档和可执行示例:
references/
用于深入了解的详细文档:
- algorithms.md:完整的算法参考,包含参数、用法和选择指南
- problems.md:基准测试问题(ZDT、DTLZ、WFG)及其特征
- operators.md:遗传算子(采样、选择、交叉、变异)及其配置
- visualization.md:所有可视化类型及示例和选择指南
- constraints_mcdm.md:约束处理技术和多准则决策方法
参考文档的搜索模式:
- 算法详情:
grep -r "NSGA-II\|NSGA-III\|MOEA/D" references/ - 约束方法:
grep -r "Feasibility First\|Penalty\|Repair" references/ - 可视化类型:
grep -r "Scatter\|PCP\|Petal" references/
scripts/
展示常见工作流的可执行示例:
- single_objective_example.py:使用 GA 进行单目标优化的基础示例
- multi_objective_example.py:使用 NSGA-II 进行多目标优化及可视化
- many_objective_example.py:使用 NSGA-III 进行多目标优化及参考方向设置
- custom_problem_example.py:定义自定义问题(带约束和无约束)
- decision_making_example.py:使用不同偏好的多准则决策
运行示例:
python3 scripts/single_objective_example.py
python3 scripts/multi_objective_example.py
python3 scripts/many_objective_example.py
python3 scripts/custom_problem_example.py
python3 scripts/decision_making_example.py
附加说明
安装:
pip install pymoo
**依赖项:**NumPy、SciPy、matplotlib、autograd(基于梯度的方法可选)
**文档:**https://pymoo.org/
**版本:**此技能基于 pymoo 0.6.x
常见模式:
- 自定义问题始终使用
ElementwiseProblem - 约束形式为
g(x) <= 0和h(x) = 0 - NSGA-III 需要参考方向
- 在 MCDM 之前对目标进行归一化
- 使用恰当的终止条件:
('n_gen', N)或get_termination("f_tol", tol=0.001)