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

为何CVXPY判定最大化$-x^2/y$不符合DCP规则?如何解决?

问题:CVXPY求解$-x^2/y$最大化问题触发DCPError

用户编写的CVXPY代码如下:

import cvxpy as cp

# Define variables
x = cp.Variable(nonneg = True)
y = cp.Variable(nonneg = True)

# Define the objective and constraint
obj = -1*cp.multiply(cp.power(x,2),cp.inv_pos(y))
objective = cp.Maximize(obj)
constraint = [y <= 1,
              x <= 1]  # Example constraint on y

# Formulate the problem
problem = cp.Problem(objective, constraint)

# Solve the problem
problem.solve()

用户疑问:$-x^2/y$难道不是凹函数吗?该如何解决这个问题?

运行代码后触发的错误信息:

---------------------------------------------------------------------------
DCPError                                  Traceback (most recent call last)
<ipython-input-194-ce998626c87f> in <cell line: 17>()
     15 
     16 # Solve the problem
---> 17 problem.solve()

5 frames
/usr/local/lib/python3.10/dist-packages/cvxpy/reductions/solvers/solving_chain.py in _reductions_for_problem_class(problem, candidates, gp, solver_opts)
    113             append += ("
However, the problem does follow DQCP rules. "
    114                        "Consider calling solve() with `qcp=True`.")
---> 115         raise DCPError(
    116             "Problem does not follow DCP rules. Specifically:
" + append)
    117     elif gp and not problem.is_dgp():

DCPError: Problem does not follow DCP rules. Specifically:
The objective is not DCP. Its following subexpressions are not:
power(var243205, 2.0) @ power(var243206 + 0.1, -1.0)

解答

为什么会触发DCPError?

虽然$-x^2/y$在$x,y>0$的定义域内确实是凹函数,但CVXPY的DCP(Disciplined Convex Programming)规则不直接验证函数本身的凹凸性,而是要求表达式通过原子函数的组合规则来推导凹凸性。

你的表达式cp.multiply(cp.power(x,2), cp.inv_pos(y))是两个凸函数的乘积:

  • cp.power(x,2)(即$x^2$)是凸函数且非负
  • cp.inv_pos(y)(即$1/y$)是凸函数且非负

根据DCP规则,两个凸函数相乘的操作无法被识别为合法的凸/凹表达式(DCP仅允许凸×非负凸、凹×非正凹等有限的组合形式),因此整个目标表达式不符合DCP规范,触发错误。


解决方法

方法1:使用CVXPY内置的兼容原子函数

CVXPY提供了cp.quad_over_lin(x, y)原子函数,专门表示$x^2/y$,这个函数被CVXPY识别为凸函数,完全符合DCP规则。修改后的代码如下:

import cvxpy as cp

# Define variables
x = cp.Variable(nonneg=True)
y = cp.Variable(nonneg=True)

# 使用quad_over_lin替代手动组合的表达式
obj = -cp.quad_over_lin(x, y)
objective = cp.Maximize(obj)
constraint = [y <= 1,
              x <= 1]

problem = cp.Problem(objective, constraint)
problem.solve()

# 输出结果
print(f"x = {x.value:.4f}, y = {y.value:.4f}, 目标值 = {problem.value:.4f}")

方法2:启用QCP模式求解

错误提示中提到问题符合DQCP(Quadratically Constrained Convex Programming)规则,因此可以直接在solve()方法中添加qcp=True参数,启用QCP模式求解,无需修改原有表达式:

import cvxpy as cp

# Define variables
x = cp.Variable(nonneg = True)
y = cp.Variable(nonneg = True)

# 保留原有表达式
obj = -1*cp.multiply(cp.power(x,2),cp.inv_pos(y))
objective = cp.Maximize(obj)
constraint = [y <= 1,
              x <= 1]

problem = cp.Problem(objective, constraint)
# 启用QCP模式
problem.solve(qcp=True)

# 输出结果
print(f"x = {x.value:.4f}, y = {y.value:.4f}, 目标值 = {problem.value:.4f}")

两种方法对比

  • 方法1使用DCP兼容的原子函数,求解效率更高,是CVXPY推荐的规范写法
  • 方法2无需修改表达式,适合快速验证问题,兼容性稍弱(依赖支持QCP的求解器)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 03:52:05