Exemplo n.º 1
0
        /// <summary>
        /// Reads a NeatGenome from XML.
        /// </summary>
        /// <param name="xr">The XmlReader to read from.</param>
        /// <param name="nodeFnIds">Indicates if node activation function IDs
        /// should be read. They are required for HyperNEAT genomes but not for NEAT</param>
        public static NeatGenome ReadGenome(XmlReader xr, bool nodeFnIds)
        {
            // Find <Network>.
            XmlIoUtils.MoveToElement(xr, false, __ElemNetwork);
            int initialDepth = xr.Depth;

            // Read genome ID attribute if present. Otherwise default to zero;
            // it's the caller's responsibility to check IDs are unique and
            // in-line with the genome factory's ID generators.
            string genomeIdStr = xr.GetAttribute(__AttrId);
            uint   genomeId;

            uint.TryParse(genomeIdStr, out genomeId);

            // Read birthGeneration attribute if present. Otherwise default to zero.
            string birthGenStr = xr.GetAttribute(__AttrBirthGeneration);
            uint   birthGen;

            uint.TryParse(birthGenStr, out birthGen);

            // Read fitness attribute if present. Otherwise default to zero.
            string fitnessStr = xr.GetAttribute(__AttrFitness);
            double fitness;

            double.TryParse(fitnessStr, out fitness);

            // Find <Nodes>.
            XmlIoUtils.MoveToElement(xr, true, __ElemNodes);

            // Create a reader over the <Nodes> sub-tree.
            int inputNodeCount  = 0;
            int outputNodeCount = 0;
            int regulatoryCount = 0;
            int localInCount    = 0;
            int localOutCount   = 0;
            // Used to count local input and output neurons (which are not
            // found in the base module = 0)
            int            activeModule = 1;
            NeuronGeneList nGeneList    = new NeuronGeneList();

            using (XmlReader xrSubtree = xr.ReadSubtree())
            {
                // Re-scan for the root <Nodes> element.
                XmlIoUtils.MoveToElement(xrSubtree, false);

                // Move to first node elem.
                XmlIoUtils.MoveToElement(xrSubtree, true, __ElemNode);

                // Read node elements.
                do
                {
                    NodeType neuronType =
                        NetworkXmlIO.ReadAttributeAsNodeType(xrSubtree, __AttrType);
                    uint id         = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrId);
                    int  functionId = GetFunctionId(neuronType);
                    int  module     = XmlIoUtils.ReadAttributeAsInt(xrSubtree, __AttrModule);
                    int  pandemonium;
                    // If we have a regulatory neuron, we read its pandemonium label
                    if (neuronType == NodeType.Regulatory)
                    {
                        pandemonium = XmlIoUtils.ReadAttributeAsInt(xrSubtree, __AttrPandemonium);
                    }
                    // Otherwise it is simply -1
                    else
                    {
                        pandemonium = -1;
                    }
                    double[] auxState = null;
                    if (nodeFnIds)
                    {   // Read activation fn ID.
                        functionId = XmlIoUtils.ReadAttributeAsInt(xrSubtree,
                                                                   __AttrActivationFunctionId);

                        // Read aux state as comma seperated list of real values.
                        auxState = XmlIoUtils.ReadAttributeAsDoubleArray(xrSubtree,
                                                                         __AttrAuxState);
                    }

                    NeuronGene nGene = new NeuronGene(id, neuronType, functionId,
                                                      module, pandemonium, auxState);
                    nGeneList.Add(nGene);

                    // Track the number of input and output nodes.
                    switch (neuronType)
                    {
                    case NodeType.Input:
                        ++inputNodeCount;
                        break;

                    case NodeType.Output:
                        ++outputNodeCount;
                        break;

                    case NodeType.Regulatory:
                        ++regulatoryCount;
                        break;

                    case NodeType.Local_Input:
                        if (module == activeModule)
                        {
                            ++localInCount;
                        }
                        else
                        {
                            // Found a new module, discard previous count
                            activeModule  = module;
                            localInCount  = 1;
                            localOutCount = 0;
                        }
                        break;

                    case NodeType.Local_Output:
                        // Here we do not care about the correct module,
                        // because that has been considered in the local input
                        // count (and local input always comes first).
                        ++localOutCount;
                        break;
                    }
                }while(xrSubtree.ReadToNextSibling(__ElemNode));
            }

            // Find <Connections>.
            XmlIoUtils.MoveToElement(xr, false, __ElemConnections);

            // Create a reader over the <Connections> sub-tree.
            ConnectionGeneList cGeneList = new ConnectionGeneList();

            using (XmlReader xrSubtree = xr.ReadSubtree())
            {
                // Re-scan for the root <Connections> element.
                XmlIoUtils.MoveToElement(xrSubtree, false);

                // Move to first connection elem.
                string localName = XmlIoUtils.MoveToElement(xrSubtree, true);
                if (localName == __ElemConnection)
                {   // We have at least one connection.
                    // Read connection elements.
                    do
                    {
                        uint           id      = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrId);
                        uint           srcId   = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrSourceId);
                        uint           tgtId   = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrTargetId);
                        double         weight  = XmlIoUtils.ReadAttributeAsDouble(xrSubtree, __AttrWeight);
                        int            module  = XmlIoUtils.ReadAttributeAsInt(xrSubtree, __AttrModule);
                        bool           protect = XmlIoUtils.ReadAttributeAsBool(xrSubtree, __AttrProtected);
                        ConnectionGene cGene   = new ConnectionGene(id, srcId, tgtId,
                                                                    weight, module,
                                                                    protect);
                        cGeneList.Add(cGene);
                    }while(xrSubtree.ReadToNextSibling(__ElemConnection));
                }
            }

            // Move the reader beyond the closing tags </Connections> and </Network>.
            do
            {
                if (xr.Depth <= initialDepth)
                {
                    break;
                }
            }while(xr.Read());

            // Construct and return loaded NeatGenome. We construct it first
            // so we can access its properties before leaving.
            bool rebuildConnectivity = true;
            // Integrity will fail if we attempt to create the genome before
            // updating some of the statistics (counts for each type of neurons,
            // etc). It can be done after that step!
            bool       shouldAssertIntegrity = false;
            NeatGenome genome = new NeatGenome(null, genomeId, birthGen, nGeneList,
                                               cGeneList, rebuildConnectivity,
                                               shouldAssertIntegrity);

            if (genomeFactory != null)
            {
                // Note genomeFactory is not fully initialized yet, but it is needed to create
                // an EvaluationInfo structure.
                genome.GenomeFactory = genomeFactory;
                genome.EvaluationInfo.SetFitness(fitness);
            }

            // We update count variables. While it is true most are static
            // variables, loading genomes is done only once, so we can afford
            // to count them for each genome.
            genome.Input      = inputNodeCount;
            genome.Output     = outputNodeCount;
            genome.Regulatory = regulatoryCount;
            genome.LocalIn    = localInCount;
            genome.LocalOut   = localOutCount;
            // We use base for neurons InHiddenModules
            genome.NeuronGeneList.LocateLastBase();
            genome.InHiddenModulesFromLoad();
            genome.ActiveConnectionsFromLoad();

            // Before this was done only once after creating all genomes. However,
            // we need these values if we want to perform an integrity check.
            // The performance overhead is negligible (specially in a one-time method)
            // and reliability is increased this way.
            genome.NeuronGeneList.LocateLastBase();
            genome.NeuronGeneList.LocateFirstIndex();
            genome.ConnectionGeneList.LocateFirstId();

            Debug.Assert(genome.PerformIntegrityCheck());
            return(genome);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Reads a NeatGenome from XML.
        /// </summary>
        /// <param name="xr">The XmlReader to read from.</param>
        /// <param name="nodeFnIds">Indicates if node activation function IDs should be read. They are required
        /// for HyperNEAT genomes but not for NEAT</param>
        public static NeatGenome ReadGenome(XmlReader xr, bool nodeFnIds)
        {
            // Find <Network>.
            XmlIoUtils.MoveToElement(xr, false, __ElemNetwork);
            int initialDepth = xr.Depth;

            // Read genome ID attribute if present. Otherwise default to zero; it's the caller's responsibility to
            // check IDs are unique and in-line with the genome factory's ID generators.
            string genomeIdStr = xr.GetAttribute(__AttrId);
            uint   genomeId;

            uint.TryParse(genomeIdStr, out genomeId);

            // Read birthGeneration attribute if present. Otherwise default to zero.
            string birthGenStr = xr.GetAttribute(__AttrBirthGeneration);
            uint   birthGen;

            uint.TryParse(birthGenStr, out birthGen);

            // Find <Nodes>.
            XmlIoUtils.MoveToElement(xr, true, __ElemNodes);

            // Create a reader over the <Nodes> sub-tree.
            int            inputNodeCount  = 0;
            int            outputNodeCount = 0;
            NeuronGeneList nGeneList       = new NeuronGeneList();

            using (XmlReader xrSubtree = xr.ReadSubtree())
            {
                // Re-scan for the root <Nodes> element.
                XmlIoUtils.MoveToElement(xrSubtree, false);

                // Move to first node elem.
                XmlIoUtils.MoveToElement(xrSubtree, true, __ElemNode);

                // Read node elements.
                do
                {
                    NodeType neuronType = NetworkXmlIO.ReadAttributeAsNodeType(xrSubtree, __AttrType);
                    uint     id         = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrId);
                    int      functionId = 0;
                    double[] auxState   = null;
                    if (nodeFnIds)
                    {   // Read activation fn ID.
                        functionId = XmlIoUtils.ReadAttributeAsInt(xrSubtree, __AttrActivationFunctionId);

                        // Read aux state as comma separated list of real values.
                        auxState = XmlIoUtils.ReadAttributeAsDoubleArray(xrSubtree, __AttrAuxState);
                    }

                    NeuronGene nGene = new NeuronGene(id, neuronType, functionId, auxState);
                    nGeneList.Add(nGene);

                    // Track the number of input and output nodes.
                    switch (neuronType)
                    {
                    case NodeType.Input:
                        inputNodeCount++;
                        break;

                    case NodeType.Output:
                        outputNodeCount++;
                        break;
                    }
                }while(xrSubtree.ReadToNextSibling(__ElemNode));
            }

            // Find <Connections>.
            XmlIoUtils.MoveToElement(xr, false, __ElemConnections);

            // Create a reader over the <Connections> sub-tree.
            ConnectionGeneList cGeneList = new ConnectionGeneList();

            using (XmlReader xrSubtree = xr.ReadSubtree())
            {
                // Re-scan for the root <Connections> element.
                XmlIoUtils.MoveToElement(xrSubtree, false);

                // Move to first connection elem.
                string localName = XmlIoUtils.MoveToElement(xrSubtree, true);
                if (localName == __ElemConnection)
                {   // We have at least one connection.
                    // Read connection elements.
                    do
                    {
                        uint           id     = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrId);
                        uint           srcId  = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrSourceId);
                        uint           tgtId  = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrTargetId);
                        double         weight = XmlIoUtils.ReadAttributeAsDouble(xrSubtree, __AttrWeight);
                        ConnectionGene cGene  = new ConnectionGene(id, srcId, tgtId, weight);
                        cGeneList.Add(cGene);
                    }while(xrSubtree.ReadToNextSibling(__ElemConnection));
                }
            }

            // Move the reader beyond the closing tags </Connections> and </Network>.
            do
            {
                if (xr.Depth <= initialDepth)
                {
                    break;
                }
            }while(xr.Read());

            // Construct and return loaded NeatGenome.
            return(new NeatGenome(null, genomeId, birthGen, nGeneList, cGeneList, inputNodeCount, outputNodeCount, true));
        }