如何在R的quadprog中表达x1 * x2

时间:2016-05-14 09:36:18

标签: r optimization

我有一个关于如何在目标函数中表达x1x2的问题。 这是互联网上的一个例子。

##
## min x1^2 +2x2^2 + 4x3^2 - x1 - x2 + 5x3
## x1 + x3 <= 1
## x1 >= 5
## x2 <= 0
##

P = 2*diag (c (1, 2, 4));
d = c (-1, -1, 5);
A = matrix (0, nrow=3, ncol=3);
A[1,] = c(-1, 0, -1);
A[2,] = c( 1, 0, 0);
A[3,] = c( 0, -1, 0);
b = c(-1, 5, 0);

从示例中,目标结果为x1^2 +2x2^2 + 4x3^2 - x1 - x2 + 5x3

在R中,它是P = 2*diag (c (1, 2, 4)); d = c (-1, -1, 5);

但是,如果我有一个像x1x2或x1 ^ 2这样的目标函数 如何键入R?

中的命令

提前多多感谢。

1 个答案:

答案 0 :(得分:0)

solve.QP函数最小化以下表达式:

min 1/2 * (t(x) %*% D %*% x) - t(d) %*% x

其中x是n变量的向量(例如x1,x2 ......),D n x n系数的对称矩阵和d向量{ {1}}系数。

为了理解这些矩阵产品如何转化为目标函数表达式,我创建了以下简单函数来扩展给定输入的quadprog目标:

n

通过用文字系数调用它,我们可以很容易地理解如何设置这些系数以获得我们想要的结果:

# Given matrix D and vector d that will be passed to solve.QP, 
# it returns the objective function expression as string
expandQPObj <- function(D, d, var.name = 'x') {
  # helper function that expands a matrix product. NB it does not compute the result, 
  # it just returns the expressions of each element of the resulting matrix
  expandMatrixProd <- function(m1, m2) {
    m1 <- as.matrix(m1)
    m2 <- as.matrix(m2)
    if (ncol(m1) != nrow(m2)) { stop("incompatible dimensions")  }
    n <- nrow(m1)
    m <- ncol(m2)
    res <- matrix('', nrow = n, ncol = m)
    for (i in 1:n) {
      for (j in 1:m) {
        a <- m1[i, ]
        b <- m2[, j]
        a <- ifelse(grepl('[+*]', a), paste0('(', a, ')'), a)
        b <- ifelse(grepl('[+*]', b), paste0('(', b, ')'), b)
        res[i, j] <- gsub('+-','-',paste(a, b, sep = '*', collapse = '+'),fixed = TRUE)
      }
    }
    return(res)
  }
  D <- as.matrix(D)
  d <- as.vector(d)
  n <- length(d)
  if (!all(dim(D) == n) || n == 0) {
    stop('Dimensions problem: D should be an nxn matrix and d a vector of length n (n>0)')
  }
  xvec <- paste(var.name, 1:n, sep = '')
  quadComp <- as.vector(Reduce(list(t(xvec), D, xvec),f=expandMatrixProd))
  linearComp <- as.vector(strMatrixMult(t(d), xvec))
  return(paste0('1/2*(', quadComp, ') - (', linearComp, ')'))
}

所以,为了得到:

Dliteral <- matrix(paste0('D',1:9),nrow=3,byrow = T)
#     [,1] [,2] [,3]
#[1,] "D1" "D2" "D3"
#[2,] "D4" "D5" "D6"
#[3,] "D7" "D8" "D9"

dliteral <- paste0('d',1:3)
#[1] "d1" "d2" "d3"

expandQPObj(Dliteral,dliteral)
#"1/2*((x1*D1+x2*D4+x3*D7)*x1+(x1*D2+x2*D5+x3*D8)*x2+(x1*D3+x2*D6+x3*D9)*x3) - d1*x1+d2*x2+d3*x3"

我们需要设置min x1*x2 (不只是D2=1 and D4=1,因为矩阵D2=2必须是对称的!)而所有其他系数= 0,因此:

D

同样,要获得:

D = rbind(c(0,1,0),c(1,0,0),c(0,0,0))
#     [,1] [,2] [,3]
#[1,]    0    1    0
#[2,]    1    0    0
#[3,]    0    0    0
d <- rep(0,3)
#[1] 0 0 0

expandQPObj(D,d)
[1] "1/2*((x1*0+x2*1+x3*0)*x1+(x1*1+x2*0+x3*0)*x2+(x1*0+x2*0+x3*0)*x3) - 0*x1+0*x2+0*x3"

我们需要设置min x1^2 (== min x1*x1) ,其他所有系数= 0:

D1=2