randomsearch

The package randomsearch optimizes a given smoof function. Use makeSingleObjectiveFunction() to wrap any function into a smoof function. It can make use of parallel resources through prallelMap. randomsearch has three internal operating modes:

  • fast.parallel is the default and used if only max.evals is defined as termination criterion. max.execbudget and target.fun.value have to be NULL.
  • slow.parallel is used if max.execbudget or target.fun.value have been set and parallelStart has been called without defined level or with level = randomsearch.feval. In this mode par.jobs (defaults to parallelGetOptions()$settings$cpus) instances are started. Each instance conducts a random search until the termination criterion is met. The instances communicate using a shared folder (par.dir = ~/.randomsearch/).
  • normal is used if no parallel mode is started and if max.execbudget or target.fun.value have been set. Note, that this introduces an overhead to fast.parallel even without parallelization because the termination criterion is checked after each evaluation.

Usage

Simple usage with functions that use a vector as input:

fun = function(x) x[1]^2 + sin(x[2])
res = randomsearch(fun, lower = c(-1, -1), upper = c(2,2), minimize = TRUE, max.evals = 30)
rs = summary(res)
rs$best.x
## $x
## [1] -0.2617368 -0.8738214
##          y 
## -0.6982813
##            x1         x2          y dob eol exec.time
## 25 -0.2020821  1.5734831 1.04083356  25  NA         0
## 26 -0.8625065  0.3266002 1.06474229  26  NA         0
## 27  1.3967745 -0.6343022 1.35836350  27  NA         0
## 28  0.6828440 -0.3804058 0.09497854  28  NA         0
## 29 -0.6174050  1.2599236 1.33325597  29  NA         0
## 30  1.6851361  0.1233883 2.96275907  30  NA         0

Discrete and hierarchical search spaces

For usage with more complicated search spaces you have to define a smoof function. This allows you to tune over discrete parameters and even hierarchical parameter sets like in this example. Here the parameter y is only active if a==a2.

## $a
## [1] "a2"
## 
## $x
## [1] -2.430956
## 
## $z
## [1] 0.7679393
##          y 
## 0.04349791
##     a          x         z         y dob eol exec.time
## 25 a2  1.4224664 1.0422715 1.9961129  25  NA         0
## 26 a2  1.9308328 1.5725631 1.1050422  26  NA         0
## 27 a2 -0.3634108 0.6234044 0.7753811  27  NA         0
## 28 a1 -2.9371973        NA 8.6271281  28  NA         0
## 29 a2 -1.6130293 0.4781999 0.3028959  29  NA         0
## 30 a1 -1.5256579        NA 2.3276321  30  NA         0

Parallel Usage

Note: For Windows use parallelStartSocket().

fun = function(x) {
  Sys.sleep(runif(1))
  x[1]^2 + sin(x[2])
}

parallelMap::parallelStartMulticore(cpus = 2, level = "randomsearch.feval")
res = randomsearch(fun, lower = c(-1, -1), upper = c(2,2), minimize = TRUE, max.execbudget = 2, max.evals = 1000)
parallelMap::parallelStop()
summary(res)

Multi-objective optimization

Note: randomsearch() detects a multi-objective optimization by the length of the minimize vector.

obj.fun = function(x) c(x[1]^2 + sin(x[2]), cos(x[1]))
res = randomsearch(obj.fun, lower = c(-1, -1), upper = c(2,2), minimize = c(TRUE, TRUE), max.evals = 30)
summary(res)
## Randomsearch Result: 
## Multiobjective Search Pareto Front 
##           y_1         y_2         x1          x2
## 1  -0.2266606  0.88324220 -0.4880643 -0.48348476
## 3  -0.2274047  0.94463890  0.3343040 -0.34602799
## 4  -0.2309050  0.98662663  0.1637271 -0.26065302
## 6   0.1701176  0.75456461  0.7158059 -0.34932171
## 8   0.3583286  0.62947484  0.8899192 -0.44851453
## 10  1.0262387  0.58171931  0.9499555  0.12414187
## 14  1.0618198  0.43129294  1.1248710 -0.20494658
## 15  1.1604827  0.34270358  1.2210031 -0.33669119
## 16  2.2456680  0.05147028  1.5193033 -0.06265551
## 21  3.3156845 -0.05322554  1.6240470  0.74525030
## 22  3.6721829 -0.23881557  1.8119423  0.39959811
## 29  4.5873757 -0.37660278  1.9569227  0.85997993

Of course multi-objective optimization works with smoof functions as well. A multi-objective smoof function is constructed as follows: