Przy tej okazji optim
nie będzie działać w sposób oczywisty, ponieważ masz ograniczenia równości. constrOptim
nie będzie działać z tego samego powodu (próbowałem przekonwertować równość na dwie nierówności, tj. Większą i mniejszą niż 15, ale to nie zadziałało z constrOptim
).
Istnieje jednak pakiet dedykowany do tego rodzaju problemów i jest to Rsolnp
.
go używać w następujący sposób:
#specify your function
opt_func <- function(x) {
10 - 5*x[1] + 2 * x[2] - x[3]
}
#specify the equality function. The number 15 (to which the function is equal)
#is specified as an additional argument
equal <- function(x) {
x[1] + x[2] + x[3]
}
#the optimiser - minimises by default
solnp(c(5,5,5), #starting values (random - obviously need to be positive and sum to 15)
opt_func, #function to optimise
eqfun=equal, #equality function
eqB=15, #the equality constraint
LB=c(0,0,0), #lower bound for parameters i.e. greater than zero
UB=c(100,100,100)) #upper bound for parameters (I just chose 100 randomly)
wyjściowa:
> solnp(c(5,5,5),
+ opt_func,
+ eqfun=equal,
+ eqB=15,
+ LB=c(0,0,0),
+ UB=c(100,100,100))
Iter: 1 fn: -65.0000 Pars: 14.99999993134 0.00000002235 0.00000004632
Iter: 2 fn: -65.0000 Pars: 14.999999973563 0.000000005745 0.000000020692
solnp--> Completed in 2 iterations
$pars
[1] 1.500000e+01 5.745236e-09 2.069192e-08
$convergence
[1] 0
$values
[1] -10 -65 -65
$lagrange
[,1]
[1,] -5
$hessian
[,1] [,2] [,3]
[1,] 121313076 121313076 121313076
[2,] 121313076 121313076 121313076
[3,] 121313076 121313076 121313076
$ineqx0
NULL
$nfuneval
[1] 126
$outer.iter
[1] 2
$elapsed
Time difference of 0.1770101 secs
$vscale
[1] 6.5e+01 1.0e-08 1.0e+00 1.0e+00 1.0e+00
Tak powstałe optymalnymi wartościami są:
$pars
[1] 1.500000e+01 5.745236e-09 2.069192e-08
co oznacza, że pierwszy parametr jest 15 i reszta zero i zero. Jest to rzeczywiście minimum globalne w twojej funkcji, ponieważ x2 dodaje się do funkcji, a 5 * x1 ma znacznie większy (negatywny) wpływ niż x3 na wynik. Wybór 15, 0, 0 jest rozwiązaniem i globalnym minimum dla funkcji zgodnie z ograniczeniami.
Funkcja działała świetnie!
Niezły! Kiedy PO mówi: "To jest uproszczony przykład prawdziwego problemu", to myślę, że rzeczywisty problem może być nieliniowy. Tak więc, aby upewnić się, zasugerowałem metodę nieliniową (która działa mimo to, nawet jeśli jest wolniejsza). Zapewnienie gradientu (prostego w tym przypadku) czyni go jeszcze szybszym, jeśli prędkość jest problemem. W każdym razie, nie mam na myśli złego, to naprawdę dobrze, że dodałaś tę odpowiedź, zdecydowanie pomocna. – LyzandeR