我试着用控件解决非线性方程。
这是我的代码。
fun <- function(x) {
b0 <- (0.64*1+(1-0.64)*x[1]*(x[2]*x[1]-1)+x[1]*1*(1-x[2])*x[3])/(x[1]-1) -1805*2.85*0.64
b1plus <- (0.64*1+(1-0.64)*x[1]*(x[2]*x[1]-1.01)+x[1]*1.01*(1-x[2])*x[3])/(1.01*(x[1]-1)) -1805*2.85*0.64*(1+0.00235)
b1minus <- (0.64*1+(1-0.64)*x[1]*(x[2]*x[1]-0.99)+x[1]*0.99*(1-x[2])*x[3])/(0.99*(x[1]-1)) -1805*2.85*0.64*(1-0.00235)
return(c(b0,b1plus,b1minus))
}
multiroot(fun,c(1.5, 0, 0))
然而,我得到的结果却远远超出了实际的结果。我希望将x1控制在(1.5,4),x2(0,1),x3(0,10000)的范围内。请问如何才能做到这一点?
牛顿-拉弗逊 "等方法在。multiroot
或 nleqslv
与边界约束一起使用效果不好。一种可能的方法是将你的函数的各部分进行平方和
fun1 <- function(x) sum(fun(x)^2)
然后将其视为一个全局优化问题,在这个问题中,你希望得到一个最小值的 0.0
. 例如: GenSA 提供了一个 "模拟退火 "的实现,在低维度的情况下效果相当好。
library(GenSA)
res <- GenSA(par=NULL, fn=fun1,
lower=c(1.5,0,0), upper=c(4,1,10000),
control=list(maxit=10e5))
res$value; res$par
## [1] 119.7869
## [1] 4.00 0.00 2469.44
几次尝试都没有找到比这个更低的函数值,这让我觉得你要求的约束框中没有共同的根。