0

我想在 R 中解决一个非常简单的二次优化问题,其中一个约束是与向量之和相关的等式约束。我尝试使用 quadprog 包,但我不知道如何使它工作。帮助函数没有提供其中一个约束等于总和的示例。但也许 quadprog 不是正确使用的包......

我的问题如下。我想缩小/扩展一个值向量,使总和等于设定值,并且它们的值受 0 和最大值的约束。由于结果需要尽可能接近初始值,我想最小化残差平方和。下面我介绍一个玩具示例。很容易看出,例如(5,5,6)在解空间中,但不是最优解。

x_start <- c(4,3,7)
tot <- 16

# Objective function that needs to be minimized
obj <- function(x){return((x-x_start)^2)}

# Subject to: 
# Sum constraint
con1 <- function(x) {return(sum(x)-tot)}

# Bounds 0 <= x <=6
x_max <- 6
x_min <- 0

4

2 回答 2

1

R 中有许多包可用于此目的。请参阅 CRAN 上的优化任务视图:https ://cran.r-project.org/web/views/Optimization.html

这里有两种可能性。

1)CVXR我们可以使用CVXR进行凸优化。

library(CVXR)

x_start <- c(4,3,7)
tot <- 16

x <- Variable(3)
objective <- Minimize(sum((x - x_start)^2))
constraints <- list(sum(x) == tot, x >= 0, x <= 6)
problem <- Problem(objective, constraints)
soln <- solve(problem)
xval <- soln$getValue(x)
xval
##          [,1]
## [1,] 5.500036
## [2,] 4.499964
## [3,] 6.000000

soln$value
## [1] 5.5

soln$status
## [1] "optimal"

2) limSolve另一个可以做到这一点的包是limSolve。这解决了在 Ex = F 和 Gx >= H 的向量 x 上最小化 ||Ax-B||^2 的问题。

library(limSolve)
lsei(A = diag(3), B = x_start, 
  E = rep(1, 3), F = tot, 
  G = rbind(diag(3), -diag(3)), H = c(0, 0, 0, -6, -6, -6))

给予:

$X
[1] 5.5 4.5 6.0

$residualNorm
[1] 7.105427e-15

$solutionNorm
[1] 5.5

$IsError
[1] FALSE

$type
[1] "lsei"
于 2019-11-07T17:19:39.803 回答
1

尝试以矩阵和向量的形式表达您的二次问题(即目标和约束)。对于和约束,您可以使用向量的和是向量的点积这一事实,因此约束矩阵上的对应行是c(1,1,1)并且该约束的 rhs 是tot

根据文档meq参数 insolve.QP(Dmat, dvec, Amat, bvec, meq=0, factorized=FALSE)指定相等约束的约束数量,

第一个meq约束被视为等式约束

因此,将此参数更改为 1(或您需要的许多等式约束)并制作Amat一个向量的第一列。

于 2019-11-07T17:49:30.703 回答