content: {-# OPTIONS_GHC -fno-warn-unused-imports #-}
  
  {- |
  Copyright    : 2010-2011 Erlend Hamberg, 2011-2013 Sergey Astanin
  License      : BSD3
  Stability    : experimental
  Portability  : portable
  
  A library for custom genetic algorithms.
  
  @
  -----------
  Quick Start
  -----------
  @
  
  Import
  
    * either "Moo.GeneticAlgorithm.Binary"
  
    * or "Moo.GeneticAlgorithm.Continuous"
  
  Genetic algorithms are used to find good solutions to optimization
  and search problems. They mimic the process of natural evolution
  and selection.
  
  A genetic algorithm deals with a /population/ of candidate solutions.
  Each candidate solution is represented with a 'Genome'. On every
  iteration the best genomes are /selected/ ('SelectionOp'). The next
  generation is produced through /crossover/ (recombination of the
  parents, 'CrossoverOp') and /mutation/ (a random change in the genome,
  'MutationOp') of the selected genomes. This process of selection --
  crossover -- mutation is repeated until a good solution appears or all
  hope is lost.
  
  Genetic algorithms are often defined in terms of minimizing a cost
  function or maximizing fitness. This library refers to observed
  performance of a genome as 'Objective', which can be minimized as well
  as maximized.
  
  
  @
  --------------------------------
  How to write a genetic algorithm
  --------------------------------
  @
  
    1. Provide an encoding and decoding functions to convert from model
       variables to genomes and back. See /How to choose encoding/ below.
  
    2. Write a custom objective function. Its type should be an instance
       of 'ObjectiveFunction' @a@. Functions of type @Genome a -> Objective@
       are commonly used.
  
    3. Optionally write custom selection ('SelectionOp'), crossover
       ('CrossoverOp') and mutation ('MutationOp') operators or just use
       some standard operators provided by this library. Operators specific
       to binary or continuous algorithms are provided by
       "Moo.GeneticAlgorithm.Binary" and "Moo.GeneticAlgorithm.Continuous"
       modules respectively.
  
    4. Use 'nextGeneration' or 'nextSteadyState' to create a single step
       of the algorithm, control the iterative process with 'loop',
       'loopWithLog', or 'loopIO'.
  
    5. Write a function to generate an initial population; for random
       uniform initialization use 'getRandomGenomes'
       or 'getRandomBinaryGenomes'.
  
  Library functions which need access to random number generator work in
  'Rand' monad.  You may use a high-level wrapper 'runGA' (or
  'runIO' if you used 'loopIO'), which takes care of creating a new random
  number generator and running the entire algorithm.
  
  To solve constrained optimization problems, modify initialization and
  selection operators (see "Moo.GeneticAlgorithm.Constraints").
  
  To solve multi-objective optimization problems, use NSGA-II algorithm
  (see "Moo.GeneticAlgorithm.Multiobjective").
  
  @
  ----------------------
  How to choose encoding
  ----------------------
  @
  
   * For problems with discrete search space, binary (or Gray)
     encoding of the bit-string is usually used.
     A bit-string is represented as a list of @Bool@ values (@[Bool]@).
     To build a binary genetic algorithm, import "Moo.GeneticAlgorithm.Binary".
  
   * For problems with continuous search space, it is possible to use a
     vector of real variables as a genome.
     Such a genome is represented as a list of @Double@ or @Float@ values.
     Special crossover and mutation operators should be used.
     To build a continuous genetic algorithm, import
     "Moo.GeneticAlgorithm.Continuous".
  
  
  @
  --------
  Examples
  --------
  @
  
  Minimizing Beale's function:
  
  @
  import Moo.GeneticAlgorithm.Continuous
  
  
  beale :: [Double] -> Double
  beale [x, y] = (1.5 - x + x*y)**2 + (2.25 - x + x*y*y)**2 + (2.625 - x + x*y*y*y)**2
  
  
  popsize = 101
  elitesize = 1
  tolerance = 1e-6
  
  
  selection = tournamentSelect Minimizing 2 (popsize - elitesize)
  crossover = unimodalCrossoverRP
  mutation = gaussianMutate 0.25 0.1
  step = nextGeneration Minimizing beale selection elitesize crossover mutation
  stop = IfObjective (\\values -> (minimum values) < tolerance)
  initialize = getRandomGenomes popsize [(-4.5, 4.5), (-4.5, 4.5)]
  
  
  main = do
    population <- runGA initialize (loop stop step)
    print (head . bestFirst Minimizing $ population)
  @
  
  See @examples/@ folder of the source distribution for more examples.
  
  -}
  
  module Moo.GeneticAlgorithm (
  ) where
  
  import Moo.GeneticAlgorithm.Types
  import Moo.GeneticAlgorithm.Random
  import Moo.GeneticAlgorithm.Run
  import Moo.GeneticAlgorithm.Utilities
  import Moo.GeneticAlgorithm.Binary
  import Moo.GeneticAlgorithm.Continuous
  