R optimization with equality and inequality constraints

后端 未结 3 749
情深已故
情深已故 2020-12-03 15:14

I am trying to find the local minimum of a function, and the parameters have a fixed sum. For example,

Fx = 10 - 5x1 + 2x2 - x3

and the cond

3条回答
  •  南方客
    南方客 (楼主)
    2020-12-03 15:50

    On this occasion optim will not work obviously because you have equality constraints. constrOptim will not work either for the same reason (I tried converting the equality to two inequalities i.e. greater and less than 15 but this didn't work with constrOptim).

    However, there is a package dedicated to this kind of problem and that is Rsolnp.

    You use it the following way:

    #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
    

    So the resulting optimal values are:

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

    which means that the first parameter is 15 and the rest zero and zero. This is indeed the global minimum in your function since the x2 is adding to the function and 5 * x1 has a much greater (negative) influence than x3 on the outcome. The choice of 15, 0, 0 is the solution and the global minimum to the function according to the constraints.

    The function worked great!

提交回复
热议问题