Using a Python function with caRamel

Short Description

caRamel is a multiobjective evolutionary algorithm combining the MEAS algorithm and the NGSA-II algorithm.

Download the package from CRAN or GitHub and then install and load it.

library(caRamel)

This example will use the reticulate package in order to call a Python function from R. Download the package from CRAN and then install and load it

library(reticulate)

Kursawe test function has two objectives of three variables. This function will be written in a Python script named kursawe.py with the following content:

import numpy as np

def kursawe(x):
    k1 = -10 * np.exp(-0.2 * np.sqrt(x[0]**2 + x[1]**2)) - \
        10 * np.exp(-0.2 * np.sqrt(x[1]**2 + x[2]**2))
    k2 = np.abs(x[0])**0.8 + 5 * np.sin(x[0]**3) + np.abs(x[1])**0.8 +\
        5 * np.sin(x[1]**3) + np.abs(x[2])**0.8 + 5 * np.sin(x[2]**3)
    return np.array([k1, k2])

The Python function has to be loaded in R:

use_python("/usr/local/bin/python3")
source_python("kursawe.py")

This function is not directly called from caRamel but with a new wrapper function and finally all can be gathered in it (recommended):

wrapperFunction <- function(i) {
  # load the package
  library(reticulate)
  # python path
  use_python("/usr/local/bin/python3")
  # source the Python function
  source_python("kursawe.py")
  # call the Python function and return the results
  return(kursawe(x[i,]))
}

The variables lie in the range [-5, 5]:

nvar <- 3 # number of variables
bounds <- matrix(data = 1, nrow = nvar, ncol = 2) # upper and lower bounds
bounds[, 1] <- -5 * bounds[, 1]
bounds[, 2] <- 5 * bounds[, 2]

Both functions are to be minimized:

nobj <- 2 # number of objectives
minmax <- c(FALSE, FALSE) # min and min

Set algorithmic parameters and launch caRamel:

popsize <- 100 # size of the genetic population
archsize <- 100 # size of the archive for the Pareto front
maxrun <- 1000 # maximum number of calls
prec <- matrix(1.e-3, nrow = 1, ncol = nobj) # accuracy for the convergence phase

results <- 
  caRamel(nobj,
          nvar,
          minmax,
          bounds,
          wrapperFunction, # It's the wrapper function that will be called
          popsize,
          archsize,
          maxrun,
          prec)

Test if the convergence is successful and plot the optimal front:

print(results$success==TRUE)

plot(results$objectives[,1], results$objectives[,2], main="Kursawe Pareto front", xlab="Objective #1", ylab="Objective #2")

Finally plot the convergences of the objective functions:

matplot(results$save_crit[,1],cbind(results$save_crit[,2],results$save_crit[,3]),type="l",col=c("blue","red"), main="Convergence", xlab="Number of calls", ylab="Objectives values")