我想在 cvxpy 中包含一个约束,其中需要进行 2 个连续的矩阵乘法。但是它一直说我有 DCP 错误。我在约束函数中进行两个矩阵乘法的方式似乎有问题。
import cvxpy as cp
# yield is an 5x1 np array
# cov is an 5x5 np array
weight = cp.Variable(5)
objective = cp.Maximize(weight @ yield)
constraint = [cp.sqrt(weight.T @ cov @ weight) < 10]
你应该使用
cp.quad_from
import cvxpy as cp
import numpy as np
# Example random data for 'yield' (expected returns) and 'cov' (covariance matrix)
# np.random.seed(42) # For reproducibility
# yield_data = np.random.rand(5)
# cov_data = np.random.rand(5, 5)
yield_data=np.array([1,1,2,3,5]).T
cov_data=np.array([[2,3,4,5,6], [1,-1,1,-1,1], [2,3,5,10,18], [3,5,10,18,31], [5,10,18,31,59]])
cov_data = cov_data @ (cov_data.T) # To ensure the covariance matrix is positive semi-definite
weight = cp.Variable(5)
objective = cp.Maximize(weight @ yield_data) # Maximize expected return
# The risk constraint using cp.quad_form
risk_constraint = [cp.sqrt(cp.quad_form(weight, cov_data)) <= 10]
# Create problem
problem = cp.Problem(objective, risk_constraint)
# Solve the problem
my_solver=cp.SCS # For example, 'ECOS', 'SCS', or 'OSQP'.
problem.solve(qcp=True, solver=my_solver, verbose=True)
# Output the results
print("Optimal weights:", weight.value)
print("Maximum yield:", problem.value)
Optimal weights: [ 0.72181163 3.74851965 10.80178756 -0.87445396 -2.95779273]
Maximum yield: 8.66158088336791
等效的 Mathematica 代码:
Clear["Global`*"];
(*Define the yield data and covariance matrix*)
yieldData = {1, 1, 2, 3, 5};
matrixTmp = {{2, 3, 4, 5, 6}, {1, -1, 1, -1, 1}, {2, 3, 5, 10,
18}, {3, 5, 10, 18, 31}, {5, 10, 18, 31, 59}};
covData = matrixTmp . Transpose[matrixTmp];
(*Variables*)
vars = Array[Subscript[x, #] &, 5];
(*Objective function to maximize*)
objective = vars . yieldData;
(*Risk constraint*)
riskConstraint = Sqrt[vars . covData . vars] <= 10;
(*Solve the optimization problem*)
solution = NMaximize[{objective, riskConstraint}, vars]
(*Output the results*)
solution
{8.63459, {Subscript[x, 1] -> 0.719549, Subscript[x, 2] -> 3.73671,
Subscript[x, 3] -> 10.7685, Subscript[x, 4] -> -0.871835,
Subscript[x, 5] -> -2.94863}}