【问题标题】:How to create an inequality constraint on the inner product of two columns in CVXPY?如何在 CVXPY 中对两列的内积创建不等式约束?
【发布时间】:2017-03-16 02:16:11
【问题描述】:

假设我的约束是矩阵变量的第一列和第三列的乘积大于一。如何在 CVXPY 中实现?示例:

w = Variable(4,3) 

在 Matlab 中,我的约束是:

w(:,1)'*w(:,3)>1

如何在 CVXPY 中实现它?或者我们可以在 CVXPY 下进行点积吗? CVXPY 不支持numpy.dot

【问题讨论】:

    标签: python python-2.7 mathematical-optimization convex-optimization cvxpy


    【解决方案1】:

    如果两个变量都是正数,那么集合 {x * y > 1} 实际上是凸的,而函数 x*y 既不是凸的也不是凹的。这可以通过查看二阶导数矩阵的特征值来检查

    (x*y)'' = 
    [[0, 1],
     [1, 0]]
    

    它们是{-1, 1}。矩阵不是正定的,也不是负定的。

    有时您可以将问题转化为凸问题。在这种情况下,这可以通过取两边的对数来实现:

    log(x) + log(y) >= 0
    

    这是一个有效的限制,因为 log(x) 和 log(y) 都是凹函数并且不等式大于或等于。该约束将通过“有纪律的凸规划”规则。祝你好运。

    【讨论】:

    • 等一下。这里的 $x$ 和 $y$ 是向量。向量的对数是什么意思?
    • @Apprentice 在我的示例中,x 和 y 不是向量。回想起来,我的回答应该是评论,因为它并没有真正解决问题。此外,我不确定问题中描述的集合是凸集
    【解决方案2】:

    不可能将两个变量相乘,所有约束都必须是线性的(通常DCP)。

    如果您尝试执行禁止操作,CVXPY 会引发 DCPError。

    import cvxpy
    x = cvxpy.Variable()
    y = cvxpy.Variable()
    constraints = [x*y > 1]
    
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\Python27\lib\site-packages\cvxpy\expressions\expression.py", line 43, in cast_op
        return binary_op(self, other)
      File "C:\Python27\lib\site-packages\cvxpy\expressions\expression.py", line 226, in __mul__
        raise DCPError("Cannot multiply two non-constants.")
    cvxpy.error.DCPError: Cannot multiply two non-constants.
    

    如果至少有一个变量是整数/布尔值,您可以使用 slack 变量来避免这种情况。否则,您可以使用任何非线性求解器,例如IPOPT。

    here 回答了同样的问题。

    【讨论】:

      【解决方案3】:

      Gram 矩阵Q := W.T * W 的东北项有严格的不等式约束,它是对称的和半正定的。因此,请改为使用 Gram 矩阵 Q,然后引入严格的不等式约束 Q[0,2] &gt; 1

      例如,这是一个目标为零的半定程序 (SDP):

      >>> from cvxpy import *
      >>> Q = Semidef(3)
      >>> objective = Minimize(0)
      >>> constraints = [ Q[0,2] > 1 ]
      >>> prob = Problem(objective,constraints)
      >>> prob.solve()
      0.0
      >>> Q.value
      matrix([[  2.33101529e+00,   2.57980002e-30,   1.76709537e+00],
              [  2.57980002e-30,   2.57740598e-15,  -2.00304682e-30],
              [  1.76709537e+00,  -2.00304682e-30,   2.33101529e+00]])
      

      注意东北入口是1.76709537e+00 &gt; 1。要从 Gram 矩阵 Q 中恢复矩阵 W,请使用 Cholesky 分解并附加一行零以获得 4 x 3 矩阵,如下所示:

      >>> import numpy as np
      >>> L = np.linalg.cholesky(Q.value)
      >>> W = (np.insert(L, 3, np.array([0,0,0]), axis=1)).T
      >>> W
      matrix([[  1.52676628e+00,   1.68971508e-30,   1.15741053e+00],
              [  0.00000000e+00,   5.07681591e-08,  -7.79768444e-23],
              [  0.00000000e+00,   0.00000000e+00,   9.95698832e-01],
              [  0.00000000e+00,   0.00000000e+00,   0.00000000e+00]])
      

      让我们验证一下:

      >>> W.T * W - Q.value
      matrix([[  0.00000000e+00,   0.00000000e+00,   0.00000000e+00],
              [  0.00000000e+00,   0.00000000e+00,   7.00649232e-46],
              [  0.00000000e+00,   7.00649232e-46,   0.00000000e+00]])
      

      【讨论】:

        猜你喜欢
        • 2019-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多