Tree generates arbitrary compounds (needs rename -.-)
This commit is contained in:
@ -2,12 +2,24 @@
|
||||
{-# LANGUAGE DeriveFoldable #-}
|
||||
{-# LANGUAGE DeriveTraversable #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
module Arbitrary where
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
module ArbitraryEnzymeTree
|
||||
( EnzymeTree
|
||||
, getTreeSize
|
||||
, getElement
|
||||
, getShape
|
||||
, getSubTrees
|
||||
, treeFromList
|
||||
, generateTreeFromList
|
||||
, generateDotFromTree
|
||||
) where
|
||||
|
||||
import Test.QuickCheck
|
||||
import GHC.Generics (Generic(..))
|
||||
import GHC.Generics (Generic())
|
||||
import Text.Pretty.Simple
|
||||
import Data.List
|
||||
import Data.String (IsString(..))
|
||||
import Data.Monoid
|
||||
|
||||
data TreeShape = Root
|
||||
{ treeSize :: Int
|
||||
@ -46,9 +58,34 @@ getTreeSize (EnzymeTree (Root a _) _ _) = a
|
||||
getShape :: EnzymeTree s a -> TreeShape
|
||||
getShape (EnzymeTree s _ _) = s
|
||||
|
||||
getElement :: EnzymeTree s a -> a
|
||||
getElement (EnzymeTree _ e _) = e
|
||||
|
||||
getSubTrees :: EnzymeTree s a -> [EnzymeTree TreeShape a]
|
||||
getSubTrees (EnzymeTree _ _ s) = s
|
||||
|
||||
treeFromList :: TreeShape -> [a] -> EnzymeTree s a
|
||||
treeFromList (Root n ns) (a:as) = EnzymeTree (Root n ns) a (unfoldr go (ns,as))
|
||||
where
|
||||
go :: ([TreeShape],[a]) -> Maybe (EnzymeTree s a,([TreeShape],[a]))
|
||||
go (n:ns,as) = Just (treeFromList n (take (treeSize n) as), (ns, drop (treeSize n) as))
|
||||
go ([],_) = Nothing
|
||||
|
||||
generateTreeFromList :: Int -> [a] -> IO (EnzymeTree s a)
|
||||
generateTreeFromList s a = flip treeFromList a . getShape <$> generate (resize s arbitrary :: Gen (EnzymeTree s ()))
|
||||
|
||||
|
||||
generateDotFromTree :: (Show a, IsString b, Monoid b) => b -> EnzymeTree s a -> b
|
||||
generateDotFromTree name t = "digraph " <> name <> " {\n"
|
||||
<> generateDotFromTree' t
|
||||
<> "}\n"
|
||||
where
|
||||
generateDotFromTree' :: (Show a, IsString b, Monoid b) => EnzymeTree s a -> b
|
||||
generateDotFromTree' (EnzymeTree _ num ns) =
|
||||
" " <> wrap (ts num) <> " -> { "
|
||||
<> mconcat (intersperse " " (wrap . ts . getElement <$> ns))
|
||||
<> " };\n"
|
||||
<> mconcat (generateDotFromTree' <$> ns)
|
||||
where
|
||||
ts = fromString . show
|
||||
wrap x = "\"" <> x <> "\""
|
@ -1,9 +1,5 @@
|
||||
{-# LANGUAGE RecordWildCards #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
|
||||
module Environment where
|
||||
|
||||
|
||||
import Data.Functor ((<$>))
|
||||
import Control.Applicative ((<*>))
|
||||
import Control.Monad (forM_)
|
||||
@ -30,17 +26,17 @@ data Component = PP
|
||||
| FPP
|
||||
deriving (Show, Enum, Bounded, Eq)
|
||||
|
||||
-- | Compounds are either direct nutrients, already processed components or GenericEnzymes
|
||||
-- | Compounds are either direct nutrients, already processed components or GenericCompound
|
||||
data Compound = Substrate Nutrient
|
||||
| Produced Component
|
||||
| GenericEnzyme Int
|
||||
| GenericCompound Int
|
||||
deriving (Show, Eq)
|
||||
|
||||
instance Enum Compound where
|
||||
toEnum x
|
||||
| x <= maxS = Substrate . toEnum $ x
|
||||
| x - (maxS+1) <= maxP = Produced . toEnum $ x - (maxS + 1)
|
||||
| otherwise = GenericEnzyme $ x - (maxS + 1) - (maxP + 1)
|
||||
| otherwise = GenericCompound $ x - (maxS + 1) - (maxP + 1)
|
||||
where
|
||||
maxS = fromEnum (maxBound :: Nutrient)
|
||||
maxP = fromEnum (maxBound :: Component)
|
||||
@ -49,7 +45,7 @@ instance Enum Compound where
|
||||
fromEnum (Produced x) = fromEnum x + maxS + 1
|
||||
where
|
||||
maxS = fromEnum (maxBound :: Nutrient)
|
||||
fromEnum (GenericEnzyme x) = x + maxS + maxP + 2
|
||||
fromEnum (GenericCompound x) = x + maxS + maxP + 2
|
||||
where
|
||||
maxS = fromEnum (maxBound :: Nutrient)
|
||||
maxP = fromEnum (maxBound :: Component)
|
||||
@ -153,7 +149,7 @@ fitness p = do
|
||||
nutrients <- absorbNutrients p -- absorb soil
|
||||
products <- produceCompounds p nutrients -- produce compounds
|
||||
survivalRate <- deterPredators products -- defeat predators with produced compounds
|
||||
let sumEnzymes = sum $ (\(_,q,a) -> (fromIntegral q)*a) <$> genome p -- amount of enzymes * activation = resources "wasted"
|
||||
let sumEnzymes = sum $ (\(_,q,a) -> fromIntegral q*a) <$> genome p -- amount of enzymes * activation = resources "wasted"
|
||||
costOfEnzymes = 0.95 ** sumEnzymes
|
||||
return $ survivalRate * costOfEnzymes
|
||||
-- can also be written as, but above is more clear.
|
||||
@ -161,11 +157,11 @@ fitness p = do
|
||||
|
||||
produceCompounds :: Plant -> [(Nutrient, Amount)] -> World (Vector Amount)
|
||||
produceCompounds (Plant genes _) substrate = do
|
||||
numIter <- metabolismIteration <$> ask
|
||||
numCompounds <- maxCompound <$> ask
|
||||
numIter <- asks metabolismIteration
|
||||
numCompounds <- asks maxCompound
|
||||
let
|
||||
initialAmount = (assoc (numCompounds+1) 0 ((\(n,a) -> (fromEnum $ Substrate n,a)) <$> substrate)) :: Vector Amount
|
||||
enzymes = (\(e,q,a) -> (synthesis e,(fromIntegral q)*a)) <$> genes -- [(((Component,Amount),(Component,Amount)),q*a)], Amount got * by quantity & activation
|
||||
initialAmount = assoc (numCompounds+1) 0 ((\(n,a) -> (fromEnum $ Substrate n,a)) <$> substrate) :: Vector Amount
|
||||
enzymes = (\(e,q,a) -> (synthesis e,fromIntegral q*a)) <$> genes -- [(((Component,Amount),(Component,Amount)),q*a)], Amount got * by quantity & activation
|
||||
positions = concat $ (\(((i,ia),(o,oa)),f) -> [((fromEnum i,fromEnum i),f*ia),((fromEnum o,fromEnum o),f*ia),((fromEnum o,fromEnum i),f*oa),((fromEnum i,fromEnum o),f*oa)]) <$> enzymes -- [((row,column),amount)]
|
||||
mat = accum (konst 0 (numCompounds+1,numCompounds+1)) (+) positions --accumulate all entries into one matrix.
|
||||
-- mat is now the rate of change in u'(t) = A u(t)
|
||||
@ -179,14 +175,14 @@ produceCompounds (Plant genes _) substrate = do
|
||||
|
||||
deterPredators :: Vector Amount -> World Probability
|
||||
deterPredators cs = do
|
||||
ps <- predators <$> ask
|
||||
ts <- toxicCompounds <$> ask
|
||||
let
|
||||
ps <- asks predators
|
||||
ts <- asks toxicCompounds
|
||||
let
|
||||
deter :: Predator -> Double
|
||||
-- multiply (toxicity of t with 100% effectiveness at l| for all toxins t | and t not in p's resistance-list)
|
||||
deter p = product [1 - min 1 (cs ! (fromEnum t) / l) | (t,l) <- ts, not (t `elem` resistance p)]
|
||||
deter p = product [1 - min 1 (cs ! fromEnum t / l) | (t,l) <- ts, t `notElem` resistance p]
|
||||
-- multiply (probability of occurence * intensity of destruction / probability to deter predator | for all predators)
|
||||
return . product $ [min 1 ((1-prob) * fitnessImpact p / deter p) | (p,prob) <- ps]
|
||||
return . product $ [min 1 ((1-prob) * fitnessImpact p / deter p) | (p,prob) <- ps]
|
||||
|
||||
-- Mating & Creation of diversity
|
||||
-- ------------------------------
|
||||
@ -201,7 +197,7 @@ haploMate (Plant genes abs) = do
|
||||
r3 <- liftIO ((randoms <$> newStdGen) :: IO [Double])
|
||||
r4 <- liftIO ((randoms <$> newStdGen) :: IO [Double])
|
||||
r5 <- liftIO ((randoms <$> newStdGen) :: IO [Double])
|
||||
enzymes <- possibleEnzymes <$> ask
|
||||
enzymes <- asks possibleEnzymes
|
||||
re1 <- liftIO ((randomRs (0,length enzymes - 1) <$> newStdGen) :: IO [Int])
|
||||
re2 <- liftIO ((randomRs (0,length enzymes - 1) <$> newStdGen) :: IO [Int])
|
||||
let
|
||||
@ -221,17 +217,17 @@ haploMate (Plant genes abs) = do
|
||||
duplicateGene _ [] = []
|
||||
|
||||
addGene :: [Double] -> [Int] -> Genome -> Genome
|
||||
addGene (r:rs) (s:ss) g = if r < 0.01 then ((enzymes !! s),1,1):g else g
|
||||
addGene (r:rs) (s:ss) g = if r < 0.01 then (enzymes !! s,1,1):g else g
|
||||
|
||||
noiseActivation :: [Double] -> Genome -> Genome
|
||||
noiseActivation (r:rs) ((e,q,a):gs) = (e,q,max 0 $ min 1 $ a-0.01+0.02*r):noiseActivation rs gs
|
||||
noiseActivation _ [] = []
|
||||
|
||||
mutateGene :: [Double] -> [Int] -> Genome -> Genome
|
||||
mutateGene (r:rs) (s:ss) ((e,1,a):gs) = if r < 0.05 then ((enzymes !! s),1,a):mutateGene rs ss gs
|
||||
mutateGene (r:rs) (s:ss) ((e,1,a):gs) = if r < 0.05 then (enzymes !! s,1,a):mutateGene rs ss gs
|
||||
else (e,1,a):mutateGene rs ss gs
|
||||
|
||||
mutateGene (r:rs) (s:ss) ((e,q,a):gs) = if r < 0.05 then (e,q-1,a):((enzymes !! s),1,a):mutateGene rs ss gs
|
||||
mutateGene (r:rs) (s:ss) ((e,q,a):gs) = if r < 0.05 then (e,q-1,a):(enzymes !! s,1,a):mutateGene rs ss gs
|
||||
else (e,q,a):mutateGene rs ss gs
|
||||
mutateGene (r:rs) (s:ss) [] = []
|
||||
return $ Plant genes' abs
|
||||
@ -243,7 +239,7 @@ haploMate (Plant genes abs) = do
|
||||
|
||||
-- | Plant with no secondary metabolism with unlimited extraction from environment.
|
||||
emptyPlant :: Plant
|
||||
emptyPlant = Plant [] (soil <$> ask)
|
||||
emptyPlant = Plant [] (asks soil)
|
||||
|
||||
getAmountOf :: Compound -> [(Compound, Amount)] -> Amount
|
||||
getAmountOf c = sum . fmap snd . filter ((== c) . fst)
|
||||
|
Reference in New Issue
Block a user