Example #1
0
        /// <summary>
        /// Create a network definition by querying the provided IBlackBox (typically a CPPN) with the
        /// substrate connection endpoints.
        /// </summary>
        /// <param name="blackbox">The HyperNEAT CPPN that defines the strength of connections between nodes on the substrate.</param>
        /// <param name="lengthCppnInput">Optionally we provide a connection length input to the CPPN.</param>
        public INetworkDefinition CreateNetworkDefinition(IBlackBox blackbox, bool lengthCppnInput)
        {
            // Get the sequence of substrate connections. Either a pre-built list or a dynamically
            // generated sequence.
            IEnumerable <SubstrateConnection> connectionSequence = _connectionList ?? GetConnectionSequence();

            // Iterate over substrate connections. Determine each connection's weight and create a list
            // of network definition connections.
            ISignalArray   inputSignalArr  = blackbox.InputSignalArray;
            ISignalArray   outputSignalArr = blackbox.OutputSignalArray;
            ConnectionList networkConnList = new ConnectionList(_connectionCountHint);
            int            lengthInputIdx  = _dimensionality + _dimensionality;

            foreach (SubstrateConnection substrateConn in connectionSequence)
            {
                // Assign the connection's endpoint position coords to the CPPN/blackbox inputs. Note that position dimensionality is not fixed.
                for (int i = 0; i < _dimensionality; i++)
                {
                    inputSignalArr[i] = substrateConn._srcNode._position[i];
                    inputSignalArr[i + _dimensionality] = substrateConn._tgtNode._position[i];
                }

                // Optional connection length input.
                if (lengthCppnInput)
                {
                    inputSignalArr[lengthInputIdx] = CalculateConnectionLength(substrateConn._srcNode._position, substrateConn._tgtNode._position);
                }

                // Reset blackbox state and activate it.
                blackbox.ResetState();
                blackbox.Activate();

                // Read connection weight from output 0.
                double weight = outputSignalArr[0];

                // Skip connections with a weight magnitude less than _weightThreshold.
                double weightAbs = Math.Abs(weight);
                if (weightAbs > _weightThreshold)
                {
                    // For weights over the threshold we re-scale into the range [-_maxWeight,_maxWeight],
                    // assuming IBlackBox outputs are in the range [-1,1].
                    weight = (weightAbs - _weightThreshold) * _weightRescalingCoeff * Math.Sign(weight);

                    // Create network definition connection and add to list.
                    networkConnList.Add(new NetworkConnection(substrateConn._srcNode._id,
                                                              substrateConn._tgtNode._id, weight));
                }
            }

            // Additionally we create connections from each hidden and output node to a bias node that is not defined at any
            // position on the substrate. The motivation here is that a each node's input bias is independent of any source
            // node (and associated source node position on the substrate). That we refer to a bias 'node' is a consequence of how input
            // biases are handled in NEAT - with a specific bias node that other nodes can be connected to.
            int setCount = _nodeSetList.Count;

            for (int i = 1; i < setCount; i++)
            {
                SubstrateNodeSet nodeSet = _nodeSetList[i];
                foreach (SubstrateNode node in nodeSet.NodeList)
                {
                    // Assign the node's position coords to the blackbox inputs. The CPPN inputs for source node coords are set to zero when obtaining bias values.
                    for (int j = 0; j < _dimensionality; j++)
                    {
                        inputSignalArr[j] = 0.0;
                        inputSignalArr[j + _dimensionality] = node._position[j];
                    }

                    // Optional connection length input.
                    if (lengthCppnInput)
                    {
                        inputSignalArr[lengthInputIdx] = CalculateConnectionLength(node._position);
                    }

                    // Reset blackbox state and activate it.
                    blackbox.ResetState();
                    blackbox.Activate();

                    // Read bias connection weight from output 1.
                    double weight = outputSignalArr[1];

                    // Skip connections with a weight magnitude less than _weightThreshold.
                    double weightAbs = Math.Abs(weight);
                    if (weightAbs > _weightThreshold)
                    {
                        // For weights over the threshold we re-scale into the range [-_maxWeight,_maxWeight],
                        // assuming IBlackBox outputs are in the range [-1,1].
                        weight = (weightAbs - _weightThreshold) * _weightRescalingCoeff * Math.Sign(weight);

                        // Create network definition connection and add to list. Bias node is always ID 0.
                        networkConnList.Add(new NetworkConnection(0, node._id, weight));
                    }
                }
            }

            // Check for no connections.
            // If no connections were generated then there is no point in further evaulating the network.
            // However, null is a valid response when decoding genomes to phenomes, therefore we do that here.
            if (networkConnList.Count == 0)
            {
                return(null);
            }

            // Construct and return a network definition.
            NetworkDefinition networkDef = new NetworkDefinition(_inputNodeCount, _outputNodeCount,
                                                                 _activationFnLibrary, _netNodeList, networkConnList);

            // Check that the definition is valid and return it.
            Debug.Assert(networkDef.PerformIntegrityCheck());
            return(networkDef);
        }
Example #2
0
        /// <summary>
        /// Create a network definition by querying the provided IBlackBox (typically a CPPN) with the
        /// substrate connection endpoints.
        /// </summary>
        /// <param name="blackbox">The HyperNEAT CPPN that defines the strength of connections between nodes on the substrate.</param>
        /// <param name="lengthCppnInput">Optionally we provide a connection length input to the CPPN.</param>
        public INetworkDefinition CreateNetworkDefinition(IBlackBox blackbox, bool lengthCppnInput)
        {
            // Iterate over substrate connections. Determine each connection's weight and create a list
            // of network definition connections.
            ISignalArray   inputSignalArr  = blackbox.InputSignalArray;
            ISignalArray   outputSignalArr = blackbox.OutputSignalArray;
            ConnectionList networkConnList = new ConnectionList(_connectionCountHint);
            int            lengthInputIdx  = Dimensionality + Dimensionality;

            for (int i = 0; i < N; i++)
            {
                foreach (var substrateConnection in _connectionList[i])
                {
                    for (int j = 0; j < Dimensionality; j++)
                    {
                        inputSignalArr[j] = substrateConnection._srcNode._position[j];
                        inputSignalArr[j + Dimensionality] = substrateConnection._tgtNode._position[j];
                    }
                    // Optional connection length input.
                    if (lengthCppnInput)
                    {
                        inputSignalArr[lengthInputIdx] = CalculateConnectionLength(substrateConnection._srcNode._position, substrateConnection._tgtNode._position);
                    }
                    blackbox.ResetState();
                    blackbox.Activate();
                    double weight = outputSignalArr[i];

                    //if LEO is toggled query for expression
                    double expressionWeight = -0.1;
                    if (Leo)
                    {
                        expressionWeight = outputSignalArr[i + M + N];
                    }
                    // Skip connections with a weight magnitude less than _weightThreshold.
                    double weightAbs = Math.Abs(weight);
                    if (!Leo && weightAbs > _weightThreshold || Leo && expressionWeight >= 0.0)
                    {
                        // For weights over the threshold we re-scale into the range [-_maxWeight,_maxWeight],
                        // assuming IBlackBox outputs are in the range [-1,1].
                        weight = (weightAbs - _weightThreshold) * _weightRescalingCoeff * Math.Sign(weight);

                        // Create network definition connection and add to list.
                        networkConnList.Add(new NetworkConnection(substrateConnection._srcNode._id,
                                                                  substrateConnection._tgtNode._id, weight));
                    }
                }
            }
            var biasOutputIdx = N;

            foreach (var nodeSet in _outputLayers.Concat(_hiddenLayers))
            {
                foreach (var node in nodeSet.NodeList)
                {
                    // Assign the node's position coords to the blackbox inputs. The CPPN inputs for source node coords are set to zero when obtaining bias values.
                    for (int j = 0; j < Dimensionality; j++)
                    {
                        inputSignalArr[j] = 0.0;
                        inputSignalArr[j + Dimensionality] = node._position[j];
                    }

                    // Optional connection length input.
                    if (lengthCppnInput)
                    {
                        inputSignalArr[lengthInputIdx] = CalculateConnectionLength(node._position);
                    }

                    // Reset blackbox state and activate it.
                    blackbox.ResetState();
                    blackbox.Activate();

                    // Read bias connection weight from output 1.
                    double weight = outputSignalArr[biasOutputIdx];
                    // Skip connections with a weight magnitude less than _weightThreshold.
                    double weightAbs = Math.Abs(weight);
                    if (weightAbs > _weightThreshold)
                    {
                        // For weights over the threshold we re-scale into the range [-_maxWeight,_maxWeight],
                        // assuming IBlackBox outputs are in the range [-1,1].
                        weight = (weightAbs - _weightThreshold) * _weightRescalingCoeff * Math.Sign(weight);

                        // Create network definition connection and add to list. Bias node is always ID 0.
                        networkConnList.Add(new NetworkConnection(0, node._id, weight));
                    }
                }
                biasOutputIdx++;
            }

            // Check for no connections.
            // If no connections were generated then there is no point in further evaulating the network.
            // However, null is a valid response when decoding genomes to phenomes, therefore we do that here.
            if (networkConnList.Count == 0)
            {
                return(null);
            }

            // Construct and return a network definition.
            NetworkDefinition networkDef = new NetworkDefinition(_inputLayers.Sum(x => x.NodeList.Count), _outputLayers.Sum(x => x.NodeList.Count),
                                                                 _activationFnLibrary, _netNodeList, networkConnList);

            // Check that the definition is valid and return it.
            Debug.Assert(networkDef.PerformIntegrityCheck());
            return(networkDef);
        }