Estoy escribiendo un algoritmo genético para generar la cadena "helloworld". Pero la función evolucionar crea un desbordamiento de pila cuando n es 10.000 o más.Haskell Stack Overflow
module Genetics where
import Data.List (sortBy)
import Random (randomRIO)
import Control.Monad (foldM)
class Gene g where
-- How ideal is the gene from 0.0 to 1.0?
fitness :: g -> Float
-- How does a gene mutate?
mutate :: g -> IO g
-- How many species will be explored?
species :: [g] -> Int
orderFitness :: (Gene g) => [g] -> [g]
orderFitness = reverse . sortBy (\a b -> compare (fitness a) (fitness b))
compete :: (Gene g) => [g] -> IO [g]
compete pool = do
let s = species pool
variants <- (mapM (mapM mutate) . map (replicate s)) pool
let pool' = (map head . map orderFitness) variants
return pool'
evolve :: (Gene g) => Int -> [g] -> IO [g]
evolve 0 pool = return pool
evolve n pool = do
pool' <- compete pool
evolve (n - 1) pool'
Con species pool = 8
, un grupo de 8 genes se replica en 8 grupos. Cada grupo muta, y el más apto de cada grupo se selecciona para una mayor evolución (de vuelta a 8 genes).
Suponiendo que estés usando '-O2' GHC como su compilador, su primera versión no tiene ningún desbordamiento de pila en el' evolve' función. Como no podemos ver la implementación de 'competir ', eso es todo lo que se puede decir. –
El enlace de GitHub proporcionado anteriormente (https://github.com/mcandre/genetics) especifica 'compete' y también un Makefile que de hecho usa' ghc -O2'. Pensé que '<-' en el primer ejemplo era lo suficientemente bueno para evitar el desbordamiento de la pila.No estoy seguro de dónde se encuentra el problema. – mcandre
>> = debe ser igual a la notación do, no hay diferencia allí. – alternative