非线性优化问题中的错误:“ x”中的值无穷或缺失

时间:2018-11-03 10:53:14

标签: r nonlinear-optimization

我必须在仿真研究中考虑优化问题。实例如下:

library(mvtnorm)
library(alabama)

n = 200
q = 0.5
X <- matrix(0, nrow = n, ncol = 2)
X[,1:2] <- rmvnorm(n = n, mean = c(0,0), sigma = matrix(c(1,1,1,4),
                                                          ncol = 2))
x0 = matrix(c(X[1,1:2]), nrow = 1)
y0 = x0 - 0.5 * log(n) * (colMeans(X) - x0)
X = rbind(X, y0)

x01 = y0[1]
x02 = y0[2]
x1 = X[,1]
x2 = X[,2]

pInit = matrix(rep(1/(n + 1), n + 1), nrow = n + 1) 

f1 <- function(p) mean(((n + 1) * p ) ^ q)

heq1 <- function(p)
  c(sum(x1 * p) - x01, sum(x2 * p) - x02, sum(p) - 1)

sol <- alabama::auglag(pInit, fn = function(p) -f1(p), heq = heq1)
cat("The maximum objective value is:", -sol$value, '\n')

这会导致错误:

Error in eigen(a$hessian, symmetric = TRUE, only.values = TRUE) : 
  infinite or missing values in 'x'

我不确定如何指出和克服这个问题。如果由于初始点指定错误而发生这种情况,如何在仿真工作中指定它,以便程序本身可以设置合适的初始点并给出正确的解决方案?否则,为什么会发生此错误,以及如何消除该错误?有人可以帮忙吗?谢谢!

2 个答案:

答案 0 :(得分:0)

如前所述,请参见Maximizing nonlinear constraints problem using r package nloptr
您必须防止求解器进入未定义目标函数的区域,这意味着每个索引p_i >= 0的{​​{1}}。如果确实如此,则让目标函数返回某个有限值。简化功能(对于i),例如,

q = 0.5

更好地为f1 <- function(p) sum(sqrt(pmax(0, p))) 提供不等式约束

p_i > 0

现在求解器返回一个合理的结果:

heq1 <- function(p) c(sum(x1 * p) - x01, sum(x2 * p) - x02, sum(p) - 1)
hin1 <- function(p) p - 1e-06

所有相等条件都满足:

sol <- alabama::auglag(pInit, fn = function(p) -f1(p), 
                       heq = heq1, hin = hin1)

-1 * sol$value
## [1] 11.47805

所有这一切都可以自然地“以编程方式”完成,只要稍加小心即可。

答案 1 :(得分:0)

此答案是第一个答案的附录,尤其针对您的第二个问题,该问题涉及显着加快整个过程。

为了使运行时间估计可重复,我们将修复种子; 所有其他定义都是您的。

set.seed(4789)
n = 200
q = 0.5
X <- mvtnorm::rmvnorm(n = n, mean = c(0,0),
                      sigma = matrix(c(1,1,1,4), ncol = 2))
x0 = matrix(c(X[1,1:2]), nrow = 1)
y0 = x0 - 0.5 * log(n) * (colMeans(X) - x0)
X = rbind(X, y0)
x01 = y0[1]; x02 = y0[2]
x1 = X[,1]; x2 = X[,2]
pInit = matrix(rep(1/(n + 1), n + 1), nrow = n + 1) 

首先,让我们使用增强的Lagrangian和optim()作为内部求解器来实现。

f1 <- function(p) sum(sqrt(pmax(0, p)))
heq1 <- function(p) c(sum(x1 * p) - x01, sum(x2 * p) - x02, sum(p) - 1)
hin1 <- function(p) p - 1e-06
system.time( sol <- alabama::auglag(pInit, fn = function(p) -f1(p), 
                           heq = heq1, hin = hin1) )
##    user  system elapsed 
##  24.631   0.054  12.324 
-1 * sol$value; heq1(sol$par)
## [1] 7.741285
## [1] 1.386921e-09 3.431108e-10 4.793488e-10

此问题是具有线性约束的。因此,我们可以应用高效的凸解算器,例如ECOS。对于建模,我们将使用CVXR软件包。

# install.packages(c("ECOSolveR", "CVXR"))
library(CVXR)

p <- Variable(201)
obj <- Maximize(sum(sqrt(p)))
cons <- list(p >= 0, sum(p) == 1,
             sum(x1*p)==x01, sum(x2*p)==x02)
prbl <- Problem(obj, cons)
system.time( sol <- solve(prbl, solver="ECOS") )
##    user  system elapsed 
##   0.044   0.000   0.044 

ps <- sol$getValue(p)
cat("The maximum value is:", sum(sqrt(pmax(0, ps))))
## The maximum value is: 7.74226
c(sum(ps), sum(x1*ps) - x01, sum(x2*ps) - x02)
## [1]  1.000000e+00 -1.018896e-11  9.167819e-12

我们看到的是凸解算器(!)快于第一个使用标准非线性解算器的方法。重要提示:我们不需要起始值,因为凸问题只有一个最优值。