예제 #1
0
        /// <summary>
        /// Returns true if there is at least one connectivity cycle within the provided INetworkDefinition.
        /// </summary>
        public bool IsNetworkCyclicInternal(INetworkDefinition networkDef)
        {
            // Clear any existing state (allow reuse of this class).
            _ancestorNodeSet.Clear();
            _visitedNodeSet.Clear();

            // Get and store connectivity data for the network.
            _networkConnectivityData = networkDef.GetConnectivityData();

            // Loop over all nodes. Take each one in turn as a traversal root node.
            foreach(INetworkNode node in networkDef.NodeList)
            {
                // Determine if the node has already been visited.
                if(_visitedNodeSet.Contains(node.Id)) 
                {   // Already traversed; Skip.
                    continue;
                }

                // Traverse into the node. 
                if(TraverseNode(node.Id))
                {   // Cycle detected.
                    return true;
                }
            }

            // No cycles detected.
            return false;
        }
예제 #2
0
        /// <summary>
        /// Creates a CyclicNetwork from an INetworkDefinition.
        /// </summary>
        public static CyclicNetwork CreateCyclicNetwork(INetworkDefinition networkDef,
                                                        NetworkActivationScheme activationScheme)
        {
            List <Neuron>     neuronList;
            List <Connection> connectionList;

            InternalDecode(networkDef, out neuronList, out connectionList);

            // Construct neural net.
            if (activationScheme.RelaxingActivation)
            {
                return(new RelaxingCyclicNetwork(neuronList,
                                                 connectionList,
                                                 networkDef.InputNodeCount,
                                                 networkDef.OutputNodeCount,
                                                 activationScheme.MaxTimesteps,
                                                 activationScheme.SignalDeltaThreshold));
            }

            return(new CyclicNetwork(neuronList,
                                     connectionList,
                                     networkDef.InputNodeCount,
                                     networkDef.OutputNodeCount,
                                     activationScheme.TimestepsPerActivation));
        }
예제 #3
0
        /// <summary>
        /// Writes an INetworkDefinition to XML.
        /// </summary>
        /// <param name="xw">XmlWriter to write XML to.</param>
        /// <param name="networkDef">Network definition to write as XML.</param>
        /// <param name="nodeFnIds">Indicates if node activation function IDs should be emitted. They are required
        /// for HyperNEAT genomes but not for NEAT.</param>
        public static void Write(XmlWriter xw, INetworkDefinition networkDef, bool nodeFnIds)
        {
            xw.WriteStartElement(__ElemNetwork);

            // Emit nodes.
            xw.WriteStartElement(__ElemNodes);
            foreach (INetworkNode node in networkDef.NodeList)
            {
                xw.WriteStartElement(__ElemNode);
                xw.WriteAttributeString(__AttrType, GetNodeTypeString(node.NodeType));
                xw.WriteAttributeString(__AttrId, node.Id.ToString(NumberFormatInfo.InvariantInfo));
                if (nodeFnIds)
                {
                    xw.WriteAttributeString(__AttrActivationFunctionId, node.ActivationFnId.ToString(NumberFormatInfo.InvariantInfo));
                }
                xw.WriteEndElement();
            }
            xw.WriteEndElement();

            // Emit connections.
            xw.WriteStartElement(__ElemConnections);
            foreach (INetworkConnection con in networkDef.ConnectionList)
            {
                xw.WriteStartElement(__ElemConnection);
                xw.WriteAttributeString(__AttrSourceId, con.SourceNodeId.ToString(NumberFormatInfo.InvariantInfo));
                xw.WriteAttributeString(__AttrTargetId, con.TargetNodeId.ToString(NumberFormatInfo.InvariantInfo));
                xw.WriteAttributeString(__AttrWeight, con.Weight.ToString("R", NumberFormatInfo.InvariantInfo));
                xw.WriteEndElement();
            }
            xw.WriteEndElement();

            // </Network>
            xw.WriteEndElement();
        }
예제 #4
0
        /// <summary>
        /// Returns true if there is at least one connectivity cycle within the provided INetworkDefinition.
        /// </summary>
        public bool IsNetworkCyclicInternal(INetworkDefinition networkDef)
        {
            // Clear any existing state (allow reuse of this class).
            _ancestorNodeSet.Clear();
            _visitedNodeSet.Clear();

            // Get and store connectivity data for the network.
            _networkConnectivityData = networkDef.GetConnectivityData();

            // Loop over all nodes. Take each one in turn as a traversal root node.
            foreach (INetworkNode node in networkDef.NodeList)
            {
                // Determine if the node has already been visited.
                if (_visitedNodeSet.Contains(node.Id))
                {   // Already traversed; Skip.
                    continue;
                }

                // Traverse into the node.
                if (TraverseNode(node.Id))
                {   // Cycle detected.
                    return(true);
                }
            }

            // No cycles detected.
            return(false);
        }
        /// <summary>
        /// Creates a CyclicNetwork from an INetworkDefinition.
        /// </summary>
        public static FastCyclicNetwork CreateFastCyclicNetwork(INetworkDefinition networkDef,
                                                                NetworkActivationScheme activationScheme)
        {
            FastConnection[] fastConnectionArray;
            IActivationFunction[] activationFnArray;
            double[][] neuronAuxArgsArray;
            InternalDecode(networkDef, 
                           activationScheme.RelaxingActivation ? activationScheme.MaxTimesteps : activationScheme.TimestepsPerActivation,
                           out fastConnectionArray, out activationFnArray, out neuronAuxArgsArray);

            // Construct neural net.
            if(activationScheme.RelaxingActivation)
            {
                return new FastRelaxingCyclicNetwork(fastConnectionArray,
                                                     activationFnArray, 
                                                     neuronAuxArgsArray,
                                                     networkDef.NodeList.Count,
                                                     networkDef.InputNodeCount,
                                                     networkDef.OutputNodeCount,
                                                     activationScheme.MaxTimesteps,
                                                     activationScheme.SignalDeltaThreshold);
            }

            return new FastCyclicNetwork(fastConnectionArray,
                                         activationFnArray,
                                         neuronAuxArgsArray,
                                         networkDef.NodeList.Count,
                                         networkDef.InputNodeCount,
                                         networkDef.OutputNodeCount,
                                         activationScheme.TimestepsPerActivation);
        }
예제 #6
0
        /// <summary>
        /// Creates a CyclicNetwork from an INetworkDefinition.
        /// </summary>
        public static FastCyclicNetwork CreateFastCyclicNetwork(INetworkDefinition networkDef,
                                                                NetworkActivationScheme activationScheme,
                                                                bool boundedOutput)
        {
            FastConnection[]      fastConnectionArray;
            IActivationFunction[] activationFnArray;
            double[][]            neuronAuxArgsArray;
            InternalDecode(networkDef,
                           activationScheme.RelaxingActivation ? activationScheme.MaxTimesteps : activationScheme.TimestepsPerActivation,
                           out fastConnectionArray, out activationFnArray, out neuronAuxArgsArray);

            // Construct neural net.
            if (activationScheme.RelaxingActivation)
            {
                return(new FastRelaxingCyclicNetwork(fastConnectionArray,
                                                     activationFnArray,
                                                     neuronAuxArgsArray,
                                                     networkDef.NodeList.Count,
                                                     networkDef.InputNodeCount,
                                                     networkDef.OutputNodeCount,
                                                     activationScheme.MaxTimesteps,
                                                     activationScheme.SignalDeltaThreshold,
                                                     boundedOutput));
            }

            return(new FastCyclicNetwork(fastConnectionArray,
                                         activationFnArray,
                                         neuronAuxArgsArray,
                                         networkDef.NodeList.Count,
                                         networkDef.InputNodeCount,
                                         networkDef.OutputNodeCount,
                                         activationScheme.TimestepsPerActivation,
                                         boundedOutput));
        }
예제 #7
0
 static void HandleNewBestNetwork(INetworkDefinition networkDefinition)
 {
     graphViewportPainter.IOGraph = graphFactory.CreateGraph(networkDefinition);
     form.Invoke((MethodInvoker) delegate {
         graphControl.RefreshImage();
     });
 }
예제 #8
0
        public BitcoinNetworkProtocolMessageSerializer(ILogger <BitcoinNetworkProtocolMessageSerializer> logger, INetworkDefinition chainDefinition, INetworkMessageSerializerManager networkMessageSerializerManager)
        {
            _logger          = logger;
            _chainDefinition = chainDefinition;
            _networkMessageSerializerManager = networkMessageSerializerManager;
            _deserializationContext          = new DeserializationContext(chainDefinition.MagicBytes);

            _peerContext = null !; //initialized by SetPeerContext
        }
예제 #9
0
        public static XmlDocument Save(INetworkDefinition networkDef, bool nodeFnIds)
        {
            XmlDocument doc = new XmlDocument();

            using (XmlWriter xw = doc.CreateNavigator().AppendChild())
            {
                Write(xw, networkDef, nodeFnIds);
            }
            return(doc);
        }
 public NetworkMessageDecoder(ILogger <NetworkMessageDecoder> logger,
                              INetworkDefinition chainDefinition,
                              INetworkMessageSerializerManager networkMessageSerializerManager,
                              ConnectionContextData contextData)
 {
     this.logger          = logger;
     this.chainDefinition = chainDefinition;
     this.networkMessageSerializerManager = networkMessageSerializerManager;
     this.ContextData = contextData;
 }
예제 #11
0
        private static void InternalDecode(INetworkDefinition networkDef,
                                           out List <Neuron> neuronList,
                                           out List <Connection> connectionList)
        {
            // Build a list of neurons.
            INodeList nodeDefList = networkDef.NodeList;
            int       nodeCount   = nodeDefList.Count;

            neuronList = new List <Neuron>(nodeCount);

            // A dictionary of neurons keyed on their innovation ID.
            var neuronDictionary = new Dictionary <uint, Neuron>(nodeCount);

            // Loop neuron genes.
            IActivationFunctionLibrary activationFnLib = networkDef.ActivationFnLibrary;

            for (int i = 0; i < nodeCount; i++)
            {   // Create a Neuron, add it to the neuron list and add an entry into neuronDictionary -
                // required for next loop.
                INetworkNode nodeDef = nodeDefList[i];

                // Note that we explicitly translate between the two NeuronType enums even though
                // they define the same types and could therefore be cast from one to the other.
                // We do this to keep genome and phenome classes completely separated and also to
                // prevent bugs - e.g. if one of the enums is changed then TranslateNeuronType() will
                // need to be modified to prevent exceptions at runtime. Otherwise a silent bug may
                // be introduced.
                Neuron neuron = new Neuron(nodeDef.Id,
                                           nodeDef.NodeType,
                                           activationFnLib.GetFunction(nodeDef.ActivationFnId),
                                           nodeDef.AuxState);
                neuronList.Add(neuron);
                neuronDictionary.Add(nodeDef.Id, neuron);
            }

            // Build a list of connections.
            IConnectionList connectionDefList = networkDef.ConnectionList;
            int             connectionCount   = connectionDefList.Count;

            connectionList = new List <Connection>(connectionCount);

            // Loop connection genes.
            for (int i = 0; i < connectionCount; i++)
            {
                INetworkConnection connDef = connectionDefList[i];
                connectionList.Add(
                    new Connection(neuronDictionary[connDef.SourceNodeId],
                                   neuronDictionary[connDef.TargetNodeId],
                                   connDef.Weight));
            }
        }
예제 #12
0
        private static void InternalDecode(INetworkDefinition networkDef,
                                           int timestepsPerActivation,
                                           out FastConnection[] fastConnectionArray,
                                           out IActivationFunction[] activationFnArray,
                                           out double[][] neuronAuxArgsArray)
        {
            // Creates an array of FastConnection(s) that represent the
            // connectivity of the network.
            fastConnectionArray = CreateFastConnectionArray(networkDef);

            // TODO: Test/optimize heuristic - this is just back of envelope maths.
            // A rough heuristic to decide if we should sort fastConnectionArray
            // by source neuron index. The principle here is that each activation
            // loop will be about 2x faster (unconfirmed) if we sort fastConnectionArray,
            // but sorting takes about n*log2(n) operations. Therefore the
            // decision to sort depends on length of fastConnectionArray and
            // _timestepsPerActivation. Another factor here is that small
            // networks will fit into CPU caches and therefore will not appear
            // to speed up - however the unsorted data will 'scramble' CPU caches
            // more than they otherwise would have and thus may slow down other
            // threads (so we just keep it simple).
            double len       = fastConnectionArray.Length;
            double timesteps = timestepsPerActivation;

            if ((len > 2) && (((len * Math.Log(len, 2)) +
                               ((timesteps * len) / 2.0)) < (timesteps * len)))
            {     // Sort fastConnectionArray by source neuron index.
                Array.Sort(fastConnectionArray, delegate(FastConnection x, FastConnection y)
                { // Use simple/fast diff method.
                    return(x._srcNeuronIdx - y._srcNeuronIdx);
                });
            }

            // Construct an array of neuron activation functions. Skip bias and
            // input neurons as these don't have an activation function
            // (because they aren't activated).
            INodeList nodeList  = networkDef.NodeList;
            int       nodeCount = nodeList.Count;
            IActivationFunctionLibrary activationFnLibrary = networkDef.ActivationFnLibrary;

            activationFnArray  = new IActivationFunction[nodeCount];
            neuronAuxArgsArray = new double[nodeCount][];

            for (int i = 0; i < nodeCount; i++)
            {
                activationFnArray[i]  = activationFnLibrary.GetFunction(nodeList[i].ActivationFnId);
                neuronAuxArgsArray[i] = nodeList[i].AuxState;
            }
        }
        private static void InternalDecode(INetworkDefinition networkDef,
                                           out List<Neuron> neuronList,
                                           out List<Connection> connectionList)
        {
            // Build a list of neurons.
            INodeList nodeDefList = networkDef.NodeList;
            int nodeCount = nodeDefList.Count;
            neuronList = new List<Neuron>(nodeCount);

            // A dictionary of neurons keyed on their innovation ID.
            Dictionary<uint,Neuron> neuronDictionary = new Dictionary<uint,Neuron>(nodeCount);

            // Loop neuron genes.
            IActivationFunctionLibrary activationFnLib = networkDef.ActivationFnLibrary;

            for(int i=0; i<nodeCount; i++) 
            {   // Create a Neuron, add it to the neuron list and add an entry into neuronDictionary -
                // required for next loop.
                INetworkNode nodeDef = nodeDefList[i];

                // Note that we explicitly translate between the two NeuronType enums even though
                // they define the same types and could therefore be cast from one to the other.
                // We do this to keep genome and phenome classes completely separated and also to 
                // prevent bugs - e.g. if one of the enums is changed then TranslateNeuronType() will 
                // need to be modified to prevent exceptions at runtime. Otherwise a silent bug may 
                // be introduced.
                Neuron neuron = new Neuron(nodeDef.Id,
                                           nodeDef.NodeType,
                                           activationFnLib.GetFunction(nodeDef.ActivationFnId),
                                           nodeDef.AuxState);
                neuronList.Add(neuron);
                neuronDictionary.Add(nodeDef.Id, neuron);
            }

            // Build a list of connections.
            IConnectionList connectionDefList = networkDef.ConnectionList;
            int connectionCount = connectionDefList.Count;
            connectionList = new List<Connection>(connectionCount);

            // Loop connection genes.
            for(int i=0; i<connectionCount; i++)
            {
                INetworkConnection connDef = connectionDefList[i];
                connectionList.Add(
                        new Connection(neuronDictionary[connDef.SourceNodeId], 
                                       neuronDictionary[connDef.TargetNodeId],
                                       connDef.Weight));
            }
        }
 public PeerConnectionFactory(ILoggerFactory loggerFactory,
                              IEventBus eventBus,
                              IPeerContextFactory peerContextFactory,
                              INetworkDefinition chainDefinition,
                              INetworkMessageProcessorFactory networkMessageProcessorFactory,
                              INetworkMessageSerializerManager networkMessageSerializerManager)
 {
     this.loggerFactory                   = loggerFactory;
     this.eventBus                        = eventBus;
     this.peerContextFactory              = peerContextFactory;
     this.chainDefinition                 = chainDefinition;
     this.networkMessageProcessorFactory  = networkMessageProcessorFactory;
     this.networkMessageSerializerManager = networkMessageSerializerManager;
     this.logger = loggerFactory.CreateLogger <PeerConnectionFactory>();
 }
예제 #15
0
        /// <summary>
        /// Calculate node depths in an acyclic network.
        /// </summary>
        public NetworkDepthInfo CalculateNodeDepths(INetworkDefinition networkDef)
        {
            // Clear any existing state (allow reuse of this class).
            _nodeDepthById.Clear();

            // Get and store connectivity data for the network.
            _networkConnectivityData = networkDef.GetConnectivityData();

            // Loop over all input (and bias) nodes; Perform a depth first traversal of each in turn.
            // Set of nodes visited in the current traversal (reset before each individual depth first traversal).
            HashSet <uint> visitedNodeSet    = new HashSet <uint>();
            int            inputAndBiasCount = networkDef.InputNodeCount + 1;

            for (int i = 0; i < inputAndBiasCount; i++)
            {
                visitedNodeSet.Clear();
                TraverseNode(_networkConnectivityData.GetNodeDataByIndex(i), visitedNodeSet, 0);
            }

            // Extract node depths from _nodeDepthById into an array of depths (node depth by node index).
            // Note. Any node not in the dictionary is in an isolated sub-network and will be assigned to
            // layer 0 by default.
            INodeList nodeList  = networkDef.NodeList;
            int       nodeCount = nodeList.Count;

            int[] nodeDepthArr = new int[nodeCount];
            int   maxDepth     = 0;

            // Loop over nodes and set the node depth. Skip over input and bias nodes, they are defined as
            // being in layer zero.
            for (int i = inputAndBiasCount; i < nodeCount; i++)
            {
                // Lookup the node's depth. If not found depth remains set to zero.
                int depth;
                if (_nodeDepthById.TryGetValue(nodeList[i].Id, out depth))
                {
                    nodeDepthArr[i] = depth;
                    // Also determine maximum depth, that is, total depth of the network.
                    if (depth > maxDepth)
                    {
                        maxDepth = depth;
                    }
                }
            }

            // Return depth analysis info.
            return(new NetworkDepthInfo(maxDepth + 1, nodeDepthArr));
        }
예제 #16
0
        /// <summary>
        /// Decodes a CPPN NeatGenome to a concrete network instance via a HyperNEAT substrate.
        /// </summary>
        public IBlackBox Decode(NeatGenome genome)
        {
            // Decode the CPPN.
            IBlackBox cppn = _decodeCppnMethod(genome);

            // Generate a network definition from the CPPN and Substrate.
            INetworkDefinition substrateNetworkDef = _substrate.CreateNetworkDefinition(cppn, _lengthCppnInput);

            // Check for null network. This can happen if, e.g. querying the substrate did not result in any connections.
            if (null == substrateNetworkDef)
            {
                return(null);
            }

            // Create a network from the substrate network definition, and return it.
            return(_createSubstrateNetworkMethod(substrateNetworkDef));
        }
        /// <summary>
        /// Calculate node depths in an acyclic network.
        /// </summary>
        public NetworkDepthInfo CalculateNodeDepths(INetworkDefinition networkDef)
        {
            // Clear any existing state (allow reuse of this class).
            _nodeDepthById.Clear();

            // Get and store connectivity data for the network.
            _networkConnectivityData = networkDef.GetConnectivityData();

            // Loop over all input (and bias) nodes; Perform a depth first traversal of each in turn.
            // Set of nodes visited in the current traversal (reset before each individual depth first traversal).
            HashSet<uint> visitedNodeSet = new HashSet<uint>();
            int inputAndBiasCount = networkDef.InputNodeCount + 1;
            for(int i=0; i<inputAndBiasCount; i++)
            {
                visitedNodeSet.Clear();
                TraverseNode(_networkConnectivityData.GetNodeDataByIndex(i), visitedNodeSet, 0);
            }

            // Extract node depths from _nodeDepthById into an array of depths (node depth by node index).
            // Note. Any node not in the dictionary is in an isolated sub-network and will be assigned to 
            // layer 0 by default.
            INodeList nodeList = networkDef.NodeList;
            int nodeCount = nodeList.Count;
            int[] nodeDepthArr = new int[nodeCount];
            int maxDepth = 0;

            // Loop over nodes and set the node depth. Skip over input and bias nodes, they are defined as 
            // being in layer zero.
            for(int i=inputAndBiasCount; i<nodeCount; i++)
            {
                // Lookup the node's depth. If not found depth remains set to zero.
                int depth;
                if(_nodeDepthById.TryGetValue(nodeList[i].Id, out depth)) 
                {
                    nodeDepthArr[i] = depth;
                    // Also determine maximum depth, that is, total depth of the network.
                    if(depth > maxDepth) {
                        maxDepth = depth;
                    }
                }
            }

            // Return depth analysis info.
            return new NetworkDepthInfo(maxDepth+1, nodeDepthArr);
        }
예제 #18
0
        /// <summary>
        /// Writes a single INetworkDefinition to XML within a containing 'Root' element and the activation
        /// function library that the genome is associated with.
        /// </summary>
        /// <param name="xw">XmlWriter to write XML to.</param>
        /// <param name="networkDef">Network definition to write as XML.</param>
        /// <param name="nodeFnIds">Indicates if node activation function IDs should be emitted. They are required
        /// for HyperNEAT genomes but not for NEAT.</param>
        public static void WriteComplete(XmlWriter xw, INetworkDefinition networkDef, bool nodeFnIds)
        {
            // <Root>
            xw.WriteStartElement(__ElemRoot);

            // Write activation function library.
            Write(xw, networkDef.ActivationFnLibrary);

            // <Networks>
            xw.WriteStartElement(__ElemNetworks);

            // Write single network.
            Write(xw, networkDef, nodeFnIds);

            // </Networks>
            xw.WriteEndElement();

            // </Root>
            xw.WriteEndElement();
        }
예제 #19
0
        private static void InternalDecode(INetworkDefinition networkDef,
                                           int timestepsPerActivation,
                                           out FastConnection[] fastConnectionArray,
                                           out IActivationFunction[] activationFnArray,
                                           out double[][] neuronAuxArgsArray)
        {
            // Create an array of FastConnection(s) that represent the connectivity of the network.
            fastConnectionArray = CreateFastConnectionArray(networkDef);

            // TODO: Test/optimize heuristic - this is just back of envelope maths.
            // A rough heuristic to decide if we should sort fastConnectionArray by source neuron index.
            // The principle here is that each activation loop will be about 2x faster (unconfirmed) if we sort 
            // fastConnectionArray, but sorting takes about n*log2(n) operations. Therefore the decision to sort
            // depends on length of fastConnectionArray and _timestepsPerActivation.
            // Another factor here is that small networks will fit into CPU caches and therefore will not appear
            // to speed up - however the unsorted data will 'scramble' CPU caches more than they otherwise would 
            // have and thus may slow down other threads (so we just keep it simple).
            double len = fastConnectionArray.Length;
            double timesteps = timestepsPerActivation;
            if((len > 2) && (((len * Math.Log(len,2)) + ((timesteps * len)/2.0)) < (timesteps * len)))
            {   // Sort fastConnectionArray by source neuron index.
                Array.Sort(fastConnectionArray, delegate(FastConnection x, FastConnection y)
                {   // Use simple/fast diff method.
                    return x._srcNeuronIdx - y._srcNeuronIdx;
                });
            }

            // Construct an array of neuron activation functions. Skip bias and input neurons as
            // these don't have an activation function (because they aren't activated).
            INodeList nodeList = networkDef.NodeList;
            int nodeCount = nodeList.Count;
            IActivationFunctionLibrary activationFnLibrary = networkDef.ActivationFnLibrary;
            activationFnArray = new IActivationFunction[nodeCount];
            neuronAuxArgsArray = new double[nodeCount][];

            for(int i=0; i<nodeCount; i++) {
                activationFnArray[i] = activationFnLibrary.GetFunction(nodeList[i].ActivationFnId);
                neuronAuxArgsArray[i] = nodeList[i].AuxState;
            }
        }
        /// <summary>
        /// Creates a CyclicNetwork from an INetworkDefinition.
        /// </summary>
        public static CyclicNetwork CreateCyclicNetwork(INetworkDefinition networkDef,
                                                           NetworkActivationScheme activationScheme)
        {
            List<Neuron> neuronList;
            List<Connection> connectionList;
            InternalDecode(networkDef, out neuronList, out connectionList);

            // Construct neural net.
            if(activationScheme.RelaxingActivation)
            {
                return new RelaxingCyclicNetwork(neuronList,
                                                 connectionList,
                                                 networkDef.InputNodeCount,
                                                 networkDef.OutputNodeCount,
                                                 activationScheme.MaxTimesteps,
                                                 activationScheme.SignalDeltaThreshold);
            }

            return new CyclicNetwork(neuronList,
                                     connectionList,
                                     networkDef.InputNodeCount,
                                     networkDef.OutputNodeCount,
                                     activationScheme.TimestepsPerActivation);
        }
예제 #21
0
        public static void Write(XmlWriter xw, INetworkDefinition networkDef, bool nodeFnIds)
        {
            xw.WriteStartElement(__ElemNetwork);

            xw.WriteStartElement(__ElemNodes);
            foreach (var node in networkDef.NodeList)
            {
                xw.WriteStartElement(__ElemNode);
                xw.WriteAttributeString(__AttrType, NetworkXmlIO.GetNodeTypeString(node.NodeType));
                xw.WriteAttributeString(__AttrId, node.Id.ToString(NumberFormatInfo.InvariantInfo));
                if (nodeFnIds)
                {       // Write activation fn ID.
                    xw.WriteAttributeString(__AttrActivationFunctionId, node.ActivationFnId.ToString(NumberFormatInfo.InvariantInfo));

                    // Write aux state as comma separated list of real values.
                    XmlIoUtils.WriteAttributeString(xw, __AttrAuxState, node.AuxState);
                }
                xw.WriteEndElement();
            }
            xw.WriteEndElement();

            // Emit connections.
            xw.WriteStartElement(__ElemConnections);
            foreach (INetworkConnection connection in networkDef.ConnectionList)
            {
                xw.WriteStartElement(__ElemConnection);
                xw.WriteAttributeString(__AttrSourceId, connection.SourceNodeId.ToString(NumberFormatInfo.InvariantInfo));
                xw.WriteAttributeString(__AttrTargetId, connection.TargetNodeId.ToString(NumberFormatInfo.InvariantInfo));
                xw.WriteAttributeString(__AttrWeight, connection.Weight.ToString("R", NumberFormatInfo.InvariantInfo));
                xw.WriteEndElement();
            }
            xw.WriteEndElement();

            // </Network>
            xw.WriteEndElement();
        }
예제 #22
0
        /// <summary>
        /// Writes a single INetworkDefinition to XML within a containing 'Root' element and the activation
        /// function library that the genome is associated with.
        /// </summary>
        /// <param name="xw">XmlWriter to write XML to.</param>
        /// <param name="networkDef">Network definition to write as XML.</param>
        /// <param name="nodeFnIds">Indicates if node activation function IDs should be emitted. They are required
        /// for HyperNEAT genomes but not for NEAT.</param>
        public static void WriteComplete(XmlWriter xw, INetworkDefinition networkDef, bool nodeFnIds)
        {
            // <Root>
            xw.WriteStartElement(__ElemRoot);

            // Write activation function library.
            Write(xw, networkDef.ActivationFnLibrary);

            // <Networks>
            xw.WriteStartElement(__ElemNetworks);

            // Write single network.
            Write(xw, networkDef, nodeFnIds);

            // </Networks>
            xw.WriteEndElement();

            // </Root>
            xw.WriteEndElement();
        }
        /// <summary>
        /// Create an IOGraph that represents the structure described by the provided INetworkDefinition.
        /// </summary>
        public IOGraph CreateGraph(INetworkDefinition networkDef)
        {
            // Perform depth analysis of network.
            NetworkDepthInfo depthInfo;

            if (networkDef.IsAcyclic)
            {
                AcyclicNetworkDepthAnalysis depthAnalysis = new AcyclicNetworkDepthAnalysis();
                depthInfo = depthAnalysis.CalculateNodeDepths(networkDef);
            }
            else
            {
                CyclicNetworkDepthAnalysis depthAnalysis = new CyclicNetworkDepthAnalysis();
                depthInfo = depthAnalysis.CalculateNodeDepths(networkDef);
            }

            // Create an IOGraph, allocating storage for the node lists.
            INodeList nodeList    = networkDef.NodeList;
            int       nodeCount   = nodeList.Count;
            int       inputCount  = networkDef.InputNodeCount + 1; // + to count bias as an input layer node.
            int       outputCount = networkDef.OutputNodeCount;
            int       hiddenCount = nodeCount - (inputCount + outputCount);
            IOGraph   ioGraph     = new IOGraph(inputCount, outputCount, hiddenCount, 0f, depthInfo._networkDepth);

            // We also build a dictionary of nodes keyed by innovation ID. This is used later
            // to assign connections to nodes.
            Dictionary <uint, GraphNode> nodeDict = new Dictionary <uint, GraphNode>(nodeCount);

            // Loop input nodes.
            int idx = 0;

            for (int i = 0; i < inputCount; i++, idx++)
            {   // Create node, assign it a tag and add it to the node dictionary and the
                // input node list of the IOGraph.
                uint      innovationId = nodeList[idx].Id;
                GraphNode node         = new GraphNode(innovationId.ToString());
                node.AuxData = CreateGraphNodeAuxData(nodeList[idx]);
                node.Depth   = depthInfo._nodeDepthArr[idx];
                nodeDict.Add(innovationId, node);
                ioGraph.InputNodeList.Add(node);
            }

            // Loop output nodes.
            for (int i = 0; i < outputCount; i++, idx++)
            {   // Create node, assign it a tag and add it to the node dictionary and the
                // output node list of the IOGraph.
                uint      innovationId = nodeList[idx].Id;
                GraphNode node         = new GraphNode(innovationId.ToString());
                node.AuxData = CreateGraphNodeAuxData(nodeList[idx]);
                node.Depth   = depthInfo._nodeDepthArr[idx];
                nodeDict.Add(innovationId, node);
                ioGraph.OutputNodeList.Add(node);
            }

            // Loop hidden nodes.
            for (; idx < nodeCount; idx++)
            {   // Create node, assign it a tag and add it to the node dictionary and the
                // hidden node list of the IOGraph.
                uint      innovationId = nodeList[idx].Id;
                GraphNode node         = new GraphNode(innovationId.ToString());
                node.AuxData = CreateGraphNodeAuxData(nodeList[idx]);
                node.Depth   = depthInfo._nodeDepthArr[idx];
                nodeDict.Add(innovationId, node);
                ioGraph.HiddenNodeList.Add(node);
            }

            // Loop connections. Build GraphConnection objects and connect them to their source
            // and target nodes.
            double          maxAbsWeight   = 0.1; // Start at a non-zero value to prevent possibility of a divide by zero occuring.
            IConnectionList connectionList = networkDef.ConnectionList;
            int             connCount      = connectionList.Count;

            for (int i = 0; i < connCount; i++)
            {
                // Create connection object and assign its source and target nodes.
                INetworkConnection connection = connectionList[i];
                GraphNode          sourceNode = nodeDict[connection.SourceNodeId];
                GraphNode          targetNode = nodeDict[connection.TargetNodeId];
                GraphConnection    conn       = new GraphConnection(sourceNode, targetNode, (float)connection.Weight);

                // Add the connection to the connection lists on the source and target nodes.
                sourceNode.OutConnectionList.Add(conn);
                targetNode.InConnectionList.Add(conn);

                // Track weight range oevr all connections.
                double absWeight = Math.Abs(connection.Weight);
                if (absWeight > maxAbsWeight)
                {
                    maxAbsWeight = absWeight;
                }
            }

            ioGraph.ConnectionWeightRange = (float)maxAbsWeight;
            return(ioGraph);
        }
예제 #24
0
 private void SaveNetworkDefinitionToFile(INetworkDefinition champ, string fileName)
 {
     NeatGenomeXmlIO.Save(champ, true).Save(fileName);
 }
예제 #25
0
 /// <summary>
 /// Returns true if there is at least one connectivity cycle within the provided INetworkDefinition.
 /// </summary>
 public static bool IsNetworkCyclic(INetworkDefinition networkDef)
 {
     return(new CyclicNetworkTest().IsNetworkCyclicInternal(networkDef));
 }
        /// <summary>
        /// Creates a AcyclicNetwork from an INetworkDefinition.
        /// </summary>
        public static FastAcyclicNetwork CreateFastAcyclicNetwork(INetworkDefinition networkDef)
        {
            Debug.Assert(!CyclicNetworkTest.IsNetworkCyclic(networkDef), "Attempt to decode a cyclic network into a FastAcyclicNetwork.");

            // Determine the depth of each node in the network.
            // Node depths are used to separate the nodes into depth based layers, these layers can then be
            // used to determine the order in which signals are propagated through the network.
            AcyclicNetworkDepthAnalysis depthAnalysis = new AcyclicNetworkDepthAnalysis();
            NetworkDepthInfo            netDepthInfo  = depthAnalysis.CalculateNodeDepths(networkDef);

            // Construct an array of NodeInfo, ordered by node depth.
            // Create/populate NodeInfo array.
            int[]     nodeDepthArr = netDepthInfo._nodeDepthArr;
            INodeList nodeList     = networkDef.NodeList;
            int       nodeCount    = nodeList.Count;

            NodeInfo[] nodeInfoByDepth = new NodeInfo[nodeCount];
            for (int i = 0; i < nodeCount; i++)
            {
                nodeInfoByDepth[i]._nodeId        = nodeList[i].Id;
                nodeInfoByDepth[i]._definitionIdx = i;
                nodeInfoByDepth[i]._nodeDepth     = nodeDepthArr[i];
            }

            // Sort NodeInfo array.
            // We use an IComparer here because an anonymous method is not accepted on the method overload that accepts
            // a sort range, which we use to avoid sorting the input and bias nodes. Sort() performs an unstable sort therefore
            // we must restrict the range of the sort to ensure the input and bias node indexes are unchanged. Restricting the
            // sort to the required range is also more efficient (less items to sort).
            int inputAndBiasCount = networkDef.InputNodeCount + 1;

            Array.Sort(nodeInfoByDepth, inputAndBiasCount, nodeCount - inputAndBiasCount, NodeDepthComparer.__NodeDepthComparer);

            // Array of live node indexes indexed by their index in the original network definition. This allows us to
            // locate the position of input and output nodes in their new positions in the live network data structures.
            int[] newIdxByDefinitionIdx = new int[nodeCount];

            // Dictionary of live node indexes keyed by node ID. This allows us to convert the network definition connection
            // endpoints from node IDs to indexes into the live/runtime network data structures.
            Dictionary <uint, int> newIdxById = new Dictionary <uint, int>(nodeCount);

            // Populate both the lookup array and dictionary.
            for (int i = 0; i < nodeCount; i++)
            {
                NodeInfo nodeInfo = nodeInfoByDepth[i];
                newIdxByDefinitionIdx[nodeInfo._definitionIdx] = i;
                newIdxById.Add(nodeInfo._nodeId, i);
            }

            // Make a copy of the sub-range of newIdxByDefinitionIdx that represents the output nodes.
            int outputCount = networkDef.OutputNodeCount;

            int[] outputNeuronIdxArr = new int[outputCount];
            // Note. 'inputAndBiasCount' holds the index of the first output node.
            Array.Copy(newIdxByDefinitionIdx, inputAndBiasCount, outputNeuronIdxArr, 0, outputCount);

            // Construct arrays with additional 'per node' data/refs (activation functions, activation fn auxiliary data).
            IActivationFunctionLibrary activationFnLibrary = networkDef.ActivationFnLibrary;

            IActivationFunction[] nodeActivationFnArr = new IActivationFunction[nodeCount];
            double[][]            nodeAuxArgsArray    = new double[nodeCount][];
            for (int i = 0; i < nodeCount; i++)
            {
                int definitionIdx = nodeInfoByDepth[i]._definitionIdx;
                nodeActivationFnArr[i] = activationFnLibrary.GetFunction(nodeList[definitionIdx].ActivationFnId);
                nodeAuxArgsArray[i]    = nodeList[definitionIdx].AuxState;
            }


            //=== Create array of FastConnection(s).

            // Loop the connections and lookup the node IDs for each connection's end points using newIdxById.
            IConnectionList connectionList  = networkDef.ConnectionList;
            int             connectionCount = connectionList.Count;

            FastConnection[] fastConnectionArray = new FastConnection[connectionCount];

            for (int i = 0; i < connectionCount; i++)
            {
                INetworkConnection conn = connectionList[i];
                fastConnectionArray[i]._srcNeuronIdx = newIdxById[conn.SourceNodeId];
                fastConnectionArray[i]._tgtNeuronIdx = newIdxById[conn.TargetNodeId];
                fastConnectionArray[i]._weight       = conn.Weight;
            }

            // Sort fastConnectionArray by source node index. This allows us to activate the connections in the
            // order they are present within the network (by depth). We also secondary sort by target index to
            // improve CPU cache coherency of the data (in order accesses that are as close to each other as possible).
            Array.Sort(fastConnectionArray, delegate(FastConnection x, FastConnection y)
            {
                if (x._srcNeuronIdx < y._srcNeuronIdx)
                {
                    return(-1);
                }
                if (x._srcNeuronIdx > y._srcNeuronIdx)
                {
                    return(1);
                }
                // Secondary sort on target index.
                if (x._tgtNeuronIdx < y._tgtNeuronIdx)
                {
                    return(-1);
                }
                if (x._tgtNeuronIdx > y._tgtNeuronIdx)
                {
                    return(1);
                }
                // Connections are equal (this should not actually happen).
                return(0);
            });

            // Create an array of LayerInfo(s). Each LayerInfo contains the index + 1 of both the last node and last
            // connection in that layer.
            // The array is in order of depth, from layer zero (bias and inputs nodes) to the last layer
            // (usually output nodes, but not necessarily if there is a dead end pathway with a high number of hops).
            // Note. There is guaranteed to be at least one connection with a source at a given depth level, this is
            // because for there to be a layer N there must necessarily be a connection from a node in layer N-1
            // to a node in layer N.
            int netDepth = netDepthInfo._networkDepth;

            LayerInfo[] layerInfoArr = new LayerInfo[netDepth];

            // Scanning over nodes can start at inputAndBiasCount instead of zero,
            // because we know that all nodes prior to that index are at depth zero.
            int nodeIdx = inputAndBiasCount;
            int connIdx = 0;

            for (int currDepth = 0; currDepth < netDepth; currDepth++)
            {
                // Scan for last node at the current depth.
                for (; nodeIdx < nodeCount && nodeInfoByDepth[nodeIdx]._nodeDepth == currDepth; nodeIdx++)
                {
                    ;
                }

                // Scan for last connection at the current depth.
                for (; connIdx < fastConnectionArray.Length && nodeInfoByDepth[fastConnectionArray[connIdx]._srcNeuronIdx]._nodeDepth == currDepth; connIdx++)
                {
                    ;
                }

                // Store node and connection end indexes for the layer.
                layerInfoArr[currDepth]._endNodeIdx       = nodeIdx;
                layerInfoArr[currDepth]._endConnectionIdx = connIdx;
            }

            return(new FastAcyclicNetwork(nodeActivationFnArr, nodeAuxArgsArray, fastConnectionArray, layerInfoArr, outputNeuronIdxArr,
                                          nodeCount, networkDef.InputNodeCount, networkDef.OutputNodeCount));
        }
예제 #27
0
        /// <summary>
        /// Create an IOGraph that represents the structure described by the provided INetworkDefinition.
        /// </summary>
        public IOGraph CreateGraph(INetworkDefinition networkDef)
        {
            // Perform depth analysis of network.
            NetworkDepthInfo depthInfo;
            if(networkDef.IsAcyclic)
            {
                AcyclicNetworkDepthAnalysis depthAnalysis = new AcyclicNetworkDepthAnalysis();
                depthInfo = depthAnalysis.CalculateNodeDepths(networkDef);
            }
            else
            {   
                CyclicNetworkDepthAnalysis depthAnalysis = new CyclicNetworkDepthAnalysis();
                depthInfo = depthAnalysis.CalculateNodeDepths(networkDef);
            }

            // Create an IOGraph, allocating storage for the node lists.
            INodeList nodeList = networkDef.NodeList;
            int nodeCount = nodeList.Count;
            int inputCount = networkDef.InputNodeCount + 1; // + to count bias as an input layer node.
            int outputCount = networkDef.OutputNodeCount;
            int hiddenCount = nodeCount - (inputCount + outputCount);
            IOGraph ioGraph = new IOGraph(inputCount, outputCount, hiddenCount, 0f, depthInfo._networkDepth);
            
            // We also build a dictionary of nodes keyed by innovation ID. This is used later
            // to assign connections to nodes.
            Dictionary<uint, GraphNode> nodeDict = new Dictionary<uint,GraphNode>(nodeCount);

            // Loop input nodes.
            int idx = 0;
            for(int i=0; i<inputCount; i++, idx++)
            {   // Create node, assign it a tag and add it to the node dictionary and the
                // input node list of the IOGraph.
                uint innovationId = nodeList[idx].Id;
                GraphNode node = new GraphNode(innovationId.ToString());
                node.AuxData = CreateGraphNodeAuxData(nodeList[idx]);
                node.Depth = depthInfo._nodeDepthArr[idx];
                nodeDict.Add(innovationId, node);
                ioGraph.InputNodeList.Add(node);
            }

            // Loop output nodes.
            for(int i=0; i<outputCount; i++, idx++)
            {   // Create node, assign it a tag and add it to the node dictionary and the
                // output node list of the IOGraph.
                uint innovationId = nodeList[idx].Id;
                GraphNode node = new GraphNode(innovationId.ToString());
                node.AuxData = CreateGraphNodeAuxData(nodeList[idx]);
                node.Depth = depthInfo._nodeDepthArr[idx];
                nodeDict.Add(innovationId, node);
                ioGraph.OutputNodeList.Add(node);
            }

            // Loop hidden nodes.
            for(; idx<nodeCount; idx++)
            {   // Create node, assign it a tag and add it to the node dictionary and the
                // hidden node list of the IOGraph.
                uint innovationId = nodeList[idx].Id;
                GraphNode node = new GraphNode(innovationId.ToString());
                node.AuxData = CreateGraphNodeAuxData(nodeList[idx]);
                node.Depth = depthInfo._nodeDepthArr[idx];
                nodeDict.Add(innovationId, node);
                ioGraph.HiddenNodeList.Add(node);
            }

            // Loop connections. Build GraphConnection objects and connect them to their source
            // and target nodes.
            double maxAbsWeight = 0.1; // Start at a non-zero value to prevent possibility of a divide by zero occurring.
            IConnectionList connectionList = networkDef.ConnectionList;
            int connCount = connectionList.Count;            
            for(int i=0; i<connCount; i++)
            {
                // Create connection object and assign its source and target nodes.
                INetworkConnection connection = connectionList[i];
                GraphNode sourceNode = nodeDict[connection.SourceNodeId];
                GraphNode targetNode = nodeDict[connection.TargetNodeId];
                GraphConnection conn = new GraphConnection(sourceNode, targetNode, (float)connection.Weight); 
    
                // Add the connection to the connection lists on the source and target nodes.
                sourceNode.OutConnectionList.Add(conn);
                targetNode.InConnectionList.Add(conn);

                // Track weight range over all connections.
                double absWeight = Math.Abs(connection.Weight);
                if(absWeight > maxAbsWeight) {
                    maxAbsWeight = absWeight;
                }
            }

            ioGraph.ConnectionWeightRange = (float)maxAbsWeight;
            return ioGraph;
        }
예제 #28
0
 private FastAcyclicNetwork CreateSubstrateNetwork_AcyclicNetwork(INetworkDefinition networkDef)
 {
     return(FastAcyclicNetworkFactory.CreateFastAcyclicNetwork(networkDef));
 }
예제 #29
0
        /// <summary>
        /// Create an array of FastConnection(s) representing the connectivity of the provided INetworkDefinition.
        /// </summary>
        private static FastConnection[] CreateFastConnectionArray(INetworkDefinition networkDef)
        {
            // We vary the decode logic depending on the size of the genome. The most CPU intensive aspect of
            // decoding is the conversion of the neuron IDs at connection endpoints into neuron indexes. For small
            // genomes we simply use the BinarySearch() method on NeuronGeneList for each lookup; Each lookup is
            // an operation with O(log n) time complexity. Thus for C connections and N neurons the number of operations
            // to perform all lookups is approximately = 2*C*Log(N)
            //
            // For larger genomes we invest time in building a Dictionary that maps neuron IDs to their indexes, this on the
            // basis that the time invested will be more than recovered in time saved performing lookups; The time complexity
            // of a dictionary lookup is near constant O(1). Thus number of operations is approximately = O(2*C*1) + the time
            // required to build the dictionary which is approximately O(N).
            //
            // Therefore the choice of lookup type is based on which of these two expressions gives the lowest value. 
            //
            //      Binary search.      LookupOps = 2 * C * Log2(N) * x
            //      Dictionary Search.  LookupOps = (N * y) + (2 * C * z)
            //
            // Where x, y and z are constants that adjust for the relative speeds of the lookup and dictionary building operations.
            // Note that the actual time required to perform these separate algorithms is actually a far more complex problem, and 
            // for modern CPUs exact times cannot be calculated because of large memory caches and superscalar architecture that
            // makes execution times in a real environment effectively non-deterministic. Thus these calculations are a rough 
            // guide/heuristic that estimate which algorithm will perform best. The constants can be found experimentally but will
            // tend to vary depending on factors such as CPU and memory architecture, .Net framework version and what other tasks the
            // CPU is currently doing which may affect our utilisation of memory caches.
            // TODO: Experimentally determine reasonably good values for constants x,y and z in some common real world runtime platform.
            IConnectionList connectionList = networkDef.ConnectionList;
            INodeList nodeList = networkDef.NodeList;
            int connectionCount = connectionList.Count;
            int nodeCount = nodeList.Count;

            FastConnection[] fastConnectionArray = new FastConnection[connectionCount];

            if((2.0 * connectionCount * Math.Log(nodeCount, 2.0)) < ((2.0 * connectionCount) + nodeCount))
            {
                // Binary search requires items to be sorted.
                Debug.Assert(nodeList.IsSorted());

                // Loop the connections and lookup the neuron IDs for each connection's end points using a binary search
                // on nGeneList. This is probably the quickest approach for small numbers of lookups.
                for(int i=0; i<connectionCount; i++)
                {   
                    INetworkConnection conn = connectionList[i];
                    fastConnectionArray[i]._srcNeuronIdx = nodeList.BinarySearch(conn.SourceNodeId);
                    fastConnectionArray[i]._tgtNeuronIdx = nodeList.BinarySearch(conn.TargetNodeId);
                    fastConnectionArray[i]._weight = conn.Weight;

                    // Check that the correct neuron indexes were found.
                    Debug.Assert( 
                           nodeList[fastConnectionArray[i]._srcNeuronIdx].Id == conn.SourceNodeId
                        && nodeList[fastConnectionArray[i]._tgtNeuronIdx].Id == conn.TargetNodeId);
                }
            }
            else
            {
                // Build dictionary of neuron indexes keyed on neuron innovation ID.
                Dictionary<uint,int> neuronIndexDictionary = new Dictionary<uint,int>(nodeCount);
                for(int i=0; i<nodeCount; i++) {
                    // ENHANCEMENT: Check if neuron innovation ID requires further manipulation to make a good hash code.
                    neuronIndexDictionary.Add(nodeList[i].Id, i);
                }

                // Loop the connections and lookup the neuron IDs for each connection's end points using neuronIndexDictionary.
                // This is probably the quickest approach for large numbers of lookups.
                for(int i=0; i<connectionCount; i++)
                {   
                    INetworkConnection conn = connectionList[i];
                    fastConnectionArray[i]._srcNeuronIdx = neuronIndexDictionary[conn.SourceNodeId];
                    fastConnectionArray[i]._tgtNeuronIdx = neuronIndexDictionary[conn.TargetNodeId];
                    fastConnectionArray[i]._weight = conn.Weight;

                    // Check that the correct neuron indexes were found.
                    Debug.Assert( 
                           nodeList[fastConnectionArray[i]._srcNeuronIdx].Id == conn.SourceNodeId
                        && nodeList[fastConnectionArray[i]._tgtNeuronIdx].Id == conn.TargetNodeId);
                }
            }

            return fastConnectionArray;
        }
예제 #30
0
 private FastCyclicNetwork CreateSubstrateNetwork_FastCyclicNetwork(INetworkDefinition networkDef)
 {
     return(FastCyclicNetworkFactory.CreateFastCyclicNetwork(networkDef, _activationSchemeSubstrate));
 }
예제 #31
0
        /// <summary>
        /// Writes an INetworkDefinition to XML.
        /// </summary>
        /// <param name="xw">XmlWriter to write XML to.</param>
        /// <param name="networkDef">Network definition to write as XML.</param>
        /// <param name="nodeFnIds">Indicates if node activation function IDs should be emitted. They are required
        /// for HyperNEAT genomes but not for NEAT.</param>
        public static void Write(XmlWriter xw, INetworkDefinition networkDef, bool nodeFnIds)
        {
            xw.WriteStartElement(__ElemNetwork);

            // Emit nodes.
            xw.WriteStartElement(__ElemNodes);
            foreach(INetworkNode node in networkDef.NodeList)
            {
                xw.WriteStartElement(__ElemNode);
                xw.WriteAttributeString(__AttrType, GetNodeTypeString(node.NodeType));
                xw.WriteAttributeString(__AttrId, node.Id.ToString(NumberFormatInfo.InvariantInfo));
                if(nodeFnIds) {
                    xw.WriteAttributeString(__AttrActivationFunctionId, node.ActivationFnId.ToString(NumberFormatInfo.InvariantInfo));
                }
                xw.WriteEndElement();
            }
            xw.WriteEndElement();

            // Emit connections.
            xw.WriteStartElement(__ElemConnections);
            foreach(INetworkConnection con in networkDef.ConnectionList)
            {
                xw.WriteStartElement(__ElemConnection);
                xw.WriteAttributeString(__AttrSourceId, con.SourceNodeId.ToString(NumberFormatInfo.InvariantInfo));
                xw.WriteAttributeString(__AttrTargetId, con.TargetNodeId.ToString(NumberFormatInfo.InvariantInfo));
                xw.WriteAttributeString(__AttrWeight, con.Weight.ToString("R", NumberFormatInfo.InvariantInfo));
                xw.WriteEndElement();
            }
            xw.WriteEndElement();

            // </Network>
            xw.WriteEndElement();
        }
예제 #32
0
 /// <summary>
 /// Returns true if there is at least one connectivity cycle within the provided INetworkDefinition.
 /// </summary>
 public static bool IsNetworkCyclic(INetworkDefinition networkDef)
 {
     return new CyclicNetworkTest().IsNetworkCyclicInternal(networkDef);
 }
예제 #33
0
 private CyclicNetwork CreateSubstrateNetwork_CyclicNetwork(INetworkDefinition networkDef)
 {
     return(CyclicNetworkFactory.CreateCyclicNetwork(networkDef, _activationSchemeCppn));
 }
예제 #34
0
        /// <summary>
        /// Create an array of FastConnection(s) representing the connectivity of the provided INetworkDefinition.
        /// </summary>
        private static FastConnection[] CreateFastConnectionArray(INetworkDefinition networkDef)
        {
            // We vary the decode logic depending on the size of the genome. The most CPU intensive aspect of
            // decoding is the conversion of the neuron IDs at connection endpoints into neuron indexes. For small
            // genomes we simply use the BinarySearch() method on NeuronGeneList for each lookup; Each lookup is
            // an operation with O(log n) time complexity. Thus for C connections and N neurons the number of operations
            // to perform all lookups is approximately = 2*C*Log(N)
            //
            // For larger genomes we invest time in building a Dictionary that maps neuron IDs to their indexes, this on the
            // basis that the time invested will be more than recovered in time saved performing lookups; The time complexity
            // of a dictionary lookup is near constant O(1). Thus number of operations is approximately = O(2*C*1) + the time
            // required to build the dictionary which is approximately O(N).
            //
            // Therefore the choice of lookup type is based on which of these two expressions gives the lowest value.
            //
            //      Binary search.      LookupOps = 2 * C * Log2(N) * x
            //      Dictionary Search.  LookupOps = (N * y) + (2 * C * z)
            //
            // Where x, y and z are constants that adjust for the relative speeds of the lookup and dictionary building operations.
            // Note that the actual time required to perform these separate algorithms is actually a far more complex problem, and
            // for modern CPUs exact times cannot be calculated because of large memory caches and superscalar architecture that
            // makes execution times in a real environment effectively non-deterministic. Thus these calculations are a rough
            // guide/heuristic that estimate which algorithm will perform best. The constants can be found experimentally but will
            // tend to vary depending on factors such as CPU and memory architecture, .Net framework version and what other tasks the
            // CPU is currently doing which may affect our utilisation of memory caches.
            // TODO: Experimentally determine reasonably good values for constants x,y and z in some common real world runtime platform.
            IConnectionList connectionList  = networkDef.ConnectionList;
            INodeList       nodeList        = networkDef.NodeList;
            int             connectionCount = connectionList.Count;
            int             nodeCount       = nodeList.Count;

            FastConnection[] fastConnectionArray = new FastConnection[connectionCount];

            if ((2.0 * connectionCount * Math.Log(nodeCount, 2.0)) < ((2.0 * connectionCount) + nodeCount))
            {
                // Binary search requires items to be sorted.
                Debug.Assert(nodeList.IsSorted());

                // Loop the connections and lookup the neuron IDs for each connection's end points using a binary search
                // on nGeneList. This is probably the quickest approach for small numbers of lookups.
                for (int i = 0; i < connectionCount; i++)
                {
                    INetworkConnection conn = connectionList[i];
                    fastConnectionArray[i]._srcNeuronIdx = nodeList.BinarySearch(conn.SourceNodeId);
                    fastConnectionArray[i]._tgtNeuronIdx = nodeList.BinarySearch(conn.TargetNodeId);
                    fastConnectionArray[i]._weight       = conn.Weight;

                    // Check that the correct neuron indexes were found.
                    Debug.Assert(
                        nodeList[fastConnectionArray[i]._srcNeuronIdx].Id == conn.SourceNodeId &&
                        nodeList[fastConnectionArray[i]._tgtNeuronIdx].Id == conn.TargetNodeId);
                }
            }
            else
            {
                // Build dictionary of neuron indexes keyed on neuron innovation ID.
                Dictionary <uint, int> neuronIndexDictionary = new Dictionary <uint, int>(nodeCount);
                for (int i = 0; i < nodeCount; i++)
                {
                    // ENHANCEMENT: Check if neuron innovation ID requires further manipulation to make a good hash code.
                    neuronIndexDictionary.Add(nodeList[i].Id, i);
                }

                // Loop the connections and lookup the neuron IDs for each connection's end points using neuronIndexDictionary.
                // This is probably the quickest approach for large numbers of lookups.
                for (int i = 0; i < connectionCount; i++)
                {
                    INetworkConnection conn = connectionList[i];
                    fastConnectionArray[i]._srcNeuronIdx = neuronIndexDictionary[conn.SourceNodeId];
                    fastConnectionArray[i]._tgtNeuronIdx = neuronIndexDictionary[conn.TargetNodeId];
                    fastConnectionArray[i]._weight       = conn.Weight;

                    // Check that the correct neuron indexes were found.
                    Debug.Assert(
                        nodeList[fastConnectionArray[i]._srcNeuronIdx].Id == conn.SourceNodeId &&
                        nodeList[fastConnectionArray[i]._tgtNeuronIdx].Id == conn.TargetNodeId);
                }
            }

            return(fastConnectionArray);
        }