带约束的R-二次多维优化

带约束的R-二次多维优化,r,constraints,quadratic,nonlinear-optimization,R,Constraints,Quadratic,Nonlinear Optimization,我试图解决以下函数的二次优化: b<-4.7e-09 a<-(-2e-05) M<-100 beta<-0.5 min<-fuction(x){ x1=x[1] x2=x[2] x3=x[3] E=a*x1+b*x1^2+a*x2+b*x2^2+a*x3+b*x3^2 V=(M-x1)+(M-x1-x2)+(M-x1-x2-x3) return (E+beta*V) } 有没有一种方法可以使用constrOptim或

我试图解决以下函数的二次优化:

b<-4.7e-09
a<-(-2e-05)
M<-100
beta<-0.5
min<-fuction(x){
    x1=x[1]
    x2=x[2]
    x3=x[3]
    E=a*x1+b*x1^2+a*x2+b*x2^2+a*x3+b*x3^2
    V=(M-x1)+(M-x1-x2)+(M-x1-x2-x3)
    return (E+beta*V)
}
有没有一种方法可以使用constrOptim或solve.QP解决此问题

不一定,但整体优化会更好


非常感谢您的评论。

[注意:在下面的内容中,我将您的函数称为
f(…)
,以避免与内置的R函数
min(…)
混淆。此外,我假设您的代码中的
x2=x[3]
是一个错误,您需要
x2=x[2]
]

首先,在你诉诸数值优化之前,你应该先做一些基础数学。如席≥ 0和<代码>求和(x)=m < /代码>,然后是席≤ 所以我们在一个有边(0,M)的立方体中运行。此外,如果
sum(x)=M
,那么我们实际上只有两个自变量(比如x1和x2)和x3=M-(x1+x2)。我们可以通过以下方式相对容易地确定最小值:

x    <- seq(0,M,len=101)
df   <- expand.grid(x=x,y=x)
df$f <- mapply(function(x,y) f(c(x,y,M-(x+y))),df$x,df$y)
df$f <- ifelse(df$x+df$y>M,NA,df$f)
df[which.min(df$f),]
#       x y         f
# 101 100 0 -0.001953

所以曲面是一个平面,最小值实际上是(100,0,0)


最后,我们当然可以使用一个数值优化器(对于这个问题,IMO做得太过分了——当然,除非这是一个家庭作业??)。这里我们使用来自同名包的
nloptr(…)
f(…)
是要最小化的函数,
g(…)
是用不等式表示的约束,
abs(sum(x)-M)看看
nloptr
包。谢谢你的回答!它应该是x2=x[2],很抱歉输入错误。我在我的电脑上试过,唯一的问题是当使用
nloptr
时,最佳值是
100,0,2.220446e-16
。总和比M大,不是。这是舍入错误:2.2e-16本质上是0。我刚刚运行了上面的代码,它向我返回了以下错误:
将*x1:非数字参数中的错误传递给二进制运算符。
结果中
x    <- seq(0,M,len=101)
df   <- expand.grid(x=x,y=x)
df$f <- mapply(function(x,y) f(c(x,y,M-(x+y))),df$x,df$y)
df$f <- ifelse(df$x+df$y>M,NA,df$f)
df[which.min(df$f),]
#       x y         f
# 101 100 0 -0.001953
library(reshape2)     # for dcast(...)
library(rgl)          # for surface3d(...), etc.
z       <- dcast(df,x~y,value.var="f")[-1]
zlim    <- range(z[!is.na(zz)])
palette <- rev(heat.colors(10))
col     <- palette[9*(df$f-zlim[1])/diff(zlim) + 1] 
surface3d(x,x,as.matrix(zz),color=col)
axes3d()
title3d(xlab="X",ylab="Y",zlab="Z")
f <-function(x){                   # objective function
  x1=x[1]
  x2=x[2]
  x3=x[3]
  E=a*x1+b*x1^2+a*x2+b*x2^2+a*x3+b*x3^2
  V=(M-x1)+(M-x1-x2)+(M-x1-x2-x3)
  return (E+beta*V)
}
g <- function(x) {abs(sum(x)-M)}   # constraint function

library(nloptr)
result <-nloptr(c(0,0,0), f, lb=c(0,0,0), eval_g_ineq=g,
                opts = list(algorithm="NLOPT_LN_COBYLA"))
result$solution
# [1] 1.000000e+02 4.440892e-16 4.835780e-16