hgalib-0.2: examples/GPTest.hs
import GA
import qualified Population.List as L
import Random
import Control.Monad.State.Strict
import List
import qualified Chromosome.GP as GP
import Control.Monad
-- Defines the operators available for the GP
-- You must specify the function, then the arity (number of arguments), then the textual representation
ops :: [GP.Op Double Double]
ops = [
GP.Op (\[x,y] -> return $ x + y) 2 "+", -- Addition
GP.Op (\[x,y] -> return $ x - y) 2 "-", -- Subtraction
GP.Op (\[x,y] -> return $ x * y) 2 "*", -- Multiplication
GP.Op (\[] -> return 1) 0 "1", -- The constant 1
GP.Op (\[] -> get) 0 "x" -- The independant variable
]
-- Examples for the function f(x) = 3x^2 + 1
examples :: [(Double,Double)]
examples = zip [1..10] $ map (\x -> 3 * x * x + 1) [1..10]
myconfig = defaultConfig {
-- cConfig configures the chromosome model and the genetic operators
cConfig = ChromosomeConfig {
-- Compute fitness based on the mean square error across the examples
fitness = GP.mseFitness examples,
-- Max tree depth of 4, mutation rate of 0.05
mutate = GP.mutate 4 ops (0.05 :: Double),
-- Oops! crossover not yet implemented for GP, see GP.hs for details
cross = error "Attempt to cross GP"
},
-- The population will be represented as a list
pConfig = L.config,
-- To generate the next population, mynewPopulation will be called
newPopulation = mynewPopulation,
-- Stop after 100 generations
maxGeneration = Just 500,
-- Initialize the random number generator to 42
-- 42 is chosen for obvious reasons
gen = mkStdGen 42
}
-- This function takes a population ("pop"), then mutates it, then applies roulette selection
mynewPopulation pop = mutateM pop >>= rouletteM
-- Create an initial population of 100 GP's
-- Tree depth of 4 using ops as the pool of available tree nodes
initPop = replicateM 100 $ GP.random 4 ops
getBest = do
pop <- initPop
-- Grab the best chromosome at the start for comparision
before <- bestChromosome pop
-- Evaluation of the GA
answer <- run pop
-- Find the new best chromosome after running the GA
after <- bestChromosome answer
return (before, after)
main = do
-- Run the GA with the config "myconfig"
let (before,after) = evalState getBest myconfig
-- Show the before/after s-expressions
putStrLn $ show $ before
putStrLn $ show $ after