Пример #1
0
 /// <summary>
 /// Loads a list of NeatGenome(s) from XML that has a containing 'Root'
 /// element. The root element also contains the activation function
 /// library that the network definitions are associated with.
 /// </summary>
 /// <param name="xmlNode">The XmlNode to read from. This can be an
 /// XmlDocument or XmlElement.</param>
 /// <param name="nodeFnIds">Indicates if node activation function IDs
 /// should be read. If false then all node activation function IDs
 /// default to 0.</param>
 /// <param name="genomeFactory">A NeatGenomeFactory object to construct
 /// genomes against.</param>
 public static List <NeatGenome> LoadCompleteGenomeList(XmlNode xmlNode,
                                                        bool nodeFnIds,
                                                        NeatGenomeFactory genomeFactory)
 {
     using (XmlNodeReader xr = new XmlNodeReader(xmlNode))
     {
         return(ReadCompleteGenomeList(xr, nodeFnIds, genomeFactory));
     }
 }
Пример #2
0
        /// <summary>
        /// Reads a list of NeatGenome(s) from XML that has a containing 'Root'
        /// element. The root element also contains the activation function
        /// library that the genomes are associated with.
        /// </summary>
        /// <param name="xr">The XmlReader to read from.</param>
        /// <param name="nodeFnIds">Indicates if node activation function IDs
        /// should be read. If false then all node activation function IDs
        /// default to 0.</param>
        /// <param name="genomeFactory">A NeatGenomeFactory object to construct
        /// genomes against.</param>
        public static List <NeatGenome> ReadCompleteGenomeList(XmlReader xr,
                                                               bool nodeFnIds,
                                                               NeatGenomeFactory givenGenomeFactory)
        {
            genomeFactory = givenGenomeFactory;

            // Find <Root>.
            XmlIoUtils.MoveToElement(xr, false, __ElemRoot);

            // Read IActivationFunctionLibrary. This library is not used, it is
            // compared against the one already present in the genome factory to
            // confirm that the loaded genomes are compatible with the genome factory.
            XmlIoUtils.MoveToElement(xr, true, __ElemActivationFunctions);
            IActivationFunctionLibrary activationFnLib =
                NetworkXmlIO.ReadActivationFunctionLibrary(xr);

            XmlIoUtils.MoveToElement(xr, false, __ElemNetworks);

            // Read genomes.
            List <NeatGenome> genomeList = new List <NeatGenome>();

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

                // Move to first Network elem.
                XmlIoUtils.MoveToElement(xrSubtree, true, __ElemNetwork);

                // Read Network elements.
                do
                {
                    NeatGenome genome = ReadGenome(xrSubtree, nodeFnIds);
                    genomeList.Add(genome);
                }while(xrSubtree.ReadToNextSibling(__ElemNetwork));
            }

            // Check for empty list.
            if (genomeList.Count == 0)
            {
                return(genomeList);
            }

            // Get the number of inputs and outputs expected by the genome factory.
            int inputCount  = genomeFactory.InputNeuronCount;
            int outputCount = genomeFactory.OutputNeuronCount;

            // Check all genomes have the same number of inputs & outputs.
            // Also track the highest genomeID and innovation ID values;
            // we need these to construct a new genome factory.
            uint maxGenomeId     = 0;
            uint maxInnovationId = 0;

            foreach (NeatGenome genome in genomeList)
            {
                // Check number of inputs/outputs.
                if (genome.Input != inputCount ||
                    genome.Output != outputCount)
                {
                    throw new SharpNeatException(string.Format(
                                                     "Genome with wrong number of inputs and/or outputs," +
                                                     " expected [{0}][{1}] got [{2}][{3}]", inputCount,
                                                     outputCount, genome.Input, genome.Output));
                }

                // Track max IDs.
                maxGenomeId = Math.Max(maxGenomeId, genome.Id);

                // Node and connection innovation IDs are in the same ID space.
                foreach (NeuronGene nGene in genome.NeuronGeneList)
                {
                    maxInnovationId = Math.Max(maxInnovationId, nGene.InnovationId);
                }

                // Register connection IDs.
                foreach (ConnectionGene cGene in genome.ConnectionGeneList)
                {
                    maxInnovationId = Math.Max(maxInnovationId, cGene.InnovationId);
                }
            }

            // Check that activation functions in XML match that in the genome factory.
            IList <ActivationFunctionInfo> loadedActivationFnList =
                activationFnLib.GetFunctionList();
            IList <ActivationFunctionInfo> factoryActivationFnList =
                genomeFactory.ActivationFnLibrary.GetFunctionList();

            if (loadedActivationFnList.Count != factoryActivationFnList.Count)
            {
                throw new SharpNeatException("The activation function library loaded" +
                                             "from XML does not match the genome" +
                                             "factory's activation function library.");
            }

            for (int i = 0; i < factoryActivationFnList.Count; i++)
            {
                if ((loadedActivationFnList[i].Id != factoryActivationFnList[i].Id) ||
                    (loadedActivationFnList[i].ActivationFunction.FunctionId !=
                     factoryActivationFnList[i].ActivationFunction.FunctionId))
                {
                    throw new SharpNeatException("The activation function library loaded" +
                                                 "from XML does not match the genome" +
                                                 "factory's activation function library.");
                }
            }

            // Initialise the genome factory's genome and innovation ID generators.
            genomeFactory.GenomeIdGenerator.Reset(Math.Max(genomeFactory.GenomeIdGenerator.Peek,
                                                           maxGenomeId + 1));
            genomeFactory.InnovationIdGenerator.Reset(Math.Max(genomeFactory.InnovationIdGenerator.Peek,
                                                               maxInnovationId + 1));
            // The active module in these loaded genomes corresponds to the last
            // module in the list:
            genomeFactory.CurrentModule = genomeList[0].FindActiveModule();
            return(genomeList);
        }