Beispiel #1
0
        private void PaintLegend(PaintState state)
        {
            const int LineHeight = 16;
            const int Margin     = 10;

            IList <ActivationFunctionInfo> fnList = _activationFnLibrary.GetFunctionList();
            int count = fnList.Count;

            // Determine y position of first line.
            int yCurr = Math.Max(Margin, state._viewportArea.Height - ((count * LineHeight) + Margin));

            for (int i = 0; i < count; i++, yCurr += LineHeight)
            {
                ActivationFunctionInfo fnInfo = fnList[i];
                const int X = Margin;

                // Paint an example node as part of the legend item.
                Point     p = new Point(X, yCurr);
                Size      s = new Size(state._nodeDiameter, state._nodeDiameter);
                Rectangle r = new Rectangle(p, s);

                // Paint the node. Fill first and then border, this gives a clean border.
                Graphics g         = state._g;
                Brush    fillBrush = _brushNodeFillArr[fnInfo.Id % _brushNodeFillArr.Length];
                g.FillRectangle(fillBrush, r);
                g.DrawRectangle(__penBlack, r);

                // Write the activation function string ID.
                g.DrawString(fnList[i].ActivationFunction.FunctionId, __fontNodeTag, __brushBlack, X + 12, yCurr - 1);
            }
        }
        /// <summary>
        /// Writes an activation function library to XML. This links activation function names to the
        /// integer IDs used by network nodes, which allows us emit just the ID for each node thus
        /// resulting in XML that is more compact compared to emitting the activation function name for
        /// each node.
        /// </summary>
        public static void Write(XmlWriter xw, IActivationFunctionLibrary activationFnLib)
        {
            xw.WriteStartElement(__ElemActivationFunctions);
            IList <ActivationFunctionInfo> fnList = activationFnLib.GetFunctionList();

            foreach (ActivationFunctionInfo fnInfo in fnList)
            {
                xw.WriteStartElement(__ElemActivationFn);
                xw.WriteAttributeString(__AttrId, fnInfo.Id.ToString(NumberFormatInfo.InvariantInfo));
                xw.WriteAttributeString(__AttrName, fnInfo.ActivationFunction.FunctionId);
                xw.WriteAttributeString(__AttrProbability, fnInfo.SelectionProbability.ToString("R", NumberFormatInfo.InvariantInfo));
                xw.WriteEndElement();
            }
            xw.WriteEndElement();
        }
Beispiel #3
0
 /// <summary>
 /// Writes an activation function library to XML. This links activation function names to the 
 /// integer IDs used by network nodes, which allows us emit just the ID for each node thus 
 /// resulting in XML that is more compact compared to emitting the activation function name for
 /// each node.
 /// </summary>
 public static void Write(XmlWriter xw, IActivationFunctionLibrary activationFnLib)
 {
     xw.WriteStartElement(__ElemActivationFunctions);
     IList<ActivationFunctionInfo> fnList = activationFnLib.GetFunctionList();
     foreach(ActivationFunctionInfo fnInfo in fnList)
     {
         xw.WriteStartElement(__ElemActivationFn);
         xw.WriteAttributeString(__AttrId, fnInfo.Id.ToString(NumberFormatInfo.InvariantInfo));
         xw.WriteAttributeString(__AttrName, fnInfo.ActivationFunction.FunctionId);
         xw.WriteAttributeString(__AttrProbability, fnInfo.SelectionProbability.ToString("R", NumberFormatInfo.InvariantInfo));
         xw.WriteEndElement();
     }
     xw.WriteEndElement();
 }
Beispiel #4
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);
        }