Created
September 5, 2011 06:03
-
-
Save Lambdanaut/1194199 to your computer and use it in GitHub Desktop.
I've got a pain fetish so I decided to wrestle a program making heavy use of System.Random WITHOUT a State Monad. When I got to the point where I needed to add a mutation rate I decided it works fine enough as it is without one, so here you go! (Technical
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module GE where | |
import System.Random | |
import Data.List (elemIndex) | |
import Control.Monad (foldM) | |
type Aminal = [Int] | |
type Population = [Aminal] | |
gen = 10 {- GENERATIONS -} | |
pop = 10 {- POPULATION NUMBER -} | |
chr = 10 {- CHROMOSOMAL LENGTH -} | |
maxi = 9 {- MAXIMUM VALUE OF CHROMOSOME -} | |
{- GENERATES A LIST OF RANDOM ANIMALS -} | |
initPop :: (RandomGen g) => Int -> g -> (Population,g) | |
initPop x rando = foldl (\(l,r) _ -> ( (fst $ randRange (0,maxi) r chr):l, snd $ randRange (0,maxi) r chr) ) ([],rando) [1..x] | |
where randRange (x,y) rando range = foldl (\(l,r) _ -> ( (fst $ randomR (x,y) r):l,snd $ randomR (x,y) r ) ) ([],rando) [1..range] | |
{- Breeds Two Animals Together splitting their genes randomly -} | |
breed :: StdGen -> Aminal -> Aminal -> (Aminal,StdGen) | |
breed rando a1 a2 = foldl (\(l,r) (g1,g2) -> (l++[fst $ randChoice r g1 g2],snd $ randChoice r g1 g2) ) ([],rando) $ zip a1 a2 | |
where randChoice r g1 g2 = case random r :: (Bool,StdGen) of | |
(True,newRando) -> (g1,newRando) | |
(False,newRando) -> (g2,newRando) | |
generation :: Population -> StdGen -> IO (Population,StdGen) | |
generation curPop rando = do | |
{- Get Greatest Fit -} | |
let fittestIndex = elemIndex (foldl max 0 $ map sum curPop) $ map sum curPop | |
case fittestIndex of | |
Nothing -> error "There is not a \"most fit\" creature in the population. " | |
Just i -> do | |
{- Breed Most Fit with All Others -} | |
return $ foldl (\(l,r) aminal -> (l++[fst $ breed r (curPop !! i) aminal],snd $ breed r (curPop !! i) aminal) ) ([],rando) curPop | |
main :: IO () | |
main = do | |
rando1 <- getStdGen | |
let (initialPop,rando2) = initPop pop rando1 | |
aminals <- foldM (\(p,r) _ -> generation p r) (initialPop,rando2) [1..gen] | |
mapM_ (putStrLn.show) $ fst aminals |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module GE where | |
import System.Random | |
import Data.List (elemIndex) | |
import Control.Monad (foldM) | |
type Aminal = [Int] | |
type Population = [Aminal] | |
gen = 10 {- GENERATIONS -} | |
pop = 10 {- POPULATION NUMBER -} | |
chr = 10 {- CHROMOSOMAL LENGTH -} | |
maxi = 9 {- MAXIMUM VALUE OF CHROMOSOME -} | |
{- GENERATES A LIST OF RANDOM ANIMALS -} | |
initPop :: (RandomGen g) => Int -> g -> (Population,g) | |
initPop x rando = foldl (\(l,r) _ -> ( (fst $ randRange (0,maxi) r chr):l, snd $ randRange (0,maxi) r chr) ) ([],rando) [1..x] | |
where randRange (x,y) rando range = foldl (\(l,r) _ -> ( (fst $ randomR (x,y) r):l,snd $ randomR (x,y) r ) ) ([],rando) [1..range] | |
{- Breeds Two Animals Together splitting their genes randomly -} | |
breed :: StdGen -> Aminal -> Aminal -> (Aminal,StdGen) | |
breed rando a1 a2 = foldl (\(l,r) (g1,g2) -> (l++[fst $ randChoice r g1 g2],snd $ randChoice r g1 g2) ) ([],rando) $ zip a1 a2 | |
where randChoice r g1 g2 = case random r of | |
(True,newRando) -> (g1,newRando) | |
(False,newRando) -> (g2,newRando) | |
generation :: Population -> StdGen -> IO (Population,StdGen) | |
generation curPop rando = do | |
{- Get Greatest Fit -} | |
let fittestIndex = elemIndex (foldl max 0 $ map sum curPop) $ map sum curPop | |
case fittestIndex of | |
Nothing -> error "There is not a \"most fit\" creature in the population. " | |
Just i -> do | |
{- Breed Most Fit with All Others -} | |
return $ foldl (\(l,r) aminal -> (l++[fst $ breed r (curPop !! i) aminal],snd $ breed r (curPop !! i) aminal) ) ([],rando) curPop | |
main :: IO () | |
main = do | |
rando1 <- getStdGen | |
let (initialPop,rando2) = initPop pop rando1 | |
aminals <- foldM (\(p,r) _ -> generation p r) (initialPop,rando2) [1..gen] | |
mapM_ (putStrLn.show) $ fst aminals |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment