github.com/yaricom/goNEAT@v0.0.0-20210507221059-e2110b885482/neat/network/link.go (about) 1 package network 2 3 import ( 4 "fmt" 5 "github.com/yaricom/goNEAT/neat" 6 ) 7 8 // A LINK is a connection from one node to another with an associated weight. 9 // It can be marked as recurrent. 10 type Link struct { 11 // Weight of connection 12 Weight float64 13 // NNode inputting into the link 14 InNode *NNode 15 // NNode that the link affects 16 OutNode *NNode 17 // If TRUE the link is recurrent 18 IsRecurrent bool 19 // If TRUE the link is time delayed 20 IsTimeDelayed bool 21 22 // Points to a trait of parameters for genetic creation 23 Trait *neat.Trait 24 25 /* ************ LEARNING PARAMETERS *********** */ 26 // The following parameters are for use in neurons that learn through habituation, 27 // sensitization, or Hebbian-type processes 28 Params []float64 29 // The amount of weight adjustment 30 AddedWeight float64 31 } 32 33 // Creates new link with specified weight, input and output neurons connected recurrently or not. 34 func NewLink(weight float64, inputNode, outNode *NNode, recurrent bool) *Link { 35 link := newLink(weight) 36 link.InNode = inputNode 37 link.OutNode = outNode 38 link.IsRecurrent = recurrent 39 return link 40 } 41 42 // Creates new Link with specified Trait 43 func NewLinkWithTrait(trait *neat.Trait, weight float64, inputNode, outNode *NNode, recurrent bool) *Link { 44 link := newLink(weight) 45 link.InNode = inputNode 46 link.OutNode = outNode 47 link.IsRecurrent = recurrent 48 link.Trait = trait 49 link.deriveTrait(trait) 50 return link 51 } 52 53 // The copy constructor to create new link with parameters taken from provided ones and connecting specified nodes 54 func NewLinkCopy(l *Link, inputNode, outNode *NNode) *Link { 55 link := newLink(l.Weight) 56 link.InNode = inputNode 57 link.OutNode = outNode 58 link.Trait = l.Trait 59 link.deriveTrait(l.Trait) 60 link.IsRecurrent = l.IsRecurrent 61 return link 62 } 63 64 // The private default constructor 65 func newLink(weight float64) *Link { 66 return &Link{ 67 Weight: weight, 68 } 69 } 70 71 // Checks if this link is genetically equal to provided one, i.e. connects nodes with the same IDs and has equal 72 // recurrent flag. I.e. if both links represent the same Gene. 73 func (l *Link) IsEqualGenetically(ol *Link) bool { 74 sameInNode := l.InNode.Id == ol.InNode.Id 75 sameOutNode := l.OutNode.Id == ol.OutNode.Id 76 sameRecurrent := l.IsRecurrent == ol.IsRecurrent 77 78 return sameInNode && sameOutNode && sameRecurrent 79 } 80 81 // The Link methods implementation 82 func (l *Link) String() string { 83 return fmt.Sprintf("[Link: (%s <-> %s), weight: %.3f, recurrent: %t, time delayed: %t]", 84 l.InNode, l.OutNode, l.Weight, l.IsRecurrent, l.IsTimeDelayed) 85 } 86 87 // Copy trait parameters into this link's parameters 88 func (l *Link) deriveTrait(t *neat.Trait) { 89 if t != nil { 90 l.Params = make([]float64, len(t.Params)) 91 for i, p := range t.Params { 92 l.Params[i] = p 93 } 94 } 95 }