【发布时间】:2021-03-21 10:51:02
【问题描述】:
我正在尝试使用 cvxpy 解决 SOCP 问题并将其集成到 cvxpylayers。我正在查看this SOCP 问题(问题 11)(here 是 scihub 链接,以防您无法访问),这里是问题的 sn-p(注意min (p-t) 来自使用上面链接中的表达式 8 改编的问题 4):
转到 ---> 编辑 2
旧
我查看了this 示例,但仍然卡住,无法解决问题。这是我尝试的示例代码:
import cvxpy as cp
import numpy as np
N = 5
Q_sqrt = cp.Parameter((N, N))
x = cp.Variable(N)
z = []
zero = []
for n in range(N):
z.append((Q_sqrt @ x)[n])
zero.append(cp.Constant(0))
p = cp.sqrt(cp.sum_squares(Q_sqrt @ x)/N) # based on expression 8
t = cp.sqrt(cp.min(x * (Q_sqrt @ x))) # based on expression 8
objective = cp.Minimize(p - t) # based on expression 8
constraint_soc1 = [cp.SOC(z[n], (Q_sqrt @ x)[n]) for n in range(N)]
constraint_soc2 = [cp.SOC(cp.quad_over_lin(t, z[n]), x[n]) for n in range(N)]
constraint_soc3 = [cp.SOC(z[n], zero[n]) for n in range(N)]
constraint_soc4 = [cp.SOC(x[n], zero[n]) for n in range(N)]
constraint_other = [cp.sum_squares(Q_sqrt @ x) <= N * (p ** 2),
cp.sum(x) == 1, p >= 0, t >= 0]
constraint_all = constraint_other + constraint_soc1 + constraint_soc2 + constraint_soc3 + constraint_soc4
matrix = np.random.random((N, N))
Q_sqrt.value = matrix.T @ matrix # to make positive definite
prob = cp.Problem(objective, constraint_all)
prob.solve()
print("status:", prob.status)
print("optimal value", prob.value)
请注意,我使用 cp.sum_squares(Q_sqrt @ x) 语法来确保它不仅符合 DCP,而且也符合 DPP(请参阅 Section 4.1)。
首先,我注意到我的p = cp.sqrt(cp.sum_squares(Q_sqrt @ x)/N) 部分目标(表达式 8 的第一项)不是 DCP,并且不知道如何解决它。
另外,有人告诉我,这个 x.T @ Q @ x <= N * p**2 约束需要使用 cp.quad_over_lin 重新制定,但是,如上所述,我要求它也遵守 DPP 规则(对于 cvxpylayers),因此我不确定如何将cp.sum_squares(Q_sqrt @ x) <= N * (p ** 2) 更改为关注cp.quad_over_lin。
最后,我确信我的代码的其他部分也错误地实现了。非常感谢您对此问题的任何帮助!
编辑 1:请注意,最终解决方案不必调用 cvxpylayers,而只需符合 DPP,以便之后可以与 cvxpylayers 集成。
__________________________________________________________________________
新
编辑 2:我现在意识到这可能是一个多变量问题,在给定变量 x,z,p,t 的情况下最小化 p - t。我不知道为什么我没有早点想到这一点。
鉴于上面的sn-p问题,我最近的尝试如下:
import cvxpy as cp
import numpy as np
N = 5
Q_sqrt = cp.Parameter((N, N))
Q = cp.Parameter((N, N))
x = cp.Variable(N)
z = cp.Variable(N)
p = cp.Variable()
t = cp.Variable()
objective = cp.Minimize(p - t)
constraint_soc = [z == Q @ x, x.value * z >= t ** 2, z >= 0, x >= 0]
constraint_other = [cp.quad_over_lin(Q_sqrt @ x, N) <= p ** 2, cp.sum(x) == 1, p >= 0, t >= 0]
constraint_all = constraint_other + constraint_soc
matrix = np.random.random((N, N))
a_matrix = matrix.T @ matrix
Q.value = a_matrix
Q_sqrt.value = np.sqrt(a_matrix)
prob = cp.Problem(objective, constraint_all)
prob.solve(verbose=True)
print("status:", prob.status)
print("optimal value", prob.value)
但是,我仍然收到错误:
DCPError:问题不遵循 DCP 规则。具体来说: 以下约束不是 DCP: quad_over_lin(param7788 @ var7790, 5.0)
对于这个x.T @ Q @ x <= N * p**2 约束(我的尝试:cp.quad_over_lin(Q_sqrt @ x, N) <= p ** 2)。
除了上面提到的问题也是SOCP,所以我在constraint_soc中的约束可能是错误的,但我不确定如何根据this循环/分配变量。
编辑 3:在 ErlingMOSEK 对约束提出建议后,我将约束从 cp.quad_over_lin(Q_sqrt @ x, N) <= p ** 2 更改为 cp.quad_over_lin(Q_sqrt @ x, p) <= N * p,但它现在可以运行了,
出现新错误
求解器“ECOS”失败。尝试其他求解器,或使用 verbose=True 求解以了解更多信息。
我认为这是由于问题是 SOCP(我的第二个问题),我不确定如何仅基于 this 示例构建 SOCP。
EDIT 4:使用 EDIT 2/3 和 Erling 的答案以及 Erling 建议的不同求解器,问题就解决了。注意我使用了XPRESS 求解器。
【问题讨论】:
标签: portfolio cvxpy convex-optimization cvxopt