github.com/yaricom/goNEAT@v0.0.0-20210507221059-e2110b885482/neat/genetics/mimo_gene.go (about) 1 package genetics 2 3 import ( 4 "github.com/yaricom/goNEAT/neat/network" 5 "fmt" 6 ) 7 8 // The Multiple-Input Multiple-Output (MIMO) control Gene allows to create modular genomes, in which several groups of genes 9 // connected through single MIMO Gene and corresponding control function is applied to all inputs in order to produce 10 // outputs. This allows to build modular hierarchical genomes which can be considered as sum of constituent components 11 // and evolved as a whole and as a concrete parts simultaneously. 12 type MIMOControlGene struct { 13 // The current innovation number for this gene 14 InnovationNum int64 15 // Used to see how much mutation has changed the link 16 MutationNum float64 17 // If true the gene is enabled 18 IsEnabled bool 19 20 // The control node with control/activation function 21 ControlNode *network.NNode 22 23 // The list of associated IO nodes for fast traversal 24 ioNodes []*network.NNode 25 } 26 27 // Creates new MIMO gene 28 func NewMIMOGene(control_node *network.NNode, innov_num int64, mut_num float64, enabled bool) *MIMOControlGene { 29 gene := &MIMOControlGene{ 30 ControlNode:control_node, 31 InnovationNum:innov_num, 32 MutationNum:mut_num, 33 IsEnabled:enabled, 34 } 35 // collect IO nodes list 36 gene.ioNodes = make([]*network.NNode, 0) 37 for _, l := range control_node.Incoming { 38 gene.ioNodes = append(gene.ioNodes, l.InNode) 39 } 40 for _, l := range control_node.Outgoing { 41 gene.ioNodes = append(gene.ioNodes, l.OutNode) 42 } 43 44 return gene 45 } 46 47 // The copy constructor taking parameters from provided control gene for given control node 48 func NewMIMOGeneCopy(g *MIMOControlGene, control_node *network.NNode) *MIMOControlGene { 49 cg := NewMIMOGene(control_node, g.InnovationNum, g.MutationNum, g.IsEnabled) 50 return cg 51 } 52 53 // Tests whether this gene has intersection with provided map of nodes, i.e. any of it's IO nodes included into list 54 func (g *MIMOControlGene) hasIntersection(nodes map[int]*network.NNode) bool { 55 for _, nd := range g.ioNodes { 56 if _, Ok := nodes[nd.Id]; Ok { 57 // found 58 return true 59 } 60 } 61 return false 62 } 63 64 // The stringer 65 func (g *MIMOControlGene) String() string { 66 enabl_str := "" 67 if !g.IsEnabled { 68 enabl_str = " -DISABLED-" 69 } 70 return fmt.Sprintf("[MIMO Gene INNOV (%4d, % .3f) %s control node: %s]", 71 g.InnovationNum, g.MutationNum, enabl_str, g.ControlNode.String()) 72 }