CVXPY求解器的输出矛盾

时间:2018-12-26 04:31:15

标签: python optimization mathematical-optimization numerical-methods cvxpy

我熟悉CVXPY,并遇到了一个奇怪的问题。我有以下简单的玩具优化问题:

import numpy as np
import cvxpy as cp

A=np.array([[1,0,0],[0,1,0], [0,0,1]])
y=np.array([1,1,1])

# Upper bound for the constraint term
upper=1
# Solve the optimization problem using CVXPY
x = cp.Variable(3)
objective = cp.Minimize(cp.sum_squares(x))
constraint = [cp.sum_squares(A*x - y) <= upper]
prob = cp.Problem(objective, constraint)
prob.solve()
optimal_x = x.value

print('Value of constraint at optimal x:' + str(np.linalg.norm(A*optimal_x - y)**2))

现在,我希望输出的数字比upper=1少,但是我得到的是:

Value of constraint at optimal x:3.0000000068183947

我对如何做到这一点感到非常困惑。我是否错误使用函数cp.sum_squares?我是否以错误的方式设置了优化?任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:3)

我认为混淆是由numpy中的错误矩阵乘法引起的:

>>> A * optimal_x - y
array([[-0.57735027, -1.        , -1.        ],
       [-1.        , -0.57735027, -1.        ],
       [-1.        , -1.        , -0.57735027]])

实际上我认为您想要的是

>>> np.dot(A, optimal_x) - y
array([-0.57735027, -0.57735027, -0.57735027])

哪些确实没有违反约束(在舍入误差内):

>>> np.linalg.norm(np.matmul(A, optimal_x) - y) ** 2
1.000000002699704

另请参阅this问题,以供参考numpy中的矩阵数组乘法。

这确实令人困惑,因为CVXPY对象即使使用numpy类型也能正确处理*运算符:

>>> (A * x - y).value
array([-0.57735027, -0.57735027, -0.57735027])

还要注意,对于在CVXPY中构造的任何表达式树,优化后,您都可以根据优化的x值查询该表达式的值:

>>> cp.sum_squares(A*x - y).value
array(1.)