Esempio n. 1
0
 /// <summary>
 /// Constructs with the provided IActivationFunctionLibrary, NeatGenomeParameters and ID generators.
 /// </summary>
 public CppnGenomeFactory(int inputNeuronCount, int outputNeuronCount,
                          IActivationFunctionLibrary activationFnLibrary,
                          NeatGenomeParameters neatGenomeParams,
                          UInt32IdGenerator genomeIdGenerator, UInt32IdGenerator innovationIdGenerator)
     : base(inputNeuronCount, outputNeuronCount, activationFnLibrary, neatGenomeParams, genomeIdGenerator, innovationIdGenerator)
 {
 }
 public AutoencoderGenomeFactory(int inputNeuronCount, int outputNeuronCount, int hiddenNeuronCount,
     IActivationFunctionLibrary activationFnLibrary, NeatGenomeParameters neatGenomeParams,
     UInt32IdGenerator genomeIdGenerator, UInt32IdGenerator innovationIdGenerator)
     : base(inputNeuronCount, outputNeuronCount, activationFnLibrary, neatGenomeParams, genomeIdGenerator,
         innovationIdGenerator)
 {
     _hiddenNeuronCount = hiddenNeuronCount;
 }
Esempio n. 3
0
 /// <summary>
 /// Constructs with the provided input/output node count, activation function library, 
 /// node and connection lists.
 /// </summary>
 public NetworkDefinition(int inputNodeCount, int outputNodeCount,
                          IActivationFunctionLibrary activationFnLib,
                          NodeList nodeList, ConnectionList connectionList)
 {
     _inputNodeCount = inputNodeCount;
     _outputNodeCount = outputNodeCount;
     _activationFnLib = activationFnLib;
     _nodeList = nodeList;
     _connectionList = connectionList;
     _isAcyclic = !CyclicNetworkTest.IsNetworkCyclic(this);
 }
 /// <summary>
 /// Construct with the provided CPPN activation function library to draw CPPNs with (genome nodes contain an index into this library).
 /// </summary>
 /// <param name="actFnLib"></param>
 public CppnGenomeView(IActivationFunctionLibrary actFnLib)
 {
     InitializeComponent();
     graphControl1.ViewportPainter = _viewportPainter = new IOGraphViewportPainter(new CppnGraphPainter(actFnLib));
 }
Esempio n. 5
0
        /// <summary>
        /// Reads a network definition from XML. 
        /// An activation function library is required to decode the function ID at each node, typically the
        /// library is stored alongside the network definition XML and will have already been read elsewhere and
        /// passed in here.
        /// </summary>
        /// <param name="xr">The XmlReader to read from.</param>
        /// <param name="activationFnLib">The activation function library used to decode node activation function IDs.</param>
        /// <param name="nodeFnIds">Indicates if node activation function IDs should be read. They are required
        /// for HyperNEAT genomes but not NEAT</param>
        public static NetworkDefinition ReadNetworkDefinition(XmlReader xr, IActivationFunctionLibrary activationFnLib, bool nodeFnIds)
        {
            // Find <Network>.
            XmlIoUtils.MoveToElement(xr, false, __ElemNetwork);
            int initialDepth = xr.Depth;

            // Find <Nodes>.
            XmlIoUtils.MoveToElement(xr, true, __ElemNodes);
            
            // Create a reader over the <Nodes> sub-tree.
            int inputNodeCount = 0;
            int outputNodeCount = 0;
            NodeList nodeList = new NodeList();
            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 nodeType = ReadAttributeAsNodeType(xrSubtree, __AttrType);
                    uint id = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrId);
                    int fnId = 0;
                    double[] auxState = null;
                    if(nodeFnIds) 
                    {   // Read activation fn ID.
                        fnId = XmlIoUtils.ReadAttributeAsInt(xrSubtree, __AttrActivationFunctionId);

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

                    // TODO: Read node aux state data.
                    NetworkNode node = new NetworkNode(id, nodeType, fnId, auxState);
                    nodeList.Add(node);

                    // Track the number of input and output nodes.
                    switch(nodeType)
                    {
                        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.
            ConnectionList connList = new ConnectionList();
            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 srcId = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrSourceId);
                        uint tgtId = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrTargetId);
                        double weight = XmlIoUtils.ReadAttributeAsDouble(xrSubtree, __AttrWeight);
                        NetworkConnection conn = new NetworkConnection(srcId, tgtId, weight);
                        connList.Add(conn);
                    } 
                    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 network definition.
            return new NetworkDefinition(inputNodeCount, outputNodeCount, activationFnLib, nodeList, connList);
        }
Esempio n. 6
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();
 }
Esempio n. 7
0
 /// <summary>
 /// Reads a NetworkDefinition from XML.
 /// </summary>
 /// <param name="xmlNode">The XmlNode to read from. This can be an XmlDocument or XmlElement.</param>
 /// <param name="activationFnLib">The activation function library used to decode node activation function IDs.</param>
 /// <param name="nodeFnIds">Indicates if node activation function IDs should be read. They are required
 /// for HyperNEAT genomes but not for NEAT.  If false then all node activation function IDs default to 0.</param>
 public static NetworkDefinition ReadGenome(XmlNode xmlNode, IActivationFunctionLibrary activationFnLib, bool nodeFnIds)
 {
     using(XmlNodeReader xr = new XmlNodeReader(xmlNode))
     {
         return ReadNetworkDefinition(xr, activationFnLib, nodeFnIds);
     }
 }
Esempio n. 8
0
 /// <summary>
 /// Construct with the provided activation function library.
 /// This must be the same library used by the genomes/graphs being painted. 
 /// A legend of the activation functions is shown and the nodes are color coded to indicate the
 /// activation function at each node.
 /// </summary>
 public CppnGraphPainter(IActivationFunctionLibrary activationFnLibrary)
 {
     _activationFnLibrary = activationFnLibrary;
 }
Esempio n. 9
0
        /// <summary>
        /// Reads a network definition from XML.
        /// An activation function library is required to decode the function ID at each node, typically the
        /// library is stored alongside the network definition XML and will have already been read elsewhere and
        /// passed in here.
        /// </summary>
        /// <param name="xr">The XmlReader to read from.</param>
        /// <param name="activationFnLib">The activation function library used to decode node activation function IDs.</param>
        /// <param name="nodeFnIds">Indicates if node activation function IDs should be read. They are required
        /// for HyperNEAT genomes but not NEAT</param>
        public static NetworkDefinition ReadNetworkDefinition(XmlReader xr, IActivationFunctionLibrary activationFnLib, bool nodeFnIds)
        {
            // Find <Network>.
            XmlIoUtils.MoveToElement(xr, false, __ElemNetwork);
            int initialDepth = xr.Depth;

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

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

            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 nodeType = ReadAttributeAsNodeType(xrSubtree, __AttrType);
                    uint     id       = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrId);
                    int      fnId     = 0;
                    double[] auxState = null;
                    if (nodeFnIds)
                    {   // Read activation fn ID.
                        fnId = XmlIoUtils.ReadAttributeAsInt(xrSubtree, __AttrActivationFunctionId);

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

                    // TODO: Read node aux state data.
                    NetworkNode node = new NetworkNode(id, nodeType, fnId, auxState);
                    nodeList.Add(node);

                    // Track the number of input and output nodes.
                    switch (nodeType)
                    {
                    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.
            ConnectionList connList = new ConnectionList();

            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              srcId  = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrSourceId);
                        uint              tgtId  = XmlIoUtils.ReadAttributeAsUInt(xrSubtree, __AttrTargetId);
                        double            weight = XmlIoUtils.ReadAttributeAsDouble(xrSubtree, __AttrWeight);
                        NetworkConnection conn   = new NetworkConnection(srcId, tgtId, weight);
                        connList.Add(conn);
                    }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 network definition.
            return(new NetworkDefinition(inputNodeCount, outputNodeCount, activationFnLib, nodeList, connList));
        }
Esempio n. 10
0
        /// <summary>
        /// Constructs with the provided substrate nodesets and mappings that describe how the nodesets are to be connected up.
        /// </summary>
        /// <param name="nodeSetList">Substrate nodes, represented as distinct sets of nodes. By convention the first and second
        /// sets in the list represent the input and output noes respectively. All other sets represent hidden nodes.</param>
        /// <param name="activationFnLibrary">The activation function library allocated to the networks that are 'grown' from the substrate.</param>
        /// <param name="activationFnId">The ID of an activation function function in activationFnLibrary. This is the activation function 
        /// ID assigned to all nodes in networks that are 'grown' from the substrate. </param>
        /// <param name="weightThreshold">The weight threshold below which substrate connections are not created in grown networks.</param>
        /// <param name="maxWeight">Defines the weight range of grown connections (+-maxWeight).</param>/// 
        /// <param name="nodeSetMappingList">A list of mappings between node sets that defines what connections to create between substrate nodes.</param>
        public Substrate(List<SubstrateNodeSet> nodeSetList, 
                         IActivationFunctionLibrary activationFnLibrary, int activationFnId,
                         double weightThreshold, double maxWeight,
                         List<NodeSetMapping> nodeSetMappingList)
        {
            VaildateSubstrateNodes(nodeSetList);

            _nodeSetList = nodeSetList;
            _inputNodeCount =  _nodeSetList[0].NodeList.Count;
            _outputNodeCount =  _nodeSetList[1].NodeList.Count;
            _dimensionality = _nodeSetList[0].NodeList[0]._position.GetUpperBound(0) + 1;

            _activationFnLibrary = activationFnLibrary;
            _activationFnId = activationFnId;

            _weightThreshold = weightThreshold;
            _maxWeight = maxWeight;
            _weightRescalingCoeff = _maxWeight / (1.0 - _weightThreshold);

            _nodeSetMappingList = nodeSetMappingList;

            // Get an estimate for the number of connections defined by mappings.
            int nonBiasConnectionCountHint = 0;
            foreach(NodeSetMapping mapping in nodeSetMappingList) {
                nonBiasConnectionCountHint += mapping.GetConnectionCountHint(nodeSetList);
            }

            if(nonBiasConnectionCountHint <= ConnectionCountCacheThreshold)
            {
                // Pre-generate the substrate connections and store them in a list.
                _connectionList = _connectionCountHint == 0 ? new List<SubstrateConnection>() : new List<SubstrateConnection>(nonBiasConnectionCountHint);
                foreach(NodeSetMapping mapping in nodeSetMappingList)
                {
                    IEnumerable<SubstrateConnection> connectionSequence = mapping.GenerateConnections(nodeSetList);
                    foreach(SubstrateConnection conn in connectionSequence) {
                        _connectionList.Add(conn);
                    }
                }
                _connectionList.TrimExcess();
            }

            // Set total connection count hint value (includes additional connections to a bias node).
            _connectionCountHint = nonBiasConnectionCountHint + CalcBiasConnectionCountHint(nodeSetList);

            // Pre-create the network definition node list. This is re-used each time a network is created from the substrate.
            _netNodeList = CreateNetworkNodeList();
        }
Esempio n. 11
0
        /// <summary>
        /// Construct a substrate with the provided node sets and a predetermined set of connections. 
        /// </summary>
        /// <param name="nodeSetList">Substrate nodes, represented as distinct sets of nodes. By convention the first and second
        /// sets in the list represent the input and output noes respectively. All other sets represent hidden nodes.</param>
        /// <param name="activationFnLibrary">The activation function library allocated to the networks that are 'grown' from the substrate.</param>
        /// <param name="activationFnId">The ID of an activation function function in activationFnLibrary. This is the activation function 
        /// ID assigned to all nodes in networks that are 'grown' from the substrate. </param>
        /// <param name="weightThreshold">The weight threshold below which substrate connections are not created in grown networks.</param>
        /// <param name="maxWeight">Defines the weight range of grown connections (+-maxWeight).</param>
        /// <param name="connectionList">A predetermined list of substrate connections.</param>
        public Substrate(List<SubstrateNodeSet> nodeSetList, 
                         IActivationFunctionLibrary activationFnLibrary, int activationFnId,
                         double weightThreshold, double maxWeight,
                         List<SubstrateConnection> connectionList)
        {
            VaildateSubstrateNodes(nodeSetList);

            _nodeSetList = nodeSetList;
            _inputNodeCount =  _nodeSetList[0].NodeList.Count;
            _outputNodeCount =  _nodeSetList[1].NodeList.Count;
            _dimensionality = _nodeSetList[0].NodeList[0]._position.GetUpperBound(0) + 1;

            _activationFnLibrary = activationFnLibrary;
            _activationFnId = activationFnId;

            _weightThreshold = weightThreshold;
            _maxWeight = maxWeight;
            _weightRescalingCoeff = _maxWeight / (1.0 - _weightThreshold);

            // Set total connection count hint value (includes additional connections to a bias node).
            _connectionList = connectionList;
            _connectionCountHint = connectionList.Count + CalcBiasConnectionCountHint(nodeSetList);

            // Pre-create the network definition node list. This is re-used each time a network is created from the substrate.
            _netNodeList = CreateNetworkNodeList();
        }
 public AutoencoderGenomeFactory(int inputNeuronCount, int outputNeuronCount, int hiddenNeuronCount,
     IActivationFunctionLibrary activationFnLibrary, NeatGenomeParameters neatGenomeParams)
     : base(inputNeuronCount, outputNeuronCount, activationFnLibrary, neatGenomeParams)
 {
     _hiddenNeuronCount = hiddenNeuronCount;
 }
 public AutoencoderGenomeFactory(int inputNeuronCount, int outputNeuronCount, int hiddenNeuronCount,
     IActivationFunctionLibrary activationFnLibrary)
     : base(inputNeuronCount, outputNeuronCount, activationFnLibrary)
 {
     _hiddenNeuronCount = hiddenNeuronCount;
 }
Esempio n. 14
0
 /// <summary>
 /// Constructs with default NeatGenomeParameters, ID generators initialized to zero and the
 /// provided IActivationFunctionLibrary.
 /// </summary>
 public RbfGenomeFactory(int inputNeuronCount, int outputNeuronCount,
                         IActivationFunctionLibrary activationFnLibrary)
     : base(inputNeuronCount, outputNeuronCount, activationFnLibrary)
 {
 }
        /// <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 genomeFactory)
        {
            // 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.InputNeuronCount != inputCount || genome.OutputNeuronCount != outputCount)
                {
                    throw new SharpNeatException(string.Format("Genome with wrong number of inputs and/or outputs, expected [{0}][{1}] got [{2}][{3}]",
                                                               inputCount, outputCount, genome.InputNeuronCount, genome.OutputNeuronCount));
                }

                // 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(maxGenomeId + 1);
            genomeFactory.InnovationIdGenerator.Reset(maxInnovationId + 1);

            // Retrospecitively assign the genome factory to the genomes. This is how we overcome the genome/genomeFactory
            // chicken and egg problem.
            foreach (NeatGenome genome in genomeList)
            {
                genome.GenomeFactory = genomeFactory;
            }

            return(genomeList);
        }
Esempio n. 16
0
 /// <summary>
 /// Constructs with default NeatGenomeParameters, ID generators initialized to zero and the
 /// provided IActivationFunctionLibrary.
 /// </summary>
 public CppnGenomeFactory(int inputNeuronCount, int outputNeuronCount,
                          IActivationFunctionLibrary activationFnLibrary)
     : base(inputNeuronCount, outputNeuronCount, activationFnLibrary)
 {
 }
Esempio n. 17
0
 /// <summary>
 /// Constructs with the provided IActivationFunctionLibrary and NeatGenomeParameters.
 /// </summary>
 public CppnGenomeFactory(int inputNeuronCount, int outputNeuronCount,
                          IActivationFunctionLibrary activationFnLibrary,
                          NeatGenomeParameters neatGenomeParams)
     : base(inputNeuronCount,outputNeuronCount, activationFnLibrary, neatGenomeParams)
 {
 }
        /// <summary>
        /// Initialize the experiment with some optional XML configutation data.
        /// </summary>
        public void Initialize(string name, XmlElement xmlConfig)
        {
            _name = name;
            _populationSize = XmlUtils.GetValueAsInt(xmlConfig, "PopulationSize");
            _specieCount = XmlUtils.GetValueAsInt(xmlConfig, "SpecieCount");
            _activationScheme = ExperimentUtils.CreateActivationScheme(xmlConfig, "Activation");
            _complexityThreshold = XmlUtils.TryGetValueAsInt(xmlConfig, "ComplexityThreshold");
            _description = XmlUtils.TryGetValueAsString(xmlConfig, "Description");
            _parallelOptions = ExperimentUtils.ReadParallelOptions(xmlConfig);

            _guesses = XmlUtils.GetValueAsInt(xmlConfig, "Guesses");
            Hashed = XmlUtils.TryGetValueAsBool(xmlConfig, "Hashed").HasValue ? XmlUtils.GetValueAsBool(xmlConfig, "Hashed") : false;
            ValidationGuesses = XmlUtils.GetValueAsInt(xmlConfig, "ValidationGuesses");

            // Load the passwords from file
            string pwdfile = XmlUtils.TryGetValueAsString(xmlConfig, "ValidationPasswordFile");
            if (pwdfile != null)
            {
                Console.Write("Loading passwords from [{0}]...", pwdfile);
                if (_passwords == null || _passwords.Count == 0)
                {
                    int? pwLength = XmlUtils.TryGetValueAsInt(xmlConfig, "PasswordLength");
                    if (pwLength.HasValue)
                        Console.Write("Filtering to {0}-character passwords...", pwLength.Value);
                    _passwords = PasswordUtil.LoadPasswords(pwdfile, pwLength);
                }
                else
                    Console.WriteLine("WARNING: Not loading passwords for experiment (already set)");
            }
            else
                Console.WriteLine("WARNING: Not loading passwords for experiment (not provided in config file)");
            _eaParams = new NeatEvolutionAlgorithmParameters();
            _eaParams.SpecieCount = _specieCount;
            _neatGenomeParams = new NeatGenomeParameters();
            _neatGenomeParams.FeedforwardOnly = false;
            _neatGenomeParams.AddNodeMutationProbability = 0.03;
            _neatGenomeParams.AddConnectionMutationProbability = 0.05;

            // TODO: Load states from XML config file
            // Generates all the valid states in the MC using all viable ASCII characters
            var stateList = new List<string>();
            for (uint i = 32; i < 127; i++)
                stateList.Add(((char)i).ToString());
            stateList.Add(null);
            _states = stateList.ToArray();
            _activationFnLibrary = MarkovActivationFunctionLibrary.CreateLibraryMc(_states);
        }
Esempio n. 19
0
        public static NeatGenome ReadNeatGenome(string serializedGenomePath, int inputCount, int outputCount, IActivationFunctionLibrary actFuncLib)
        {
            // Create a new genome factory
            NeatGenomeFactory genomeFactory = new NeatGenomeFactory(inputCount, outputCount, actFuncLib);

            // Create a reader for the serialized genome
            XmlReader reader = XmlReader.Create(serializedGenomePath);

            // Create XML document and give it the reader reference
            XmlDocument document = new XmlDocument();
            document.Load(reader);

            // Traverse down to the network definition
            XmlNodeList nodeList = document.GetElementsByTagName("Root");

            // Read in the genome
            NeatGenome genome = NeatGenomeXmlIO.LoadCompleteGenomeList(nodeList[0], true, genomeFactory)[0];

            return genome;
        }
        /// <summary>
        /// Creates a AcyclicNetwork from an INetworkDefinition.
        /// </summary>
        public static FastAcyclicNetwork CreateFastAcyclicNetwork(INetworkDefinition networkDef, bool boundedOutput)
        {
            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, boundedOutput));
        }