/// <summary>
        ///     Executes all runs of a given experiment using the database as both the configuration source and the results
        ///     destination.
        /// </summary>
        /// <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="seedPopulationFiles">The seed population XML file names.</param>
        private static void ExecuteDatabaseBasedExperiment(string experimentName, int numRuns,
            string[] seedPopulationFiles)
        {
            // Create new database context and read in configuration for the given experiment
            ExperimentDataEntities experimentContext = new ExperimentDataEntities();
            var name = experimentName;
            ExperimentDictionary experimentConfiguration =
                experimentContext.ExperimentDictionaries.Single(
                    expName => expName.ExperimentName == name);

            // Determine which experiment to execute
            BaseMazeNavigationExperiment experiment =
                DetermineMazeNavigationExperiment(experimentConfiguration.Primary_SearchAlgorithmName,
                    experimentConfiguration.Primary_SelectionAlgorithmName, false);

            // Execute the experiment for the specified number of runs
            for (int runIdx = 0; runIdx < numRuns; runIdx++)
            {
                // Initialize the experiment
                experiment.Initialize(experimentConfiguration);

                _executionLogger.Error(string.Format("Initialized experiment {0}.", experiment.GetType()));

                // This will hold the number of evaluations executed for each "attempt" of the EA within the current run
                ulong curEvaluations = 0;

                // This will hold the number of restarts of the algorithm
                int curRestarts = 0;

                do
                {
                    List<NeatGenome> genomeList;

                    // Open and load population XML file.
                    using (XmlReader xr = XmlReader.Create(seedPopulationFiles[runIdx]))
                    {
                        genomeList = experiment.LoadPopulation(xr);
                    }
                    IGenomeFactory<NeatGenome> genomeFactory = genomeList[0].GenomeFactory;
                    _executionLogger.Info(string.Format("Loaded [{0}] genomes as initial population.", genomeList.Count));

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

                    // Kick off the experiment run
                    RunExperiment(genomeFactory, genomeList, experimentName, experiment, numRuns, runIdx, curEvaluations);

                    // Increment the evaluations
                    curEvaluations = _ea.CurrentEvaluations;

                    // Increment the restart count
                    curRestarts++;
                } while (_ea.StopConditionSatisfied == false && experiment.MaxRestarts >= curRestarts);
            }

            // Dispose of the database context
            experimentContext.Dispose();
        }
        /// <summary>
        ///     Maps applicable entity fields for the novelty experiment organism state entity and persists to the database.
        /// </summary>
        /// <param name="loggableElements">The loggable elements (data) to persist.</param>
        public override void LogRow(params List<LoggableElement>[] loggableElements)
        {
            // Initialize new DB context
            ExperimentDataEntities localDbContext = new ExperimentDataEntities
            {
                Configuration = {AutoDetectChangesEnabled = false, ValidateOnSaveEnabled = false}
            };

            // Combine and sort the loggable elements
            LoggableElement[] combinedElements = ExtractLoggableElementArray(EvaluationFieldElements.NumFieldElements,
                loggableElements);

            NoveltyExperimentOrganismStateData noveltyData = new NoveltyExperimentOrganismStateData
            {
                ExperimentDictionaryID = ExperimentConfiguration.ExperimentDictionaryID,
                Run = Run
            };

            noveltyData.Generation =
                (int)
                    Convert.ChangeType(combinedElements[EvaluationFieldElements.Generation.Position].Value,
                        noveltyData.Generation.GetType());
            noveltyData.Evaluation =
                (int)
                    Convert.ChangeType(combinedElements[EvaluationFieldElements.EvaluationCount.Position].Value,
                        noveltyData.Evaluation.GetType());
            noveltyData.StopConditionSatisfied =
                (bool)
                    Convert.ChangeType(
                        combinedElements[EvaluationFieldElements.StopConditionSatisfied.Position].Value,
                        noveltyData.StopConditionSatisfied.GetType());
            noveltyData.DistanceToTarget =
                (double)
                    Convert.ChangeType(
                        combinedElements[EvaluationFieldElements.DistanceToTarget.Position].Value,
                        noveltyData.DistanceToTarget.GetType());
            noveltyData.AgentXLocation =
                (double)
                    Convert.ChangeType(combinedElements[EvaluationFieldElements.AgentXLocation.Position].Value,
                        noveltyData.AgentXLocation.GetType());
            noveltyData.AgentYLocation =
                (double)
                    Convert.ChangeType(combinedElements[EvaluationFieldElements.AgentYLocation.Position].Value,
                        noveltyData.AgentYLocation.GetType());

            // Add the new organism state observation
            localDbContext.NoveltyExperimentOrganismStateDatas.Add(noveltyData);

            // Save the changes and dispose of the context
            localDbContext.SaveChanges();
            localDbContext.Dispose();
        }
        /// <summary>
        ///     Maps applicable entity fields for the novelty experiment evaluation entity and persists to the database.
        /// </summary>
        /// <param name="loggableElements">The loggable elements (data) to persist.</param>
        public override void LogRow(params List<LoggableElement>[] loggableElements)
        {
            // Initialize new DB context
            ExperimentDataEntities localDbContext = new ExperimentDataEntities
            {
                Configuration = {AutoDetectChangesEnabled = false, ValidateOnSaveEnabled = false}
            };

            // Combine and sort the loggable elements
            LoggableElement[] combinedElements = ExtractLoggableElementArray(EvolutionFieldElements.NumFieldElements,
                loggableElements);

            NoveltyExperimentEvaluationData noveltyData = new NoveltyExperimentEvaluationData
            {
                ExperimentDictionaryID = ExperimentConfiguration.ExperimentDictionaryID,
                Run = Run
            };

            noveltyData.Generation =
                (int)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.Generation.Position].Value,
                        noveltyData.Generation.GetType());
            noveltyData.SpecieCount =
                (int)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.SpecieCount.Position].Value,
                        noveltyData.SpecieCount.GetType());
            noveltyData.AsexualOffspringCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.AsexualOffspringCount.Position].Value,
                        noveltyData.AsexualOffspringCount.GetType());
            noveltyData.SexualOffspringCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.SexualOffspringCount.Position].Value,
                        noveltyData.SexualOffspringCount.GetType());
            noveltyData.TotalOffspringCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.TotalOffspringCount.Position].Value,
                        noveltyData.TotalOffspringCount.GetType());
            noveltyData.InterspeciesOffspringCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.InterspeciesOffspringCount.Position].Value,
                        noveltyData.InterspeciesOffspringCount.GetType());
            noveltyData.MaxFitness =
                (double)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.MaxFitness.Position].Value,
                        noveltyData.MaxFitness.GetType());
            noveltyData.MeanFitness =
                (double)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.MeanFitness.Position].Value,
                        noveltyData.MeanFitness.GetType());
            noveltyData.MeanSpecieChampFitness =
                (double)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.MeanSpecieChampFitness.Position].Value,
                        noveltyData.MeanSpecieChampFitness.GetType());
            noveltyData.MaxComplexity =
                (int)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.MaxComplexity.Position].Value,
                        noveltyData.MaxComplexity.GetType());
            noveltyData.MeanComplexity =
                (double)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.MeanComplexity.Position].Value,
                        noveltyData.MeanComplexity.GetType());
            noveltyData.MinSpecieSize =
                (int)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.MinSpecieSize.Position].Value,
                        noveltyData.MinSpecieSize.GetType());
            noveltyData.MaxSpecieSize =
                (int)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.MaxSpecieSize.Position].Value,
                        noveltyData.MaxSpecieSize.GetType());
            noveltyData.TotalEvaluations =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.TotalEvaluations.Position].Value,
                        typeof (int));
            noveltyData.EvaluationsPerSecond =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.EvaluationsPerSecond.Position].Value,
                        typeof (int));
            noveltyData.ChampGenomeID =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeGenomeId.Position].Value,
                        noveltyData.ChampGenomeID.GetType());
            noveltyData.ChampGenomeFitness =
                (double)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeFitness.Position].Value,
                        noveltyData.ChampGenomeFitness.GetType());
            noveltyData.ChampGenomeBirthGeneration =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeBirthGeneration.Position].Value,
                        noveltyData.ChampGenomeBirthGeneration.GetType());
            noveltyData.ChampGenomeConnectionGeneCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeConnectionGeneCount.Position].Value,
                        noveltyData.ChampGenomeConnectionGeneCount.GetType());
            noveltyData.ChampGenomeNeuronGeneCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeNeuronGeneCount.Position].Value,
                        noveltyData.ChampGenomeNeuronGeneCount.GetType());
            noveltyData.ChampGenomeTotalGeneCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeTotalGeneCount.Position].Value,
                        noveltyData.ChampGenomeTotalGeneCount.GetType());
            noveltyData.ChampGenomeEvaluationCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeEvaluationCount.Position].Value,
                        typeof (int));
            noveltyData.ChampGenomeBehavior1 =
                (double)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeBehaviorX.Position].Value,
                        typeof (double));
            noveltyData.ChampGenomeBehavior2 =
                (double)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeBehaviorY.Position].Value,
                        typeof (double));

            // Add the new evaluation data
            localDbContext.NoveltyExperimentEvaluationDatas.Add(noveltyData);

            // Save the changes and dispose of the context
            localDbContext.SaveChanges();
            localDbContext.Dispose();
        }