我有一个关于如何在目标函数中表达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?
中的命令提前多多感谢。
答案 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