func findDownstreamNodeId(cortex *ng.Cortex, layerMap ng.LayerToNodeIdMap, fromLayer float64) *ng.NodeId { numAttempts := len(cortex.AllNodeIds()) * 5 for i := 0; i < numAttempts; i++ { downstreamNodeId := layerMap.ChooseNodeIdFollowingLayer(fromLayer) if downstreamNodeId == nil { log.Printf("findDownstreamNodeId unable to find downstream neuron, cannot add neuron") return nil } if downstreamNodeId.NodeType == ng.ACTUATOR { // make sure it has capacity for new incoming actuator := cortex.FindActuator(downstreamNodeId) if actuator.CanAddInboundConnection() == false { continue } } return downstreamNodeId } return nil }
func Outsplice(cortex *ng.Cortex, chooseOutbound OutboundChooser) (bool, *ng.Neuron) { numAttempts := len(cortex.AllNodeIds()) * 5 for i := 0; i < numAttempts; i++ { neuronA := randomNeuron(cortex) outbound := chooseOutbound(neuronA) if outbound == nil { continue } if neuronA.NodeId.UUID == outbound.NodeId.UUID { continue } nodeIdB := outbound.NodeId // figure out which layer neuronK will go in nodeIdLayerMap := cortex.NodeIdLayerMap() layerA := neuronA.NodeId.LayerIndex layerB := nodeIdB.LayerIndex layerK := nodeIdLayerMap.LayerBetweenOrNew(layerA, layerB) // create neuron K neuronK := cortex.CreateNeuronInLayer(layerK) // disconnect neuronA <-> nodeB nodeBConnector := cortex.FindInboundConnector(nodeIdB) ng.DisconnectOutbound(neuronA, nodeIdB) ng.DisconnectInbound(nodeBConnector, neuronA) // connect neuronA -> neuronK weights := randomWeights(1) ng.ConnectOutbound(neuronA, neuronK) ng.ConnectInboundWeighted(neuronK, neuronA, weights) // connect neuronK -> nodeB switch nodeIdB.NodeType { case ng.NEURON: neuronB := cortex.FindNeuron(nodeIdB) ng.ConnectOutbound(neuronK, neuronB) ng.ConnectInboundWeighted(nodeBConnector, neuronK, weights) case ng.ACTUATOR: actuatorB := cortex.FindActuator(nodeIdB) ng.ConnectOutbound(neuronK, actuatorB) ng.ConnectInbound(nodeBConnector, neuronK) } return true, neuronK } return false, nil }
// Find a nodeId suitable for use as an outbound node for a newly created // neuron. This can either be a either another neuron node (including // the new neuron itself), or an actuator (if it has space), but it cannot // be a sensor node func findRecurrentOutboundNodeId(cortex *ng.Cortex, layerMap ng.LayerToNodeIdMap, fromLayer float64) *ng.NodeId { numAttempts := len(cortex.AllNodeIds()) * 5 keys := layerMap.Keys() sensorLayer := keys[0] for i := 0; i < numAttempts; i++ { chosenNodeId := layerMap.ChooseNodeIdFollowingLayer(sensorLayer) if chosenNodeId.NodeType == ng.ACTUATOR { // make sure it has capacity for new incoming actuator := cortex.FindActuator(chosenNodeId) if actuator.CanAddInboundConnection() == false { continue } } return chosenNodeId } return nil }