static void Main(string[] args)
        {
            // Initialise log4net (log to console).
            XmlConfigurator.Configure(new FileInfo("log4net.properties"));

            // Experiment classes encapsulate much of the nuts and bolts of setting up a NEAT search.
            XorExperiment experiment = new XorExperiment();

            // Load config XML.
            XmlDocument xmlConfig = new XmlDocument();
            xmlConfig.Load("xor_logging.config.xml");
            experiment.Initialize("XOR", xmlConfig.DocumentElement);

            // Create a genome factory with our neat genome parameters object and the appropriate number of input and output neuron genes.
            _genomeFactory = experiment.CreateGenomeFactory();

            // Create an initial population of randomly generated genomes.
            _genomeList = _genomeFactory.CreateGenomeList(150, 0);

            // Create evolution algorithm and attach update event.
            _ea = experiment.CreateEvolutionAlgorithm(_genomeFactory, _genomeList);
            _ea.UpdateEvent += new EventHandler(ea_UpdateEvent);

            // Start algorithm (it will run on a background thread).
            _ea.StartContinue();

            while (RunState.Terminated != _ea.RunState && RunState.Paused != _ea.RunState)
            {
                Thread.Sleep(2000);
            }

            // Hit return to quit.
            //Console.ReadLine();
        }
        private static void Main(string[] args)
        {
            Debug.Assert(args != null && args.Length == 2,
                "Experiment configuration file and number of runs are required!");

            // Read in experiment configuration file
            string experimentName = args[0];
            int numRuns = Int32.Parse(args[1]);

            // Initialise log4net (log to console).
            XmlConfigurator.Configure(new FileInfo("log4net.properties"));

            // Experiment classes encapsulate much of the nuts and bolts of setting up a NEAT search.
            SteadyStateMazeNavigationNoveltyExperiment experiment = new SteadyStateMazeNavigationNoveltyExperiment();

            // Load config XML.
            XmlDocument xmlConfig = new XmlDocument();
            xmlConfig.Load("./ExperimentConfigurations/" + experimentName);
            experiment.Initialize("Novelty", xmlConfig.DocumentElement, null, null);

            // Create a genome factory with our neat genome parameters object and the appropriate number of input and output neuron genes.
            _genomeFactory = experiment.CreateGenomeFactory();

            // Create an initial population of randomly generated genomes.
            _genomeList = _genomeFactory.CreateGenomeList(experiment.DefaultPopulationSize, 0);

            // Create evolution algorithm and attach update event.
            _ea = experiment.CreateEvolutionAlgorithm(_genomeFactory, _genomeList);
            _ea.UpdateEvent += ea_UpdateEvent;

            // Start algorithm (it will run on a background thread).
            _ea.StartContinue();

            /*while (RunState.Terminated != _ea.RunState && RunState.Paused != _ea.RunState &&
                   _ea.CurrentGeneration < maxGenerations)
            {
                Thread.Sleep(2000);
            }*/

            // Hit return to quit.
            //Console.ReadLine();
        }
        /// <summary>
        ///     Executes a single run of the given experiment.
        /// </summary>
        /// <param name="genomeFactory">The factory for producing NEAT genomes.</param>
        /// <param name="genomeList">The list of initial genomes (population).</param>
        /// <param name="experimentName">The name of the experiment to execute.</param>
        /// <param name="experiment">Reference to the initialized experiment.</param>
        /// <param name="numRuns">Total number of runs being executed.</param>
        /// <param name="runIdx">The current run being executed.</param>
        /// <param name="startingEvaluation">
        ///     The number of evaluations from which execution is starting (this is only applicable in
        ///     the event of a restart).
        /// </param>
        private static void RunExperiment(IGenomeFactory<NeatGenome> genomeFactory, List<NeatGenome> genomeList,
            string experimentName, BaseMazeNavigationExperiment experiment, int numRuns,
            int runIdx, ulong startingEvaluation)
        {
            // Trap initialization exceptions (which, if applicable, could be due to initialization algorithm not
            // finding a viable seed) and continue to the next run if an exception does occur
            try
            {
                // Create evolution algorithm and attach update event.
                _ea = experiment.CreateEvolutionAlgorithm(genomeFactory, genomeList, startingEvaluation);
                _ea.UpdateEvent += ea_UpdateEvent;
            }
            catch (Exception)
            {
                _executionLogger.Error(string.Format("Experiment {0}, Run {1} of {2} failed to initialize",
                    experimentName,
                    runIdx + 1, numRuns));
                Environment.Exit(0);
            }

            _executionLogger.Info(string.Format(
                "Executing Experiment {0}, Run {1} of {2} from {3} starting evaluations", experimentName, runIdx + 1,
                numRuns, startingEvaluation));

            // Start algorithm (it will run on a background thread).
            _ea.StartContinue();

            while (RunState.Terminated != _ea.RunState && RunState.Paused != _ea.RunState)
            {
                Thread.Sleep(2000);
            }
        }
        /// <summary>
        ///     Handles execution of the novelty search algorithm for comparison to each maze in the coevolution experiment.
        /// </summary>
        /// <returns>The end-state of the novelty search algorithm.</returns>
        public INeatEvolutionAlgorithm<NeatGenome> RunNoveltySearch()
        {
            // Instantiate a new novelty search experiment
            NoveltySearchComparisonExperiment nsExperiment = new NoveltySearchComparisonExperiment(_evaluationMazeDomain);

            // Initialize the experiment
            nsExperiment.Initialize(_comparisonExperimentConfig);

            // Create the genome factory and generate genome list
            IGenomeFactory<NeatGenome> genomeFactory = nsExperiment.CreateGenomeFactory();
            List<NeatGenome> genomeList =
                genomeFactory.CreateGenomeList(_comparisonExperimentConfig.Primary_PopulationSize, 0);

            try
            {
                // Setup the algorithm and add the update event
                _comparisonAlgorithm = nsExperiment.CreateEvolutionAlgorithm(genomeFactory, genomeList, 0);
                _comparisonAlgorithm.UpdateEvent += ea_UpdateEvent;
            }
            catch (Exception)
            {
                _executionLogger.Error(
                    string.Format(
                        "Comparison experiment [{0}], for reference experiment [{1}] Run [{2}] of [{3}], failed to initialize",
                        nsExperiment.Name, _referenceExperimentName, _currentRun + 1, _totalRuns));
                Environment.Exit(0);
            }

            _executionLogger.Info(string.Format(
                "Executing comparison experiment [{0}] for reference experiment {1}, Run {2} of {3}", nsExperiment.Name,
                _referenceExperimentName, _currentRun + 1,
                _totalRuns));

            // Start algorithm (it will run on a background thread).
            _comparisonAlgorithm.StartContinue();

            while (RunState.Terminated != _comparisonAlgorithm.RunState &&
                   RunState.Paused != _comparisonAlgorithm.RunState)
            {
                Thread.Sleep(2000);
            }

            // Return the final state of the algorithm so that statistics can be extracted
            return _comparisonAlgorithm;
        }