使用Python绘制Pareto前沿时遇TypeError错误求助
多目标优化Pareto前沿绘制错误排查与修正
错误信息
TypeError: '>' not supported between instances of 'generator' and 'int'
原代码
import numpy as np from pymoo.core.problem import Problem from pymoo.visualization.scatter import Scatter from pymoo.algorithms.moo.nsga2 import RankAndCrowdingSurvival from pymoo.core.mixed import MixedVariableGA from pymoo.optimize import minimize v=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] w=[22.0, 31.0, 0.0, 0.0, 11416.0, 0.0, 0.0, 0.0, 0.0, 15376.6, 977.97, 4324.97, 3264.79, 32.4, 43.02, 0.029, 0.2,0.00185, 0.00185, 0.0001, 0.03, 0.017, 0.0,0,0,0,0,0,0] e=[562.51, 562.51, 0.0, 0.0, 223.16, 0.0, 0.0, 0.0, 0.0, 1401.63, 411.42, 1401.63, 0.0,312.53, 17195.71, 0.623, 15.14,0.01, 4.5, 23.42, 0.66,0,0,0,0,0,0,0,0] g=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 840.000,469.000,46.000,18.000,4.000,12.000,0,0,0,0] class WEN(Problem): def __init__(self): super().__init__(n_var=v, n_obj=2, n_ieq_constr=2, xl=np.array(0 for i in range(29)), xu=None) def _evaluate(self, x, out, *args, **kwargs): f1=[numpy.dot(v,e)] f2=[numpy.dot(v,w)] g1=[(numpy.dot(v*w)/100)-585] g2=[(numpy.dot(v*g)*0.00001)-1610] out["F"] = [f1, f2] out["G"] = [g1, g2] problem = WEN() algorithm = MixedVariableGA(pop_size=20, survival=RankAndCrowdingSurvival()) res = minimize(problem, algorithm, ('n_gen', 50), seed=1, verbose=False) plot = Scatter() plot.add(problem.pareto_front(), plot_type="line", color="black", alpha=0.7) plot.add(res.F, facecolor="none", edgecolor="red") plot.show()
错误原因与修正步骤
1. Problem初始化参数错误
n_var需要传入变量的数量(整数),原代码传入了列表v,导致后续内部逻辑将其当作迭代器处理,引发类型错误。应改为n_var=29。xl=np.array(0 for i in range(29))是生成器表达式,改为xl=np.zeros(29)更高效清晰;xu未设置,若为二进制变量可设为xu=np.ones(29),根据实际变量范围调整。
2. _evaluate方法误用全局变量
目标函数和约束不应使用固定全局列表v,而应使用方法参数x(当前种群的变量矩阵,每行对应一个个体),否则优化过程不会更新变量,失去意义。
3. 矩阵运算与输出格式错误
- 列表不能直接做
*和dot运算,需先转为numpy数组;对于矩阵x(N×29),可直接用矩阵乘法x @ e计算所有个体的目标值。 out["F"]需要是形状为(N, 2)的二维数组,out["G"]是(N, 2)的二维数组,不能嵌套列表。
修正后的完整代码
import numpy as np from pymoo.core.problem import Problem from pymoo.visualization.scatter import Scatter from pymoo.algorithms.moo.nsga2 import RankAndCrowdingSurvival from pymoo.core.mixed import MixedVariableGA from pymoo.optimize import minimize # 转为numpy数组方便运算 w = np.array([22.0, 31.0, 0.0, 0.0, 11416.0, 0.0, 0.0, 0.0, 0.0, 15376.6, 977.97, 4324.97, 3264.79, 32.4, 43.02, 0.029, 0.2,0.00185, 0.00185, 0.0001, 0.03, 0.017, 0.0,0,0,0,0,0,0]) e = np.array([562.51, 562.51, 0.0, 0.0, 223.16, 0.0, 0.0, 0.0, 0.0, 1401.63, 411.42, 1401.63, 0.0,312.53, 17195.71, 0.623, 15.14,0.01, 4.5, 23.42, 0.66,0,0,0,0,0,0,0,0]) g = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 840.000,469.000,46.000,18.000,4.000,12.000,0,0,0,0]) class WEN(Problem): def __init__(self): # 假设变量是二进制(0/1),设置上下限 super().__init__(n_var=29, n_obj=2, n_ieq_constr=2, xl=np.zeros(29), xu=np.ones(29)) def _evaluate(self, x, out, *args, **kwargs): # 计算所有个体的目标值,x形状为(N,29) f1 = x @ e # 形状(N,) f2 = x @ w # 形状(N,) # 计算约束,pymoo要求G <= 0 g1 = (x @ w)/100 - 585 # 约束:(x·w)/100 ≤ 585 g2 = (x @ g)*0.00001 - 1610 # 约束:(x·g)*1e-5 ≤ 1610 out["F"] = np.column_stack([f1, f2]) # 转为(N,2)数组 out["G"] = np.column_stack([g1, g2]) # 转为(N,2)数组 problem = WEN() # 明确变量类型,如果是二进制变量,指定var_type algorithm = MixedVariableGA( pop_size=50, # 增大种群数量 survival=RankAndCrowdingSurvival(), var_type=np.int8 # 二进制变量用int8类型 ) res = minimize(problem, algorithm, ('n_gen', 100), # 增加迭代次数 seed=1, verbose=True) # 开启verbose查看优化过程 plot = Scatter() # 若没有Pareto前沿解析解,注释掉下面一行,或用res.F中的非支配解 # plot.add(problem.pareto_front(), plot_type="line", color="black", alpha=0.7) plot.add(res.F, facecolor="none", edgecolor="red") plot.show()
额外优化建议
- 变量类型确认:如果变量是二进制(0/1),必须在
MixedVariableGA中指定var_type=np.int8,否则算法会按连续变量处理,导致结果错误。 - 约束方向检查:pymoo默认要求不等式约束
G <= 0,如果你的实际约束是(x·w)/100 >= 585,则需要改为g1 = 585 - (x @ w)/100。 - 种群与迭代次数:29个变量的优化问题,pop_size=50、n_gen=100是更合理的初始设置,可根据优化结果进一步调整。
- Pareto前沿绘制:
problem.pareto_front()需要问题类实现_calc_pareto_front方法来提供解析解,若无解析解,可直接用res.F中的非支配解绘制,或使用pymoo的NonDominatedSort筛选非支配解。
内容的提问来源于stack exchange,提问作者Fatima Mansour
相关产品推荐
相关产品推荐

