簡體   English   中英

如何構建 SOCP 問題並使用 cvxpy 和 cvxpylayers 解決

[英]How to construct a SOCP problem and solve using cvxpy and cvxpylayers

我正在嘗試使用cvxpy解決 SOCP 問題並將其集成到cvxpylayers 我正在查看這個SOCP 問題(問題 11 )( 是 scihub 鏈接,以防您無法訪問),這是問題的一個片段(注意min (pt)來自使用表達式問題 4的改編8在上面的鏈接中):

在此處輸入圖像描述

Go 到 --->編輯 2

老的

我看過這個例子,但仍然卡住了,無法解決問題。 這是我嘗試的示例代碼:

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(請參閱第 4.1 節)。

首先,我注意到我的p = cp.sqrt(cp.sum_squares(Q_sqrt @ x)/N)部分目標(表達式 8的第一項)不是 DCP 並且不知道如何解決它。

另外,有人告訴我,需要使用cp.quad_over_lin重新制定這個xT @ Q @ x <= N * p**2約束,但是,如前所述,我要求它也遵循 DPP 規則(對於cvxpylayers ),因此我不確定如何更改cp.sum_squares(Q_sqrt @ x) <= N * (p ** 2)以跟隨cp.quad_over_lin

最后,我確信我的代碼的其他部分也錯誤地實現了。 非常感謝您對這個問題的任何幫助!

編輯 1 :請注意,最終解決方案不必調用cvxpylayers ,而只需符合 DPP 標准,以便之后可以與cvxpylayers集成。

__________________________________________________________________________

新的

編輯 2 :我現在意識到這可能是一個多變量問題,以最小化p - t給定變量x,z,p,t 我不知道為什么我沒有早點想到這一點。

鑒於上面的代碼片段問題,我最近的嘗試如下:

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) <= power(var7792, 2.0),因為以下子表達式不是:|-- quad_over_lin(param7788 @ var7790, 5.0) <= power(var7792, 2.0)

對於這個xT @ Q @ x <= N * p**2約束(我的嘗試: cp.quad_over_lin(Q_sqrt @ x, N) <= p ** 2 )。

除此之外,問題也是上面提到的SOCP ,所以我在 constraint_soc 中的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 (我的第二個問題),我不確定如何僅基於示例構建 SOCP。

編輯 4 :使用EDIT 2/3和 Erling 的答案以及 Erling 建議的不同求解器,問題得到解決。 注意我改用XPRESS求解器。

你應該改變

xT @ Q @ x <= N * p**2

(xT@Q@x)/p <= N * p

假設 p>=0。

順便說一句,如果您想了解更多關於如何將其表述為SOCP 的信息,請查閱 Mosek 建模食譜

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM