/// <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);
     }
 }
        private static IBlackBox BrainFromFile(string brainFileName, int inputCount, int outputCount)
        {
            // TODO: Refactor
            var genomeDecoder = new NeatGenomeDecoder(NetworkActivationScheme.CreateCyclicFixedTimestepsScheme(1));
            var genomeFactory = new NeatGenomeFactory(inputCount, outputCount, new NeatGenomeParameters());

            NeatGenome genome;
            using (var xr = XmlReader.Create(brainFileName))
            {
                genome = NeatGenomeXmlIO.ReadCompleteGenomeList(xr, false, genomeFactory)[0];
            }

            return genomeDecoder.Decode(genome);
        }
        public void ConectionBufferTest()
        {
            NeatGenomeFactory genomeFactory = new NeatGenomeFactory(3, 1);

            for (uint i = 0; i < 200000; i++)
            {
                ConnectionEndpointsStruct endpointsStruct = new ConnectionEndpointsStruct(i, i+1);
                AddedNeuronGeneStruct addedNeuronGeneStruct = new AddedNeuronGeneStruct(genomeFactory.InnovationIdGenerator);

                genomeFactory.AddedConnectionBuffer.Enqueue(endpointsStruct, i);
                genomeFactory.AddedNeuronBuffer.Enqueue(i, addedNeuronGeneStruct);
            }

            //Assert.Fail();
        }
        /// <summary>
        ///     Creates the coevolution algorithm container using the given agent and maze population sizes.
        /// </summary>
        /// <param name="populationSize1">The agent population size.</param>
        /// <param name="populationSize2">The maze population size.</param>
        /// <returns>The instantiated coevolution algorithm container.</returns>
        public override ICoevolutionAlgorithmContainer<NeatGenome, MazeGenome> CreateCoevolutionAlgorithmContainer(
            int populationSize1, int populationSize2)
        {
            // Create a genome factory for the NEAT genomes
            IGenomeFactory<NeatGenome> neatGenomeFactory = new NeatGenomeFactory(AnnInputCount, AnnOutputCount,
                NeatGenomeParameters);

            // Create a genome factory for the maze genomes
            IGenomeFactory<MazeGenome> mazeGenomeFactory = new MazeGenomeFactory(MazeGenomeParameters, _mazeHeight,
                _mazeWidth);

            // Create an initial population of maze navigators
            List<NeatGenome> neatGenomeList = neatGenomeFactory.CreateGenomeList(populationSize1, 0);

            // Create an initial population of mazes
            // NOTE: the population is set to 1 here because we're just starting with a single, completely open maze space
            List<MazeGenome> mazeGenomeList = mazeGenomeFactory.CreateGenomeList(populationSize2, 0);

            // Create the evolution algorithm container
            return CreateCoevolutionAlgorithmContainer(neatGenomeFactory, mazeGenomeFactory, neatGenomeList,
                mazeGenomeList);
        }
Example #5
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;
        }
Example #6
0
        /// <summary>
        ///     The map evaluator constructor.
        /// </summary>
        /// <param name="experimentParameters">The experiment definition and control parameters.</param>
        /// <param name="agentInputNeuronCount">The number of input neurons in the agent neural controller.</param>
        /// <param name="agentOutputNeuronCount">The number of output neurons in the agent neural controller.</param>
        public MapEvaluator(ExperimentParameters experimentParameters, int agentInputNeuronCount,
            int agentOutputNeuronCount)
        {
            // Create the NEAT genome (agent) decoder - acyclic activation is always used
            _agentDecoder = new NeatGenomeDecoder(NetworkActivationScheme.CreateAcyclicScheme());

            // Create the maze decoder
            _mazeDecoder = new MazeDecoder(experimentParameters.MazeHeight, experimentParameters.MazeWidth,
                experimentParameters.MazeScaleMultiplier);

            // Initialize evaluation units
            EvaluationUnits = new List<MazeNavigatorEvaluationUnit>();

            // Create default maze factory (NEAT factory will be set later based on structure of first genome encountered)
            _mazeGenomeFactory = new MazeGenomeFactory();
            _neatGenomeFactory = new NeatGenomeFactory(agentInputNeuronCount, agentOutputNeuronCount);

            // Set experiment parameters
            _experimentParameters = experimentParameters;

            // Create new agent ID list and maze ID/structure map
            _agentGenomeIds = new List<int>();
            _mazeIdStructureMap = new Dictionary<int, MazeStructure>();
        }
        /// <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(Math.Max(genomeFactory.GenomeIdGenerator.Peek, maxGenomeId+1));
            genomeFactory.InnovationIdGenerator.Reset(Math.Max(genomeFactory.InnovationIdGenerator.Peek, 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;
        }
 /// <summary>
 ///     Reads a single genome from a population from the given XML file.  This is typically used in cases where a
 ///     population file is being read in, but it only contains one genome.
 /// </summary>
 /// <param name="xr"></param>
 /// Reference to the XmlReader.
 /// <param name="nodeFnIds">
 ///     Indicates if node activation function IDs should be read. They are required for HyperNEAT
 ///     genomes but not for NEAT.
 /// </param>
 /// <param name="genomeFactory">A NeatGenomeFactory object to construct genomes against.</param>
 /// <returns>Instantiated NEAT genome.</returns>
 public static NeatGenome ReadSingleGenomeFromRoot(XmlReader xr, bool nodeFnIds, NeatGenomeFactory genomeFactory)
 {
     return ReadCompleteGenomeList(xr, nodeFnIds, genomeFactory)[0];
 }
        public void VerifyBootstrappedStateTest()
        {
            const string parentDirectory =
                "F:/User Data/Jonathan/Documents/school/Jonathan/Graduate/PhD/Development/C# NEAT/SharpNoveltyNeat/SharpNeatConsole/bin/Debug/";
            const string agentGenomeFile = "ViableSeedGenomes.xml";
            const string baseBitmapFilename = "AgentTrajectory";
            const int mazeHeight = 20;
            const int mazeWidth = 20;
            const int scaleMultiplier = 16;
            const int maxTimesteps = 400;
            const int minSuccessDistance = 5;

            // Setup stuff for the navigators
            List<NeatGenome> agentGenomes;
            NeatGenomeDecoder agentGenomeDecoder = new NeatGenomeDecoder(NetworkActivationScheme.CreateAcyclicScheme());
            NeatGenomeFactory agentGenomeFactory = new NeatGenomeFactory(10, 2);

            // Create new minimal maze (no barriers)
            MazeStructure mazeStructure = new MazeDecoder(mazeHeight, mazeWidth, scaleMultiplier).Decode(
                new MazeGenomeFactory(null, null, null).CreateGenome(0));

            // Create behavior characterization factory
            IBehaviorCharacterizationFactory behaviorCharacterizationFactory =
                new TrajectoryBehaviorCharacterizationFactory(null);

            // Create evaluator
            MazeNavigatorMCSEvaluator mazeNavigatorEvaluator = new MazeNavigatorMCSEvaluator(maxTimesteps,
                minSuccessDistance, behaviorCharacterizationFactory, 1);

            // Set maze within evaluator
            mazeNavigatorEvaluator.UpdateEvaluatorPhenotypes(new List<MazeStructure> {mazeStructure});

            // Read in agents
            using (XmlReader xr = XmlReader.Create(parentDirectory + agentGenomeFile))
            {
                agentGenomes = NeatGenomeXmlIO.ReadCompleteGenomeList(xr, false, agentGenomeFactory);
            }

            // Decode agent genomes to phenotype and run simulation
            for (int i = 0; i < agentGenomes.Count; i++)
            {
                // Decode navigator genome
                IBlackBox agentPhenome = agentGenomeDecoder.Decode(agentGenomes[i]);

                // Run simulation
                BehaviorInfo behaviorInfo = mazeNavigatorEvaluator.Evaluate(agentPhenome, 0, false, null, null);

                // Print the navigator trajectory through the maze
                DomainTestUtils.PrintMazeAndTrajectory(mazeStructure, behaviorInfo.Behaviors,
                    string.Format("{0}_{1}.bmp", baseBitmapFilename, i));
            }
        }