使用 quadProg 库进行约束二次优化
Constrained quadratic optimization with the quadProg library
我有一个长度为 N
的向量 A
。我还有 N*N
矩阵 C
。我想最大化以下等式:
minimize (- (w_transpose * A) + p * w_transpose * C * w)
其中 w
是一个长度为 N
的向量,其中每个 w
都是非负的且所有 w
的总和为 1.
我看到了一个叫做 quadProg
的包裹。在那里我需要指定:
Dmat = C
、dvec = A
和 bvec = w
但不确定如何在那里应用上述约束。
我想我可以提供 Amat
作为单位矩阵,这将使所有 w
保持非负。但不确定如何保持 w
标准化(总和等于零)。实际上我也可以稍后将它们归一化,但仍然想知道我是否可以在这里自己做。
您可以使用 quadprog 的 solve.QP
函数来完成此操作。从 ?solve.QP
,我们读到 solve.QP
求解形式为 min_b {-d'b + 0.5 b'Db | A'b >= b0}
的系统。您正在解决 min_w {-A'w + pw'Cw | w >= 0, 1'w = 1}
形式的问题。因此,表格之间的映射:
d = A
(在 solve.QP
的参数中称为 dvec
)
D = 2pC
(在 solve.QP
的参数中称为 Dmat
)
- 对于第一组约束,您有
I'w >= 0
。最终约束可以重新表述为 1'w >= 1
和 -1'w >= -1
。因此,您的 A 约束矩阵(solve.QP
的参数中的 Amat
)是单位矩阵,其右侧附加了一个 1 向量和一个 -1 向量,右侧 b0([= solve.QP
) 的参数中的 28=] 是附加了 1 和 -1 的 0 向量。
您可以很容易地将它们全部放在 R 中:
library(quadprog)
solve.my.QP <- function(A, p, C) {
solve.QP(Dmat=2*p*C,
dvec=A,
Amat=cbind(diag(1, length(A)), rep(1, length(A)), rep(-1, length(A))),
bvec=c(rep(0, length(A)), 1, -1))$solution
}
您可以在一些简单的二维问题上对其进行测试:
# Even penalty
solve.my.QP(c(0, 0), 1, diag(1, 2))
# [1] 0.5 0.5
# Encourage inclusion of first variable
solve.my.QP(c(0.1, 0), 1, diag(1, 2))
# [1] 0.525 0.475
我有一个长度为 N
的向量 A
。我还有 N*N
矩阵 C
。我想最大化以下等式:
minimize (- (w_transpose * A) + p * w_transpose * C * w)
其中 w
是一个长度为 N
的向量,其中每个 w
都是非负的且所有 w
的总和为 1.
我看到了一个叫做 quadProg
的包裹。在那里我需要指定:
Dmat = C
、dvec = A
和 bvec = w
但不确定如何在那里应用上述约束。
我想我可以提供 Amat
作为单位矩阵,这将使所有 w
保持非负。但不确定如何保持 w
标准化(总和等于零)。实际上我也可以稍后将它们归一化,但仍然想知道我是否可以在这里自己做。
您可以使用 quadprog 的 solve.QP
函数来完成此操作。从 ?solve.QP
,我们读到 solve.QP
求解形式为 min_b {-d'b + 0.5 b'Db | A'b >= b0}
的系统。您正在解决 min_w {-A'w + pw'Cw | w >= 0, 1'w = 1}
形式的问题。因此,表格之间的映射:
d = A
(在solve.QP
的参数中称为dvec
)D = 2pC
(在solve.QP
的参数中称为Dmat
)- 对于第一组约束,您有
I'w >= 0
。最终约束可以重新表述为1'w >= 1
和-1'w >= -1
。因此,您的 A 约束矩阵(solve.QP
的参数中的Amat
)是单位矩阵,其右侧附加了一个 1 向量和一个 -1 向量,右侧 b0([=solve.QP
) 的参数中的 28=] 是附加了 1 和 -1 的 0 向量。
您可以很容易地将它们全部放在 R 中:
library(quadprog)
solve.my.QP <- function(A, p, C) {
solve.QP(Dmat=2*p*C,
dvec=A,
Amat=cbind(diag(1, length(A)), rep(1, length(A)), rep(-1, length(A))),
bvec=c(rep(0, length(A)), 1, -1))$solution
}
您可以在一些简单的二维问题上对其进行测试:
# Even penalty
solve.my.QP(c(0, 0), 1, diag(1, 2))
# [1] 0.5 0.5
# Encourage inclusion of first variable
solve.my.QP(c(0.1, 0), 1, diag(1, 2))
# [1] 0.525 0.475