Nothing
#' Variable neighborhood trust region search.
#' @description
#' This function performs variable neighborhood trust region search.
#' @references
#' Bierlaire et al. (2009) "A Heuristic for Nonlinear Global Optimization"
#' \doi{10.1287/ijoc.1090.0343}.
#' @inheritParams check_f
#' @param minimize
#' If \code{TRUE}, \code{f} gets minimized. If \code{FALSE}, maximized.
#' @inheritParams check_controls
#' @param quiet
#' If \code{TRUE}, progress messages are suppressed.
#' @param seed
#' Set a seed for the sampling of the random starting points.
#' @return
#' A data frame. Each row contains information of an identified optimum. The
#' first \code{npar} columns \code{"p1"},...,\code{"p<npar>"} store the argument
#' values, the next column \code{"value"} has the optimal function values and
#' the last column \code{"global"} contains \code{TRUE} for global optima and
#' \code{FALSE} for local optima.
#' @examples
#' rosenbrock = function(x) {
#' stopifnot(is.numeric(x))
#' stopifnot(length(x) == 2)
#' f = expression(100 * (x2 - x1^2)^2 + (1 - x1)^2)
#' g1 = D(f, "x1")
#' g2 = D(f, "x2")
#' h11 = D(g1, "x1")
#' h12 = D(g1, "x2")
#' h22 = D(g2, "x2")
#' x1 = x[1]
#' x2 = x[2]
#' f = eval(f)
#' g = c(eval(g1), eval(g2))
#' h = rbind(c(eval(h11), eval(h12)), c(eval(h12), eval(h22)))
#' list(value = f, gradient = g, hessian = h)
#' }
#' vntrs(f = rosenbrock, npar = 2, seed = 1, controls = list(neighborhoods = 1))
#' @export
vntrs = function(f, npar, minimize = TRUE, controls = NULL, quiet = TRUE,
seed = NULL) {
### check inputs
if(!is.logical(minimize))
stop("'minimize' must be a boolean.")
if(!is.logical(quiet))
stop("'quiet' must be a boolean.")
if(quiet){
sink(tempfile())
on.exit(sink())
}
if(!is.null(seed))
set.seed(seed)
cat("Check controls.\n")
controls = check_controls(controls = controls)
if(!is.null(controls$time_limit))
start_time = Sys.time()
cat("Check function.\n")
check_f(f = f, npar = npar, controls = controls)
### initialization of variable neighborhood search
cat("Initialize VNTRS.\n")
initialization = initialize(f = f, npar = npar, minimize = minimize,
controls = controls)
L = initialization$L
x_best = initialization$x_best
### iterative variable neighborhood search
cat("Start VNTRS.\n")
k = 1
stop = FALSE
while(k <= controls$neighborhoods){
if(stop) break
### select neighbors
cat(paste0("* Select neighborhood ",k,".\n"))
z = select_neighbors(f = f, x = x_best, neighborhood_expansion = 1.5^(k-1),
controls = controls)
### perform local search around neighbors
for(j in seq_len(length(z))){
### check total time
if(!is.null(controls$time_limit)){
if(difftime(Sys.time(), start_time, units = "secs") > controls$time_limit){
stop = TRUE
warning("Stopped early because 'controls$time_limit' reached.",
call. = FALSE, immediate. = TRUE, noBreaks. = TRUE)
break
}
}
### perform local search
cat("** Neighbor",j)
start = Sys.time()
local_search = local(f = f,
parinit = z[[j]],
minimize = minimize,
controls = controls,
L = L)
end = Sys.time()
### save local optimum (if unique one has been found)
t = difftime(end,start,units = "auto")
cat(paste0(" [",sprintf("%.0f",t)," ",units(t),"]"))
if(local_search$success){
cat(" [found optimum]")
if(unique_optimum(L = L, argument = local_search$argument,
tolerance = controls$tolerance)){
cat(" [optimum is unknown]")
L = c(L,list(local_search))
}
}
cat("\n")
}
### if identified better optimum, reset neighborhoods
pos_x_best_new = do.call(what = ifelse(minimize,which.min,which.max),
args = list(unlist(lapply(L,function(x) x$value))))
x_best_new = L[[pos_x_best_new]]$argument
if(!isTRUE(all.equal(target = x_best_new,
current = x_best,
tolerance = controls$tolerance))){
cat("* Reset neighborhood, because better optimum was found.\n")
x_best = x_best_new
k = 1
} else {
k = k + 1
}
}
### prepare output
if(length(L) == 0){
warning("No optima found.")
return(NULL)
}
arguments = sapply(L,function(x)x$argument)
if(npar > 1)
arguments = t(arguments)
values = sapply(L,function(x)x$value)
global = values == ifelse(minimize,min,max)(values)
out = data.frame(arguments, values, global)
colnames(out) = c(paste0("p",1:npar), "value", "global")
### return output
cat("Done.\n")
return(out)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.