郭岚 2019-06-25
$$f(x_1,x_2)=(1-x_1)^2+100(x_2-x_1^2)^2$$
该函数全局最小值在($x_1=1,x_2=1$)时取到。
下面这种写法是因为有多个自变量函数,传入一个参数x,每个自变量用向量x的分量来表示,从而定义出目标函数。
obj <- function(x){ x1 <- x[1] x2 <- x[2] y <- 100*(x2-x1^2)^2+(1-x1)^2 return(y) }
x1梯度:$-400*x_1*(x_2-x_1^2)-2*(1-x_1)$
x2梯度:$200*(x_2-x_1^2)$
梯度:
gradient <- function(x){ x1 <- x[1] x2 <- x[2] c(x1_gradient = -400*x1*(x2-x1^2)-2*(1-x1), x2_gradient =200*(x2-x1^2)) }
tip:对于多元函数,需要用向量的形式来输出各个变量上的梯度。
下面以$x_1=0,x_2=3$作为起始点,其他参数采用默认设置,梯度也不输入。(默认时优化算法为单纯型法)
optim(par = c(0,3),fn=obj)
convergence是收敛的代码
method:优化方法,通过字符串形式传入,表示优化求解的算法,
Nelder-Mead:单纯型法,为optim默认优化算法。
使用CG共轭梯度法在默认的迭代次数下求解:
optim(par = c(0,3),fn=obj)
发现算法到达迭代次数上限而退出。
我们增加迭代次数:
optim(par = c(0,3),fn=obj,method = "CG",control = list(maxit=500))
可以发现目标函数的值可以减少,进一步增加迭代的次数可以得到最优解,但是效率上比默认的Nelder-Mead单纯型法差太多。注意:CG已经使用梯度信息,不需要我们自己传入自定义的gradient函数
如果我们使用拟牛顿法BFGS,下面分别为不传入梯度信息与自己传入梯度信息
optim(par = c(0,3),fn=obj,method = "BFGS")
optim(par = c(0,3),fn=obj,gr=gradient,method = "BFGS")