如何解决GUROBI Python中无度数表达式(Degree None)的报错问题
问题分析与解决方案
报错原因
你遇到的DegreeError是因为目标函数中包含除法运算,Pyomo无法确定该表达式的次数,而GurobiDirect求解器不支持这种不确定次数的表达式。另外,代码中直接用np.square()处理Pyomo变量也是不合适的——numpy函数无法识别Pyomo的Var对象,会导致表达式解析异常。
关键优化:代数化简消除除法
观察你的成本函数:(x*price_coeff - x²*factor)/x
由于所有电机的功率变量x都有正下界约束(比如Motor1≥0.6,其他≥1),因此x≠0,可以直接对表达式进行代数化简:(x*price_coeff - x²*factor)/x = price_coeff - factor*x
化简后目标函数变为线性表达式,完全避免了除法,Gurobi可以直接处理。
修正后的代码
import pyomo.environ as pyo from pyomo.environ import SolverFactory power_ranges = { 'Motor1': (0.6, 1.1), 'Motor2': (2.1, 6), 'Motor3': (1, 1.94), 'Motor4': (1, 1.94), } # 化简后的成本函数:直接用线性表达式替代带除法的原公式 prices = { 'Motor1': lambda x: 5000 - 100 * x, 'Motor2': lambda y: 5500 - 100 * y, 'Motor3': lambda z: 5100 - 200 * z, 'Motor4': lambda a: 5200 - 300 * a, } # 创建模型 model = pyo.ConcreteModel() # 决策变量:非负实数,约束会进一步限制下界 model.x = pyo.Var(power_ranges.keys(), domain=pyo.NonNegativeReals) # 目标函数:求和化简后的线性成本 model.cost = pyo.Objective( expr=sum(prices[motor](model.x[motor]) for motor in power_ranges), sense=pyo.minimize ) # 上下界约束 model.bounds_constraint = pyo.ConstraintList() for motor in power_ranges: lower_bound, upper_bound = power_ranges[motor] model.bounds_constraint.add(lower_bound <= model.x[motor]) model.bounds_constraint.add(model.x[motor] <= upper_bound) # 注:原代码中`x >= min(0, lower_bound)`是冗余约束——所有lower_bound都是正数,且变量已设为NonNegativeReals,无需重复添加 # 总功率约束 model.power_constraint = pyo.Constraint( expr=sum(model.x[motor] for motor in power_ranges) == 5 ) # 求解 solver = SolverFactory('gurobi', solver_io='python') solver.options['NonConvex'] = 2 # 化简后是线性问题,该参数可移除,保留也不影响 results = solver.solve(model) # 输出结果 print("求解状态:", results.solver.status) print("最优成本:", model.cost()) for motor in power_ranges: print(f"{motor}最优功率:", model.x[motor]())
额外说明
- 化简后的目标函数是线性的,因此
NonConvex=2参数其实可以移除(该参数用于处理非凸非线性问题),保留也不会产生负面影响。 - 避免用numpy函数处理Pyomo变量:Pyomo有自己的表达式运算规则,直接用
x**2、x*y等原生运算符即可,无需依赖numpy。
内容的提问来源于stack exchange,提问作者Miguff
相关产品推荐
相关产品推荐

