% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/gena.R
\name{gena}
\alias{gena}
\title{Genetic Algorithm}
\usage{
gena(
  fn,
  gr = NULL,
  lower,
  upper,
  pop.n = 100,
  pop.initial = NULL,
  pop.method = "uniform",
  mating.method = "rank",
  mating.par = NULL,
  mating.self = FALSE,
  crossover.method = "local",
  crossover.par = NULL,
  crossover.prob = 0.8,
  mutation.method = "constant",
  mutation.par = NULL,
  mutation.prob = 0.2,
  mutation.genes.prob = 1/length(lower),
  elite.n = min(10, 2 * round(pop.n/20)),
  elite.duplicates = FALSE,
  hybrid.method = "rank",
  hybrid.par = 2,
  hybrid.prob = 0,
  hybrid.opt.par = NULL,
  hybrid.n = 1,
  constr.method = NULL,
  constr.par = NULL,
  maxiter = 100,
  is.max = TRUE,
  info = TRUE,
  ...
)
}
\arguments{
\item{fn}{function to be maximized i.e. fitness function.}

\item{gr}{gradient of the \code{fn}.}

\item{lower}{lower bound of the search space.}

\item{upper}{upper bound of the search space.}

\item{pop.n}{integer representing the size of the population.}

\item{pop.initial}{numeric matrix whose rows are chromosomes to be
included in the initial population. A numeric vector will be coerced to
a single-row matrix.}

\item{pop.method}{the algorithm to be applied for the creation of 
the initial population. See 'Details' for additional information.}

\item{mating.method}{the algorithm to be applied for mating, i.e., selection
of parents. See 'Details' for additional information.}

\item{mating.par}{parameters of the mating (selection) algorithm.}

\item{mating.self}{logical; if \code{TRUE} then the chromosome may
mate with itself, i.e., both parents may be the same chromosome.}

\item{crossover.method}{an algorithm to be applied for crossover, i.e.,
creation of the children. See 'Details' for additional information.}

\item{crossover.par}{parameters of the crossover algorithm.}

\item{crossover.prob}{probability of the crossover for each pair of parents.}

\item{mutation.method}{algorithm to be applied for mutation, i.e., random
change in some genes of the children. 
See 'Details' for additional information.}

\item{mutation.par}{parameters of the mutation algorithm.}

\item{mutation.prob}{mutation probability for the chromosomes.}

\item{mutation.genes.prob}{mutation probability for the genes.}

\item{elite.n}{number of elite children, i.e., those that have the
highest function value and will be preserved for the next population.}

\item{elite.duplicates}{logical; if \code{TRUE} then some elite children
may have the same genes.}

\item{hybrid.method}{hybrid selection algorithm, i.e., mechanism 
determining which chromosomes should be subject to local optimization.
See 'Details' for additional information.}

\item{hybrid.par}{parameters of the hybridization algorithm.}

\item{hybrid.prob}{probability of generating hybrids each iteration.}

\item{hybrid.opt.par}{parameters of the local optimization function
to be used for the hybridization algorithm 
(including \code{fn} and \code{gr}).}

\item{hybrid.n}{number of hybrids that appear if hybridization
takes place during the iteration.}

\item{constr.method}{the algorithm to be applied for imposing constraints
on the chromosomes. See 'Details' for additional information.}

\item{constr.par}{parameters of the constraint algorithm.}

\item{maxiter}{maximum number of iterations of the algorithm.}

\item{is.max}{logical; if \code{TRUE} (default) then fitness function
will be maximized. Otherwise it will be minimized.}

\item{info}{logical; if \code{TRUE} (default) then some optimization-related 
information will be printed each iteration.}

\item{...}{additional parameters to be passed to 
\code{fn} and \code{gr} functions.}
}
\value{
This function returns an object of class \code{gena} that is a list
containing the following elements:
\itemize{
\item \code{par} - chromosome (solution) with the highest fitness
(objective function) value.
\item \code{value} - value of \code{fn} at \code{par}.
\item \code{population} - matrix of chromosomes (solutions) from the 
last iteration of the algorithm.
\item \code{counts} - a two-element integer vector giving the number of
calls to \code{fn} and \code{gr} respectively.
\item \code{is.max} - identical to \code{is.max} input argument.
\item \code{fitness.history} - vector whose i-th element is the fitness
of the best chromosome in the i-th iteration.
\item \code{iter} - last iteration number.
}
}
\description{
This function allows the use of a genetic algorithm for
numeric global optimization of real-valued functions.
}
\details{
To find information on particular methods available via the 
\code{pop.method},
\code{mating.method}, \code{crossover.method}, \code{mutation.method},
\code{hybrid.method}, and \code{constr.method}
arguments, please see the 'Details' section of 
\code{\link[gena]{gena.population}}, \code{\link[gena]{gena.crossover}},
\code{\link[gena]{gena.mutation}}, \code{\link[gena]{gena.hybrid}}, 
and \code{\link[gena]{gena.constr}}, respectively. For example to
find information on possible values of \code{mutation.method} and
\code{mutation.par} arguments see description of \code{method} and
\code{par} arguments of \code{\link[gena]{gena.mutation}} function.

It is possible to provide manually implemented functions for 
population initialization, mating, crossover, mutation, and hybridization. 
For example, a manual mutation function may be provided through
the \code{mutation.method} argument. It should have the same signature 
(arguments) as the \code{\link[gena]{gena.mutation}} function and return 
the same object, i.e., the matrix of chromosomes of the appropriate size.
Manually implemented functions for other operators (crossover, mating,
and so on) may be provided in a similar way.

By default, the function does not impose any constraints on the parameters.
If \code{constr.method = "bounds"}, then \code{lower} and \code{upper} 
constraints will be imposed. Lower bounds should be strictly smaller
than upper bounds.

Currently the only available termination condition is \code{maxiter}. We
are going to provide some additional termination conditions during
future updates.

Infinite values in \code{lower} and \code{upper} are substituted with
\code{-(.Machine$double.xmax * 0.9)} and \code{.Machine$double.xmax * 0.9},
respectively.

By default, if \code{gr} is provided, then the BFGS algorithm will be used 
inside \code{\link[stats]{optim}} during hybridization.
Otherwise, \code{Nelder-Mead} will be used. 
Manual values for \code{\link[stats]{optim}} arguments may be provided 
(as a list) through the \code{hybrid.opt.par} argument.

Arguments \code{pop.n} and \code{elite.n} should be even integers, and
\code{elite.n} should be greater than 2. If these arguments are odd integers, 
then they will be coerced to even integers by adding 1. 
Also, \code{pop.n} should be greater than \code{elite.n} by at least 2.

For more information on the genetic algorithm,
please see Katoch et al. (2020).
}
\examples{
## Consider Ackley function
\donttest{
fn <- function(par, a = 20, b = 0.2)
{
  val <- a * exp(-b * sqrt(0.5 * (par[1] ^ 2 + par[2] ^ 2))) +
         exp(0.5 * (cos(2 * pi * par[1]) + cos(2 * pi * par[2]))) -
         exp(1) - a
  return(val)
}

# Maximize this function using classical
# genetic algorithm setup
set.seed(123)
lower <- c(-5, -100)
upper <- c(100, 5)
opt <- gena(fn = fn, 
            lower = lower, upper = upper,
            hybrid.prob = 0,
            a = 20, b = 0.2)
print(opt$par)

# Replicate optimization using hybridization
opt <- gena(fn = fn, 
            lower = lower, upper = upper,
            hybrid.prob = 0.2,
            a = 20, b = 0.2)
print(opt$par)
}

## Consider Rosenbrock function
fn <- function(par, a = 100)
{
  val <- -(a * (par[2] - par[1] ^ 2) ^ 2 + (1 - par[1]) ^ 2 +
           a * (par[3] - par[2] ^ 2) ^ 2 + (1 - par[2]) ^ 2)
  return(val)
}

# Apply genetic algorithm
lower <- rep(-10, 3)
upper <- rep(10, 3)
set.seed(123)
opt <- gena(fn = fn,
            lower = lower, upper = upper,
            a = 100)
print(opt$par)

\donttest{
# Improve the results by hybridization
opt <- gena(fn = fn,
            lower = lower, upper = upper,
            hybrid.prob = 0.2,
            a = 100)
print(opt$par)
}

# Provide manually implemented mutation function
# which simply randomly sorts genes. 
# Note that this function should have the same 
# arguments as gena.mutation.
mutation.my <- function(children, lower, upper, 
                        prob, prob.genes, 
                        method, par, iter)
{
  # Get dimensional data
  children.n <- nrow(children)
  genes.n <- ncol(children)
  
  # Select chromosomes that should mutate
  random_values <- runif(children.n, 0, 1)
  mutation_ind <- which(random_values <= prob)
   
  # Mutate chromosomes by randomly sorting
  # their genes
  for (i in mutation_ind)
  {
    children[i, ] <- children[i, sample(1:genes.n)]
  }
  
  # Return mutated chromosomes
  return(children)
}

opt <- gena(fn = fn,
            lower = lower, upper = upper,
            mutation.method = mutation.my,
            a = 100)
print(opt$par)

}
\references{
S. Katoch, S. Chauhan, V. Kumar (2020). 
A review on genetic algorithm: past, present, and future.
\emph{Multimedia Tools and Applications}, 80, 8091-8126.
<doi:10.1007/s11042-020-10139-6>
}
