【问题标题】:cvxpy: Converting a nonlinear constraint to an equivalent linear constraintcvxpy:将非线性约束转换为等效线性约束
【发布时间】:2020-04-21 07:40:28
【问题描述】:

上下文:我是PyPortfolioOpt 的开发人员,这是一个 python 投资组合优化库,我正在尝试允许用户为最大夏普比率问题添加约束。

目前,用户可以将约束作为 lambda 函数传递,例如使所有权重大于 1%:

ef = EfficientFrontier(mu, S)  # mu and S are expected return and covariance
ef.add_constraint(lambda w: w >= 0.01)  # example new constraint
ef.min_volatility()  # optimise with constraint

在后端,我将 cvxpy 变量 w = cp.Variable(n) 传递给约束 lambda 函数,以创建有效的 cvxpy 约束,然后将其传递给 cp.Problem 并解决它。

我遇到的麻烦是最大化夏普比率需要您进行变量替换。 Ax ~ b 形式的约束(其中~ 表示相等或不相等)必须变为Ax ~ k * b,其中k 是非负优化变量。

我尝试的一件事是将w / k 传递给 lambda 函数。这将导致约束w / k >= 0.01,我希望它等同于w >= k * 0.01,但遗憾的是这给出了:

DCPError: Problem does not follow DCP rules. Specifically:
The following constraints are not DCP:
0.01 <= var2817 / Promote(var2818, (20,)) , because the following subexpressions are not:
|--  var2817 / Promote(var2818, (20,))

然后我想我也许可以将非线性约束constr = (w / k &gt;= 0.01) 乘以k 得到k * constr = (w &gt;= 0.01 * k),但是你不能在cvxpy 中乘以约束。

TL;DR:如何将表示 w / k &gt;= 0.01 的 cvxpy 约束对象(已实例化)转换为表示 w &gt;= k * 0.01 的 cvxpy 约束对象?

或者失败了,我有什么办法可以重新设计它?我想保留 lambda 函数 API。

【问题讨论】:

    标签: python cvxpy convex-optimization


    【解决方案1】:

    也许有一些 API 用于分解已经实例化的约束,以便我可以放入变量?

    约束在设计上是不可变的。不变性简化了 CVXPY 的大部分逻辑。

    为什么不构造一个新的约束?您当然可以检查约束的左侧和右侧。现在,这可以通过检查args 属性来完成(参见https://github.com/cvxgrp/cvxpy/blob/master/cvxpy/constraints/nonpos.py#L97)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-13
      • 1970-01-01
      • 2015-07-31
      相关资源
      最近更新 更多