summaryrefslogtreecommitdiff
path: root/src/Genome.hs
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-11-29 16:25:38 -0600
committersanine <sanine.not@pm.me>2023-11-29 16:25:38 -0600
commit4c63f3d4dba0c7164cce9559f09dc82612cdee36 (patch)
tree46204da85448e7ca97cb5ac2aaa90134c9c7e23c /src/Genome.hs
parent3047e46f3478e20250556de833c1b6dd1b1a31f0 (diff)
implement mutateGenomeAddGene
Diffstat (limited to 'src/Genome.hs')
-rw-r--r--src/Genome.hs31
1 files changed, 28 insertions, 3 deletions
diff --git a/src/Genome.hs b/src/Genome.hs
index 500512c..927005e 100644
--- a/src/Genome.hs
+++ b/src/Genome.hs
@@ -8,6 +8,7 @@ module Genome
, mutateGenomeAddInternal
, mutateGenomeRemoveInternal
+ , mutateGenomeAddGene
) where
@@ -111,8 +112,6 @@ validn g (Output x)
| (inRange (0, numOutput g - 1) x) = Output x
| otherwise = error "out of range Output!"
-
-
incrementNeuron :: Genome -> NeuronIndex -> NeuronIndex
incrementNeuron g (Input x)
| (x >= numInput g - 1) = validn g (Internal 0)
@@ -124,7 +123,6 @@ incrementNeuron g (Output x)
| (x >= numOutput g - 1) = error "cannot increment past the end of outputs!"
| otherwise = validn g (Output $ x+1)
-
decrementNeuron :: Genome -> NeuronIndex -> NeuronIndex
decrementNeuron g (Input x)
| (x <= 0) = error "cannot decrement past the first Input!"
@@ -139,3 +137,30 @@ decrementNeuron g (Output x)
isInternal :: NeuronIndex -> Bool
isInternal (Internal _) = True
isInternal _ = False
+
+
+-- add a new, random gene
+mutateGenomeAddGene :: RandomGen a => Genome -> a -> (Genome, a)
+mutateGenomeAddGene g r =
+ let
+ (so, r') = randomSource g r
+ (si, r'') = randomSink g r'
+ (w, r''') = randomR (-4, 4) r''
+ gene = Gene so si w
+ in (g {genes = gene:(genes g)}, r''')
+
+
+
+randomSource :: RandomGen a => Genome -> a -> (NeuronIndex, a)
+randomSource g r =
+ let
+ (idx, r') = randomR (0, numInput g + numInternal g - 1) r
+ result = if idx < numInput g then Input idx else Internal $ idx - numInput g
+ in (result, r')
+
+randomSink :: RandomGen a => Genome -> a -> (NeuronIndex, a)
+randomSink g r =
+ let
+ (idx, r') = randomR (0, numInternal g + numOutput g - 1) r
+ result = if idx < numInternal g then Internal idx else Output $ idx - numInput g
+ in (result, r')