начальные значения constrOptim - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь использовать функцию constrOptim() в R для оптимизации:

2x + 2y + 3z

при условии:

-2x + y + z <= 1

4x - y + 3z <= 3

x, y, z >= 0

То, что у меня пока есть, таково:

ui = matrix(c(2,-1,-1,-4, 1,-3, 1, 0, 0, 0, 1, 0, 0, 0, 1),
                     nrow = 5,
                     byrow = T)

ci = c(-1, -3, 0, 0, 0)
theta = c(0, 1, 0)

constrOptim(
  theta = theta,
  f = func,
  ui = ui,
  ci = ci)

Это дает мне ошибку, что " начальное значение не во внутреннем допустимом районе". Однако, если я запускаю следующее в качестве теста:

ui = matrix(c(2,-1,-1,-4, 1,-3, 1, 0, 0, 0, 1, 0, 0, 0, 1),
                     nrow = 5,
                     byrow = T)

ci = c(-1, -3, 0, 0, 0)
theta = c(0, 1, 0)

ui %*% theta - ci

, я получаю (0 4 0 1 0), что определенно> = 0.

У меня вопрос, почему я получаю сообщение об ошибке, сообщающее мне что ui %*% theta - ci не> = 0, когда это ясно? Чего мне не хватает?

Редактировать: удалось разобраться благодаря Стефану Лорану .

Есть какие-нибудь идеи, как наилучшим образом построить возможную область в R? Какие-нибудь полезные пакеты?

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

Начальное значение должно быть в внутренней части допустимой области, поэтому вам нужно > 0, а не >= 0. Вы можете использовать theta = c(0.1, 1, 0.1)

ui = matrix(c(2,-1,-1,-4, 1,-3, 1, 0, 0, 0, 1, 0, 0, 0, 1),
            nrow = 5,
            byrow = T)
ci = c(-1, -3, 0, 0, 0)
theta = c(0.1, 1, 0.1)

all(ui %*% theta - ci > 0) # TRUE

constrOptim(
  theta = theta,
  f = function(xyz) c(crossprod(c(2,2,3), xyz)),
  grad = NULL,
  ui = ui,
  ci = ci)

Кстати, мне кажется очевидным, что решение - c(0,0,0).

0 голосов
/ 18 февраля 2020

Причина ошибки была объяснена из ответа Стефана Лорана .

Альтернативой constrOptim является использование fmincon из пакета pracma, и вы можете выполнить код без ошибок даже с начальными значениями на границе, т. е. theta = c(0,1,0)

ui = matrix(c(2,-1,-1,-4, 1,-3, 1, 0, 0, 0, 1, 0, 0, 0, 1),
            nrow = 5,
            byrow = T)
ci = c(-1, -3, 0, 0, 0)
theta = c(0, 1, 0)
func <- function(v) crossprod(c(2,2,3),v)

res <- pracma::fmincon(theta,
                       f = func,
                       A = -ui,
                       b = -ci)

таким, что

> res
$par
[1] 0 0 0

$value
     [,1]
[1,]    0

$convergence
[1] 0

$info
$info$lambda
$info$lambda$lower
     [,1]
[1,]    0
[2,]    0
[3,]    0

$info$lambda$upper
     [,1]
[1,]    0
[2,]    0
[3,]    0

$info$lambda$ineqlin
[1] 0 0 2 2 3


$info$grad
     [,1]
[1,]    2
[2,]    2
[3,]    3

$info$hessian
     [,1] [,2] [,3]
[1,]    1 0.00    0
[2,]    0 0.03    0
[3,]    0 0.00    1
...