From 440dd38f24d1df150fb5b4c7965bb6e792c929fe Mon Sep 17 00:00:00 2001 From: Ray Hogenson Date: Sat, 7 Sep 2019 16:36:01 -0700 Subject: Write a little guy This program is in a weird state right now, but I'm checking it in to git so that I can back it up, since I want to reinstall again. --- Evolve.hs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Evolve.hs (limited to 'Evolve.hs') diff --git a/Evolve.hs b/Evolve.hs new file mode 100644 index 0000000..a34a382 --- /dev/null +++ b/Evolve.hs @@ -0,0 +1,45 @@ +module Evolve (Evolvable, evolve, mutate, score, mutateProbability) where + +import qualified System.Random as Random +import Data.List (maximumBy) +import qualified Par +import qualified Control.Monad.State as State +import RandomState (splits) +import Data.Function (on) +import qualified Control.Concurrent.Chan as Chan +import System.Timeout (timeout) +import Control.Exception (evaluate) + +class Evolvable e where + mutate :: Random.RandomGen g => e -> State.State g e + score :: e -> Double + +numChildren :: Int +numChildren = 100 + +printModCount :: Int +printModCount = 100 + +scoreTimeout :: Int +scoreTimeout = 1000 + +mutateProbability :: Double +mutateProbability = 0.005 + +evolve :: (Evolvable e, Show e) => Chan.Chan e -> e -> IO () +evolve c e = evolve' 0 c e 0 + +timeoutScore :: Evolvable e => e -> IO Double +timeoutScore e = maybe (-1) id <$> timeout scoreTimeout (evaluate (score e)) + +evolve' :: (Evolvable e, Show e) => Int -> Chan.Chan e -> e -> Double -> IO () +evolve' generation chan startState myScore = do gs <- take numChildren . State.evalState splits <$> Random.newStdGen + childrenScores <- ((myScore, startState) :) <$> Par.mapIO scoreChild gs + let (bestScore, bestChild) = maximumBy (compare `on` fst) childrenScores + if generation `mod` printModCount == 0 + then Chan.writeChan chan bestChild + else return () + evolve' (succ generation) chan bestChild bestScore + where scoreChild g = do let myChild = State.evalState (mutate startState) g + realScore <- timeoutScore myChild + return (realScore, myChild) -- cgit v1.3.1