Esempio n. 1
0
        /// <summary>
        ///     Reads the experiment logging configuration.
        /// </summary>
        /// <param name="xmlConfig">The reference to the XML configuration file.</param>
        /// <param name="loggingType">The type of logging (evolution, evaluation, etc.).</param>
        /// <param name="parentElementName">The name of the top-level logging configuration element.</param>
        /// <returns>A constructed data logger.</returns>
        public static IDataLogger ReadDataLogger(XmlElement xmlConfig, LoggingType loggingType,
                                                 string parentElementName = "LoggingConfig")
        {
            XmlElement xmlLoggingConfig = null;

            // Get root of novelty configuration section
            var nodeList = xmlConfig.GetElementsByTagName(parentElementName, "");

            // Iterate through the list of logging configurations, finding one that matches the specified logging type
            foreach (XmlElement curXmlLoggingConfig in nodeList)
            {
                if (loggingType ==
                    LoggingParameterUtils.ConvertStringToLoggingType(XmlUtils.TryGetValueAsString(curXmlLoggingConfig,
                                                                                                  "Type")))
                {
                    xmlLoggingConfig = curXmlLoggingConfig;
                    break;
                }
            }

            // If no appropriate logger was found, just return null (meaning there won't be any logging for this type)
            if (xmlLoggingConfig == null)
            {
                return(null);
            }

            // Read in the log file name
            var logFileName = XmlUtils.TryGetValueAsString(xmlLoggingConfig, "LogFile");

            // Instantiate the file data logger
            IDataLogger dataLogger = new FileDataLogger(logFileName);

            return(dataLogger);
        }
        /// <summary>
        ///     Executes all runs of a given MCC experiment using a configuration file as the configuration source and
        ///     generated flat files as the result destination.
        /// </summary>
        /// <param name="experimentConfigurationDirectory">The directory containing the XML experiment configuration file.</param>
        /// <param name="logFileDirectory">The directory into which to write the evolution/evaluation log files.</param>
        /// <param name="seedAgentPath">The path to the XML agent genome file.</param>
        /// <param name="seedMazePath">The path to the XML maze genome file.</param>
        /// <param name="experimentName">The name of the experiment to execute.</param>
        /// <param name="numRuns">The number of runs to execute for that experiment.</param>
        /// <param name="startFromRun">The run to start from (1 by default).</param>
        private static void ExecuteFileBasedMCCExperiment(string experimentConfigurationDirectory,
                                                          string logFileDirectory, string seedAgentPath, string seedMazePath,
                                                          string experimentName,
                                                          int numRuns, int startFromRun)
        {
            // Read in the configuration files that match the given experiment name (should only be 1 file)
            var experimentConfigurationFiles =
                Directory.GetFiles(experimentConfigurationDirectory, $"{experimentName}.*");

            // Make sure there's only one configuration file that matches the experiment name
            // (otherwise, we don't know for sure which configuration to use)
            if (experimentConfigurationFiles.Count() != 1)
            {
                _executionLogger.Error(
                    $"Experiment configuration ambiguous: expected a single possible configuration, but found {experimentConfigurationFiles.Count()} possible configurations");
                Environment.Exit(0);
            }

            // Instantiate XML reader for configuration file
            var xmlConfig = new XmlDocument();

            xmlConfig.Load(experimentConfigurationFiles[0]);

            // Determine which experiment to execute
            var experiment = DetermineMCCMazeNavigationExperiment(xmlConfig.DocumentElement);

            // Execute the experiment for the specified number of runs
            for (int runIdx = startFromRun; runIdx <= numRuns; runIdx++)
            {
                // Initialize the data loggers for the given run
                IDataLogger navigatorDataLogger =
                    new FileDataLogger($"{logFileDirectory}\\{experimentName} - Run{runIdx} - NavigatorEvolution.csv");
                IDataLogger navigatorPopulationLogger =
                    new FileDataLogger($"{logFileDirectory}\\{experimentName} - Run{runIdx} - NavigatorPopulation.csv");
                IDataLogger navigatorGenomesLogger =
                    new FileDataLogger($"{logFileDirectory}\\{experimentName} - Run{runIdx} - NavigatorGenomes.csv");
                IDataLogger mazeDataLogger =
                    new FileDataLogger($"{logFileDirectory}\\{experimentName} - Run{runIdx} - MazeEvolution.csv");
                IDataLogger mazePopulationLogger =
                    new FileDataLogger($"{logFileDirectory}\\{experimentName} - Run{runIdx} - MazePopulation.csv");
                IDataLogger mazeGenomesLogger =
                    new FileDataLogger($"{logFileDirectory}\\{experimentName} - Run{runIdx} - MazeGenomes.csv");

                // Initialize new experiment
                experiment.Initialize(experimentName, xmlConfig.DocumentElement, navigatorDataLogger,
                                      navigatorPopulationLogger, navigatorGenomesLogger, mazeDataLogger, mazePopulationLogger,
                                      mazeGenomesLogger);

                _executionLogger.Info($"Initialized experiment {experiment.GetType()}.");

                // Create a new agent genome factory
                var agentGenomeFactory = experiment.CreateAgentGenomeFactory();

                // Create a new maze genome factory
                var mazeGenomeFactory = experiment.CreateMazeGenomeFactory();

                // Read in the seed agent population or generate the initial agent population if no seeds were specified
                var agentGenomeList = seedAgentPath != null
                    ? ExperimentUtils.ReadSeedNeatGenomes(seedAgentPath, (NeatGenomeFactory)agentGenomeFactory)
                    : agentGenomeFactory.CreateGenomeList(experiment.AgentInitializationGenomeCount, 0);

                // Read in the seed maze population
                var mazeGenomeList = ExperimentUtils
                                     .ReadSeedMazeGenomes(seedMazePath, (MazeGenomeFactory)mazeGenomeFactory)
                                     .Take(experiment.MazeSeedGenomeCount).ToList();

                // Check for insufficient number of genomes in the seed maze file
                if (mazeGenomeList.Count < experiment.MazeSeedGenomeCount)
                {
                    throw new SharpNeatException(
                              $"The maze genome input file contains only {mazeGenomeList.Count} genomes while the experiment configuration requires {experiment.MazeDefaultPopulationSize} genomes.");
                }

                _executionLogger.Info(
                    $"Loaded [{agentGenomeList.Count}] navigator genomes and [{mazeGenomeList.Count}] seed maze genomes as initial populations.");

                _executionLogger.Info("Kicking off Experiment initialization/execution");

                // Kick off the experiment run
                RunExperiment(agentGenomeFactory, mazeGenomeFactory, agentGenomeList, mazeGenomeList,
                              seedAgentPath != null, experimentName, experiment, numRuns, runIdx);

                // Close the data loggers
                navigatorDataLogger.Close();
                navigatorPopulationLogger.Close();
                navigatorGenomesLogger.Close();
                mazeDataLogger.Close();
                mazePopulationLogger.Close();
                mazeGenomesLogger.Close();
            }
        }