You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pyomo中使用Xpress求解非线性模型?

问题描述

我用Pyomo编写了一个简单的非线性模型示例:

import pyomo.environ as pyo
model = pyo.ConcreteModel()
model.N = pyo.RangeSet(0, 2)
model.x = pyo.Var(model.N, within=pyo.NonNegativeReals, bounds=[5, 1000])
model.objective = pyo.Objective(expr=pyo.quicksum(model.x[j] for j in model.N))
def constraint_rule(model):
    return pyo.sqrt(model.x[0] + model.x[1]) == model.x[2]
    # return model.x[0] + model.x[1] <= model.x[2]
model.constraint = pyo.Constraint(rule=constraint_rule)
# solver = pyo.SolverFactory('knitroampl')
solver = pyo.SolverFactory('xpress_direct')
results = solver.solve(model, tee=True)

我可以用Knitro求解这个模型,也能用Xpress求解线性模型,但不知道如何用Xpress求解该非线性模型,运行时出现以下错误:

Traceback (most recent call last):
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 258, in _get_expr_from_pyomo_expr
    xpress_expr, referenced_vars = self._get_expr_from_pyomo_repn(repn, max_degree)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 231, in _get_expr_from_pyomo_repn
    raise DegreeError('XpressDirect does not support expressions of degree {0}.'.format(degree))
pyomo.solvers.plugins.solvers.xpress_direct.DegreeError: XpressDirect does not support expressions of degree None.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "pyomo_xpress.py", line 12, in <module>
    results = solver.solve(model, tee=True)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/direct_solver.py", line 120, in solve
    self._presolve(*args, **kwds)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/direct_solver.py", line 63, in _presolve
    self._set_instance(model, kwds)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 319, in _set_instance
    self._add_block(model)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 322, in _add_block
    DirectOrPersistentSolver._add_block(self, block)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/direct_or_persistent_solver.py", line 218, in _add_block
    self._add_constraint(con)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 339, in _add_constraint
    xpress_expr, referenced_vars = self._get_expr_from_pyomo_expr(
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 262, in _get_expr_from_pyomo_expr
    raise DegreeError(msg)
pyomo.solvers.plugins.solvers.xpress_direct.DegreeError: XpressDirect does not support expressions of degree None.
expr: sqrt(x[0] + x[1]) - x[2]

解决方法

问题根源

xpress_direct是Pyomo与Xpress的直接绑定接口,它仅支持多项式形式的非线性表达式,像sqrt这类超越函数无法被识别为固定次数的多项式,因此触发DegreeError。

方案1:改用Xpress的AMPL接口

替换求解器初始化代码,使用Xpress的AMPL格式接口,该接口对非线性表达式的兼容性更好:

# 替换xpress_direct为xpress
solver = pyo.SolverFactory('xpress')
results = solver.solve(model, tee=True)

需要确保你的Xpress安装包含AMPL接口支持,Pyomo能正确找到Xpress的可执行文件。

方案2:等价转化非线性约束

将sqrt(x[0]+x[1]) = x[2]等价转化为二次约束,避免使用超越函数,这样xpress_direct可直接处理:

def constraint_rule(model):
    # 等价转化为平方形式,利用变量已设置NonNegativeReals的特性
    return model.x[0] + model.x[1] == model.x[2] ** 2
model.constraint = pyo.Constraint(rule=constraint_rule)

转化后的问题属于二次规划,求解效率通常比原始超越函数问题更高。

内容的提问来源于stack exchange,提问作者fontanf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:12:09