GithubHelp home page GithubHelp logo

ecr's Introduction

IMPORTANT: This repository is outdated. Visit the official repository of ecr2 for the current state of development. There are various substantial interface changes and the package benefits from better performance as well as the possibility to prototype non-standard EAs by offering many more helper functions and make stuff much more explicit.

ecr: Evolutionary Computing in R

CRAN Status Badge CRAN Downloads Build Status Build status Coverage Status

The ecr package provides a powerful framework for implementing both single- and multi-objective evolutionary algorithms in R. It has build-in support for standard genotypes like real-valued vectors, binary strings and permutations. Beside, different pre-defined building blocks in form of evolutionary operators (selectors, mutators, recombinators), e.g., k-tournament selection, uniform mutation, crossover and many helper functions frequently needed in evolutionary algorithms are provided. The possibility to extend the available toolbox by defining new operators and even operate on non-standard representations makes the package very flexible.

Overview of Features

  • Optimization of single and multi-objective functions.
  • Build-in genotypes float, binary, permutation.
  • Possibility to create custom representations/genotypes.
  • Large collection of predefined evolutionary operators for standard representations.
  • Powerful and flexible monitoring/logging.
  • Event dispatching mechanism. For instance the user can register actions which should be called each time the population is updated.

Installation Instructions

The package is available at CRAN soon. Install the release version via:

install.packages("ecr")

If you are interested in trying out and playing around with the current github developer version use the devtools package and type the following command in R:

devtools::install_github("jakobbossek/ecr")

Example (The flexible approach)

In this section we want to optimize a one dimensional function with an evolutionary algorithm using just the evolutionary operators shipped with the package. A more in-depth introduction will be available soon.

The smoof R package provides a large collection of continuous single-objective test functions commonly used in benchmarking algorithms. As an example we are going to search for the global optimum of the one-dimensional Rastrigin function.

library(smoof)
library(ggplot2)
library(ecr)

obj.fun = makeRastriginFunction(dimensions = 1L)
autoplot(obj.fun, show.optimum = TRUE)

As a next step we generate an ecr control object, which holds all the neccessary parameters for the evolutionary algorithm. The construction of this object consists of generating the object itself and kind of decorating it with some evolutionary operators.

For our setup we choose the natural representation with real-valued numbers as the genotype, a population size of 20 individuals with 5 individuals being created by recombination and mutation in each generation. Furthermore we decide to use a 'plus' survival strategy, i. e., the current population and the offspring will be merged before survival selection takes place. Gaussian mutation with a standard deviance of 0.005 serves as the mutation operator and we keep the intermediate recombination operator (which is the default for the real-valued representation). Moreover we define a maximal number of 50 generations and activate the build-in logging which is needed in order to visualize the results afterwards.

# Generate the control object (set basic parameters)
control = setupECRControl(
  n.population = 20L,
  n.offspring = 10L,
  representation = "float",
  survival.strategy = "plus",
  logger = setupOptPathLoggingMonitor(),
  stopping.conditions = list(
    setupMaximumIterationsTerminator(max.iter = 50L)
  )
)

# Setup the evolutionary toolbox by specifying operators
control = setupEvolutionaryOperators(
  control,
  mutator = setupGaussMutator(sdev = 0.005)
)
print(control)

Now lets start the optimization process and print the result object, which contains the optimization path, the best parameters, the best fitness value and some additional information.

set.seed(123)
res = doTheEvolution(obj.fun, control = control)
print(res)
print(head(as.data.frame(res$opt.path)))
print(autoplot(res, complete.trace = TRUE, log.fitness = TRUE))

Example (R like interface)

This example above demonstrated the most flexible way of creating an EA in ecr:

  1. Create optimization problem, i.e., the objective function to optimize.
  2. Set up an cntrol object with all the evolutionary parameters and operators attached to it.
  3. Pass both to the doTheEvolutionFunction function.

Although this approach is highly flexible in practise a R user often aims to optimize a single-objective R function at hand. In this scenario the upper low-level proceeding is cumbersome and a lot of code needs to be written. The ecr package thus provides a more R like interface (similar to optim). Alternative code for solving the Rastrigin function is shown below.

library(smoof)
library(ggplot2)
library(ecr)

obj.fun = makeRastriginFunction(dimensions = 1L)
res = ecr(obj.fun, n.dim = 1L, lower = -10, upper = 10, 
    n.population = 20L, n.offspring = 10L, representation = "float", 
    max.iter = 100L, mutator = setupGaussMutator(sdev = 0.005)
)

Contact

Please address questions and missing features about the ecr package to the author Jakob Bossek [email protected]. Found some nasty bugs? Please use the issue tracker for this. Pay attention to explain the problem as good as possible. At its best you provide an example, so I can reproduce your problem quickly.

ecr's People

Contributors

jakobbossek avatar surmann avatar lucasmpavelski avatar

Stargazers

 avatar  avatar Juan Julián Merelo Guervós avatar  avatar  avatar Matteo De Felice avatar Dominik Leutnant avatar Júnior César Abreu avatar  avatar  avatar  avatar Bernd Bischl avatar  avatar

Watchers

James Cloos avatar Bernd Bischl avatar  avatar  avatar

ecr's Issues

Postprocessing

One might want to apply a function on each individual after each generation. There should be a possibility to provide a list of post-processing functions I think.

Think about tracing.

How to best save the optimization trace? What values should the main function return?
For mono-criteria functions it surely should return at least:

  • Best parameter value(s)
  • Optimal objective.fun/fitness.fun value
  • Number of iterations, max number of iterations
  • Reason for termination (time budget reached, maximal number of generations exceeded)
  • optimization trace, i. e., a data frame with a row for each generation saving the generation, best parameter value(s) so far, best/worst/mean(/median) fitness value of the generation, .... Maybe it would be a good idea to let the user provide a tracing function and allow him to extract the information he needs from the current population for the trace.

Plot function for result object

There should be a plot function for the result object for sure. For one dimensional objective funs we should print the optimization trace. For two-dimensional funs there should be a function to plot the approximate Pareto front.
Further there should be options to plot this stuff after each iteration.

Parental selection

So far the procedure for selecting parents for the mating pool is not ingenious. Work on it.

clean up control object

Since ecr now requires the objective functions to be of otf type, parameters n.params and later n.targets as well as target.names are redundant, since ecr can extract this information from the objective function. Moreover, n.targets is not needed at the moment, because multi-objective optimization is not supported at the moment.

Use otf package for target functions

I guess we do not need n.params, n.targets anymore in the control object. The global.optimum and par.set arguments for ecr are not needed as well, because they can be extracted from objective.fun.

Licence

The package needs a license.

We need tests

A lot of stuff is not tested automatically. Think of meaningful test cases and write a lot of tests!

Termination criteria

Until now only max.iter serves as a termination criterion. Implement more possibilities to terminate:

  • maximal number of objective function evaluations
  • maximal time budget (how to do this the best way? system.time?
  • tolerance level (if global optimum is known)
  • ...

Introduce subpopulation schemes

To maintain diversity and prevent premature convergence one can maintain multiple subpopulations, which is known as island model or regional model in the literature. Here different subpopulations evolve independently and occasionally exchange individuals. This way one might prevent the algorithm to converge to early in a local minimum.

We should think about the introduction of simple regional schemes. At least the following things should be introduced:

  • the number of (sub)populations
  • isolation time, i. e., the number of generations in which the subpopulations evolve independently without exchanging individuals
  • migration rate, i. e., the number or the fraction of individuals shared in the migration phase
  • migration selection mechanism, i. e., which elements (best/random/...) should be interchanged between the subpopulations

ParamHelpers

At the moment we set the objective function and lower/upper bounds as parameters the the main function. Maybe it would be better to provide objects Param respectively ParamSets from ParamHelpers package. For real-valued or integer value representations this should work fine, but what about the representation via permutations? How do we handle this?

Alternatively we could outsource this stuff to the objective function. This way we should force the user to wrap his objective function with an ecrObjevtiveFunction wrapper. For example:

fun = makeEcrObjectiveFunction(
   fun = function(x) sum(x^2),
   lower = c(-10, -10),
   upper = c(10, 10),
   ...
)

Parallelization

There are definitely parts which can be parallelized. At least the evaluation of the fitness function should use parallelization via parallelMap. We should think about other places as well!

Add creator/initializer objects

In the field of Evolutionary Computing algorithms are population-based. In the majority of cases the initial population is randomly generated. Provide an interface for such initialization methods. As for mutator and recombinator objects there should be a makeCreator method. Make sure, that the outcome of such a method highly depends on the representation of the parameters.

Interface(s) for evolutionary operators

I am still unhappy with the interface(s) for evolutionary operators. At the moment operators expect a set of individuals and a list of control parameters. The default parameter values (beside some additional stuff like supported representations) are stored as attributes of the operator. In addition, there must be a parameter checking function for each operator which is called only one time in the control object and not each time the function is called. That's fine, but there are several problems I see:

  • later we want self-adaptive parameters. They do not fit in nicely in this interface, if they do at all
  • The operators are build by hand. Currently makeOperator as well as makeMutator and makeRecombinator are not used. This functions work fine, but this way we cannot state via roxygen which parameters are needed by the specific operators.

operator chaining

Offer the possibility to chain mutation operators. We did it for example in our tspmeta EA.

Update README

The readme markdown file should contain a brief overview of the aims of the package, the current development status, information on how to install the development version, a short example (optimization of a soobench function) and contact information.

Rename the package

esoo (evolutionary single objective optimization) is not appropriate anymore, because mutli-objective evolutionary optimization is planed as well for a later release. Maybe call it better ecr (evolutionary computing in R).

Self-adaptive parameters for mutator

Later it should be possible to activate self-adaption of mutation parameters such as the mutation step size of the Gauss mutator. Think about a good way to store the individual mutation parameters! Probably the best location are the individuals. So, make objects out of the individuals with genotype, phenotype, mutation parameters and so on? This would surely introduce much more complexity. Hmm...

Example for Evolutionary Strategy

Following the classification of EC algorithms of Eiben and Smith there should be an example for the optimization of a (soobench) function using an Evolutionary Strategy.

Reason for termination

The result object should contain information about the reason for termination, i. e., maximal number of iterations reached, time budget depleted or something like this.

Elitism

Until now the there is just a (mu + 1) method implemented. Survival of the fittest is therefore given at the moment. But later we will have different strategies and the user should be able to enable elitism via corresponding options in the control object.

Parent selection methods

Until now we only draw randomly (uniformly!) from the mating pool. We need rhoullette-wheel-selection and other, better algorithms.

Interface for stopping criteria

At the moment we have some "hard-coded" stopping criteria, i.e., we set the parameters in the control object and the stopping criterions are evaluated. This is 1) not modular and 2) not extensible. We hence need a better solution.
I think what we need is a means to generate StoppingCondition objects and a generator for termination objects. This way we could compound a set of desired stopping conditions similar to that:

stoppingConditionSet = makeStoppingConditionSet(
  makeMaximumEvaluationsStoppingCondition(max.evals = 1000000L),
  makeMaximumTimeStoppingCondition(max.time = 60 * 60),
  makeGapToOptimumStoppingCondition(tolerance = 0.01)
)
control = ecr.control(..., stoppingConditionSet = StoppingCondition)
...

This would moreover give the possibility to add custom stopping criteria in the following fashion

makeMyCustomSenselessStoppingCondition = function(some.param) {
  force(some.param)
  # we need to constitute an interface for stopping conditions
  stoppingCondition = function(opt.path, iter, ...) {
    return(runif(1) < some.param)
  }
  makeInternalStoppingCondition(
    stoppingCondition = stoppingCondition,
    name = "Senseless stopping condition",
    ...
   )
}

Add monitoring option(s)

Allow the user not only to activate monitoring via show.info, but also provide different monitoring functions and a clean interface to make development of proprietary monitoring functions easy.

Something like show.info.stepsize

Maybe we should provide something like show.info.stepsize to allow the user to specify at which iterations there will be informative output.

Multi-criteria optimization

The package shall offer a toolset/framework for mono-objective as well as multi-criteria objective functions. Think about how to separate that. Do we need optim.mono and optim.multi funs or can we handle all the stuff with one fun?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.