R中的约束优化

use*_*215 14 optimization r constraints

我试图在R中使用http://rss.acs.unt.edu/Rdoc/library/stats/html/constrOptim.html在R中进行优化,但是有一些给定的线性约束,但是无法弄清楚如何设置问题.

例如,我需要最大化$ f(x,y)= log(x)+\frac {x ^ 2} {y ^ 2} $受限于约束$ g_1(x,y)= x + y <1 $ ,$ g_2(x,y)= x> 0 $和$ g_3(x,y)= y> 0 $.我如何在R中执行此操作?这只是一个假设的例子.不要担心它的结构,而是我有兴趣知道如何在R中设置它.

谢谢!

42-*_*42- 19

设置该功能是微不足道的:

fr <- function(x) {      x1 <- x[1]
    x2 <- x[2]
    -(log(x1) + x1^2/x2^2)  # need negative since constrOptim is a minimization routine
}
Run Code Online (Sandbox Code Playgroud)

由于缺少大量文档,设置约束矩阵是有问题的,我采用了实验.帮助页面显示"可行区域由ui%*%theta - ci> = 0"定义.所以我测试了,这似乎"工作":

> rbind(c(-1,-1),c(1,0), c(0,1) ) %*% c(0.99,0.001) -c(-1,0, 0)
      [,1]
[1,] 0.009
[2,] 0.990
[3,] 0.001
Run Code Online (Sandbox Code Playgroud)

所以我为每个约束/边界排成一行:

constrOptim(c(0.99,0.001), fr, NULL, ui=rbind(c(-1,-1),  # the -x-y > -1
                                              c(1,0),    # the x > 0
                                              c(0,1) ),  # the y > 0
                                           ci=c(-1,0, 0)) # the thresholds
Run Code Online (Sandbox Code Playgroud)

对于这个问题,存在一个潜在的困难,即对于x的所有值,函数作为y - > 0进入Inf.即使我将起始值推出到x,也会得到x = .95和y = 0的最大值. "角落",但我有点怀疑这不是我想到的在"角落"里面的真正最大值.编辑:追求这个我推断渐变可能提供额外的"方向"并添加了渐变功能:

grr <- function(x) { ## Gradient of 'fr'
    x1 <- x[1]
    x2 <- x[2]
    c(-(1/x[1] + 2 * x[1]/x[2]^2),
       2 * x[1]^2 /x[2]^3 )
}
Run Code Online (Sandbox Code Playgroud)

这确实使得优化更加靠近c(.999 ...,0)角,而不是远离它,就像它对某些起始值所做的那样.我仍然有些失望的是,当起始值接近可行区域的中心时,这个过程似乎"走向悬崖":

 constrOptim(c(0.99,0.001), fr, grr, ui=rbind(c(-1,-1),  # the -x-y > -1
                                               c(1,0),    # the x > 0
                                               c(0,1) ),  # the y > 0
                                            ci=c(-1,0, 0) )
$par
[1]  9.900007e-01 -3.542673e-16

$value
[1] -7.80924e+30

$counts
function gradient 
    2001       37 

$convergence
[1] 11

$message
[1] "Objective function increased at outer iteration 2"

$outer.iterations
[1] 2

$barrier.value
[1] NaN
Run Code Online (Sandbox Code Playgroud)

注意:Hans Werner Borchers在R-Help上发布了一个更好的例子,通过设置稍微远离边缘的约束来成功获得角点值:

> constrOptim(c(0.25,0.25), fr, NULL, 
              ui=rbind( c(-1,-1), c(1,0),   c(0,1) ),  
              ci=c(-1, 0.0001, 0.0001)) 
$par
[1] 0.9999 0.0001
Run Code Online (Sandbox Code Playgroud)