2015-05-27 20 views
6

Tôi đang cố gắng tìm mức tối thiểu cục bộ của một hàm và các tham số có tổng cố định. Ví dụ,R tối ưu hóa với các ràng buộc bình đẳng và bất bình đẳng

Fx = 10 - 5x1 + 2x2 - x3

và các điều kiện như sau,

x1 + x2 + x3 = 15

(x1, x2, x3)> = 0

Trường hợp tổng x1, x2 và x3 có giá trị đã biết và tất cả chúng lớn hơn 0. Trong R, nó sẽ trông giống như thế này,

Fx = function(x) {10 - (5*x[1] + 2*x[2] + x[3])} 
opt = optim(c(1,1,1), Fx, method = "L-BFGS-B", lower=c(0,0,0), upper=c(15,15,15)) 

Tôi cũng cố gắng sử dụng sự bất bình đẳng với constrOptim để buộc tổng được cố định. Tôi vẫn nghĩ rằng đây có thể là một công việc hợp lý, nhưng tôi không thể làm cho nó hoạt động được. Đây là một ví dụ đơn giản về vấn đề thực sự, nhưng bất kỳ sự trợ giúp nào cũng sẽ được đánh giá rất cao.

Trả lời

6

Nhân dịp này optim sẽ không làm việc rõ ràng bởi vì bạn có những hạn chế bình đẳng. constrOptim sẽ không hoạt động hoặc vì cùng một lý do (tôi đã thử chuyển đổi bình đẳng thành hai sự bất bình đẳng nghĩa là lớn hơn và nhỏ hơn 15 nhưng điều này không hoạt động với constrOptim).

Tuy nhiên, có một gói phần mềm dành riêng cho loại vấn đề và đó là Rsolnp.

Bạn sử dụng nó theo cách sau:

#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) 

Output:

> 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 

Vì vậy, các giá trị tối ưu kết quả là:

$pars 
[1] 1.500000e+01 5.745236e-09 2.069192e-08 

có nghĩa là tham số đầu tiên là 15 và phần còn lại bằng không và không. Đây thực sự là mức tối thiểu toàn cầu trong hàm của bạn kể từ khi x2 được thêm vào hàm và 5 * x1 có ảnh hưởng lớn hơn nhiều (âm) so với x3 trên kết quả. Sự lựa chọn của 15, 0, 0 là giải pháp và tối thiểu toàn cầu cho hàm theo các ràng buộc.

Chức năng hoạt động tuyệt vời!

4

Đây thực sự là một vấn đề lập trình tuyến tính, do đó, cách tiếp cận tự nhiên sẽ là sử dụng bộ giải mã lập trình tuyến tính chẳng hạn như gói lpSolve. Bạn cần cung cấp một hàm mục tiêu và một ma trận hạn chế và giải quyết sẽ làm phần còn lại:

library(lpSolve) 
mod <- lp("min", c(-5, 2, -1), matrix(c(1, 1, 1), nrow=1), "=", 15) 

Sau đó, bạn có thể truy cập các giải pháp tối ưu và giá trị khách quan (thêm giá trị bất biến 10, mà không được cung cấp cho giải):

mod$solution 
# [1] 15 0 0 
mod$objval + 10 
# [1] -65 

một giải quy hoạch tuyến tính nên có một thỏa thuận tốt nhanh hơn một người giải quyết tối ưu hóa phi tuyến nói chung và không nên gặp khó khăn khi trả lại giải pháp tối ưu chính xác (thay vì một điểm gần đó có thể bị lỗi làm tròn số).

+1

Đẹp nhất! Khi OP nói: "Đây là một ví dụ đơn giản về vấn đề thực sự" nó làm cho tôi nghĩ rằng vấn đề thực tế có thể là phi tuyến. Vì vậy, chỉ để chắc chắn tôi đề nghị một phương pháp phi tuyến (mà hoạt động anyway ngay cả khi nó là chậm hơn). Cung cấp gradient (đơn giản cho trường hợp này) làm cho nó thậm chí còn nhanh hơn nếu tốc độ là một vấn đề. Dù sao, tôi không có ý xấu, nó thực sự là tốt mà bạn thêm câu trả lời này, chắc chắn hữu ích. – LyzandeR

Các vấn đề liên quan