решить простую квадратичную оптимизацию в R с ограничением суммы - PullRequest
0 голосов
/ 07 ноября 2019

Я хочу решить очень простую задачу квадратичной оптимизации в 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

Ответы [ 2 ]

1 голос
/ 07 ноября 2019

В 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. Это решает проблему минимизации || Ax-B || ^ 2 над вектором x с учетом Ex = F и Gx> = H.

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"
0 голосов
/ 07 ноября 2019

Попытайтесь выразить свою квадратичную задачу (т.е. цель и ограничения) в матричной и векторной форме. Для ограничения суммы вы можете использовать тот факт, что сумма векторов является точечным произведением с вектором единиц, поэтому соответствующая строка в матрице ограничений равна c(1,1,1), а rhs для этого ограничения - tot.

В соответствии с документацией , параметр meq в solve.QP(Dmat, dvec, Amat, bvec, meq=0, factorized=FALSE) указывает количество ограничений, являющихся ограничениями равенства,

первое meqограничения рассматриваются как ограничения равенства

, поэтому измените этот параметр на 1 (или сколько угодно ограничений равенства) и сделайте первый столбец Amat вектором из них.

...