--- title: "Basic Usage of the MOEADr Package" author: "Claus Aranha, Felipe Campelo" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Basic Usage of the MOEADr Package} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- We use **MOEADr** to optimize a simple 2-objective problem composed of the Sphere function and the Rastrigin function in $X = \{x_1,x_2,\dots,x_D\} \in\mathbb{R}^D$. ## Setting up the Target Problem: For this example, we define the sphere and rastrigin function in $\mathbb{R}$ as: $$ \text{sphere}(X) = \sum_{i=1}^D x_i^2\\ \text{rastrigin}(X) = \sum_{i=1}^D (x_i^2 - 10 \text{cos}(2\pi x_i) + 10) $$ Their R implementation is as follows. Because both functions have the optimum at the zero, we apply a simple displacement on the input parameters to make the output of the example problem more interesting. ```{r} sphere <- function(X) { X.shift <- X + seq_along(X)*0.1 # displace input parameters sum(X.shift**2) } rastringin <- function(X) { X.shift <- X - seq_along(X)*0.1 # displace input parameters in the opposite direction sum((X.shift)**2 - 10 * cos(2 * pi * X.shift) + 10) } ``` The **MOEADr** package requires the multi objective problem to be defined as a function that receives the entire solution set as a matrix, and return the objective values also as a matrix. For details see the [Problem Definition](problem-definition.html) vignette. We will achieve this requirement by wrapping the sphere function and the rastrigin function as follows: ```{r} problem.sr <- function(X) { t(apply(X, MARGIN = 1, FUN = function(X) { c(sphere(X), rastringin(X)) } )) } ``` Finally, we need to create a problem definition list that specifies the number of objectives, and the minimum and maximum parameter values for each dimension: ```{r} problem.1 <- list(name = "problem.sr", # function that executes the MOP xmin = rep(-1,30), # minimum parameter value for each dimension xmax = rep(1,30), # maximum parameter value for each dimension m = 2) # number of objectives ``` ## Setting up **MOEADr** To load the package and run the problem using the original MOEA/D variant, we use the following commands: ```{r, collapse = TRUE, comment = "#>"} library(MOEADr) results <- moead(problem = problem.1, preset = preset_moead("original"), showpars = list(show.iters = "none"), seed = 42) ``` The *moead()* function requires a problem definition (discussed in the previous section) and an algorithm configuration (in this case, an algorithm preset, and optional changes to the preset), logging parameters, and a seed. The *preset_moead()* function can output a number of different presets based on combinations found on the literature. In this example, *preset_moead("original")* returns the original MOEA/D configuration, as proposed by Zhang and Li (2007)^[[IEEE Trans. Evol. Comp. 11(6): 712-731, 2007](https://doi.org/10.1109/TEVC.2007.892759).]. You can get a list of available presets by running: ```{r, collapse = TRUE, comment = "#>"} preset_moead() ``` ## Visualizing the results The *moead()* function returns a list object of class _moead_, containing the final solution set, objective values for each solution, and other information about the optimization process. The **MOEADr** package uses S3 to implement versions of *plot()* and *summary()* for this object. *plot()* will show the pareto front for the objectives, as in the figure below. When the number of objectives is greater than 2, a parallel coordinates plot is also produced (see the next example). *summary()* displays information about the number of non-dominated and feasible solution points, the estimated ideal and nadir values (when available), and (optionally) the IDR and hypervolume yielded by the feasible, nondominated set. ```{r,collapse = TRUE, comment = "#>", fig.align="center", fig.width=6, fig.height=6} summary(results) plot(results, suppress.pause = TRUE) ``` ## A more complex example The **smoof** package^[[https://CRAN.R-project.org/package=smoof](https://CRAN.R-project.org/package=smoof)] provides generators for a large number of single and multi objective test functions. The **MOEADr** package provides a wrapper (function *make_vectorized_smoof()*) to easily convert **smoof** functions to the format required by the *moead()* function. The code snipped below generates a MOP with five objective functions from **smoof**, and the necessary problem definition for *moead()*. ```{r,collapse = TRUE, comment = "#>"} library(smoof) DTLZ2 <- make_vectorized_smoof(prob.name = "DTLZ2", dimensions = 20, n.objectives = 5) problem.dtlz2 <- list(name = "DTLZ2", xmin = rep(0, 20), xmax = rep(1, 20), m = 5) ``` In this example we will also show how to modify an algorithm preset. Because of the higher number of objectives, we want to reduce the value of the parameter $H$ in the decomposition component *SLD* used by the preset from 100 to 8: ```{r, collapse = TRUE, comment = "#>"} results.dtlz <- moead(problem = problem.dtlz2, preset = preset_moead("original"), decomp = list(name = "SLD", H = 8), showpars = list(show.iters = "dots"), seed = 42) ``` Notice on the figure below that **MOEADr** plots extra information when the number of objectives in a problem is greater than 2: ```{r,collapse = TRUE, comment = "#>", fig.align="center", fig.width=6, fig.height=6} summary(results.dtlz) plot(results.dtlz, suppress.pause = TRUE) ``` Note that for more complex MOPs, the preset values suggested by *preset_moead()* might not be effective. For example, the standard value of 100 for $H$ in the *SLD* component is appropriate for 2 objectives, but exceeds the available memory for $m > 3$. Therefore, we strongly recommend that the user explore the meta-parameter space. The next case study shows one way to perform this task semi-automatically.