HSGEP-0.1.1: GEP/Random.hs
{- |
Randomized functions for GEP applications. Attempting to
isolate all code that needs to be run under the Rmonad here.
Author: mjsottile\@computer.org
-}
module GEP.Random (
randomSymbol,
randomSymbolList,
newIndividual,
newPopulation,
mutate
) where
import GEP.Types
import GEP.Params
import GEP.Rmonad
{-|
Select a random symbol from the provided list.
-}
randomSymbol :: [a] -- ^ List of symbols
-> GEPMonad a -- ^ Selected symbol
randomSymbol syms =
do index <- nextR (length syms)
return (syms !! (index-1))
{-|
Select a sequence of random symbols from the provided list.
-}
randomSymbolList :: [a] -- ^ List of symbols
-> Int -- ^ Number to select
-> GEPMonad [a] -- ^ List of selected
-- symbols
randomSymbolList _ 0 = do return []
randomSymbolList syms n =
do current <- randomSymbol syms
rest <- randomSymbolList syms (n-1)
return ([current]++rest)
-- | Generate a new individual given a genome specification.
newIndividual :: Genome -- ^ Genome for individual
-> Int -- ^ Number of genes to generate
-> GEPMonad Chromosome
newIndividual _ 0 = do return []
newIndividual g n =
do hI <- randomSymbolList (allsymbols g) head_len
tI <- randomSymbolList (terminals g) tail_len
otherGenes <- newIndividual g (n-1)
return (hI++tI++otherGenes)
where
head_len = headLength g
tail_len = tailLength g
-- |Create a population of fresh random individuals given a genome
-- |specification.
newPopulation :: Genome -- ^ Genome of population
-> Int -- ^ Number of individuals to create
-> GEPMonad [Chromosome]
newPopulation _ 0 = do return []
newPopulation g n =
do p <- newPopulation g (n-1)
i <- newIndividual g (numGenes g)
return ([i]++p)
-- | Mutate symbols in a gene. Symbols are chosen from terminals and allsymbols
-- for head and tail of the gene respectively.
mutateGene :: Genome -> Rates -> Gene -> GEPMonad Gene
mutateGene g r gene = do
let (h, t) = splitAt (headLength g) gene
hMutated <- mapM mutateHeadSymbol h
tMutated <- mapM mutateTailSymbol t
return $ hMutated ++ tMutated
where
mutateTailSymbol :: Symbol -> GEPMonad Symbol
mutateTailSymbol s = mutateSymbol r s $ terminals g
mutateHeadSymbol :: Symbol -> GEPMonad Symbol
mutateHeadSymbol s = mutateSymbol r s $ allsymbols g
-- | Mutate single symbol with probability pMutate choosing from given symbol
-- list.
mutateSymbol :: Rates -> Symbol -> [Symbol] -> GEPMonad Symbol
mutateSymbol r s ss =
nextF 1.0 >>= \prob ->
if prob < pMutate r
then randomSymbol ss
else return s
mutate :: Genome -> Rates -> Chromosome -> GEPMonad Chromosome
mutate g r s =
do
genes' <- mapM (\i -> mutateGene g r i) genes
return $ genesToChrom genes'
where
genes = chromToGenes s (geneLength g)