/// <summary>
        ///     Retrieves the batches during a given run of a given experiment that have associated genome data.
        /// </summary>
        /// <param name="experimentId">The experiment that was executed.</param>
        /// <param name="run">The run number of the given experiment.</param>
        /// <param name="runPhase">The run phase (i.e. initialization or primary) for which to get the associated batches.</param>
        /// <returns>The collection of batch numbers in the given experiment/run that have associated genome data.</returns>
        public static IList<int> GetBatchesWithGenomeData(int experimentId, int run, RunPhase runPhase)
        {
            IList<int> batchesWithGenomeData = null;
            bool querySuccess = false;
            int retryCnt = 0;

            while (querySuccess == false && retryCnt <= MaxQueryRetryCnt)
            {
                try
                {
                    // Query for the distinct batches in the current run of the given experiment
                    using (ExperimentDataEntities context = new ExperimentDataEntities())
                    {
                        batchesWithGenomeData = context.CoevolutionMCSNavigatorExperimentGenomes.Where(
                            expData =>
                                expData.ExperimentDictionaryID == experimentId && expData.Run == run &&
                                expData.RunPhase.RunPhaseName == runPhase.ToString())
                            .Select(row => row.Generation)
                            .Distinct().OrderBy(row => row).ToList();
                    }

                    querySuccess = true;
                }
                catch (Exception e)
                {
                    HandleQueryException(MethodBase.GetCurrentMethod().ToString(), retryCnt++, e);
                }
            }

            return batchesWithGenomeData;
        }
示例#2
0
        static void Main(string[] args)
        {
            int testExperimentCount;

            using (ExperimentDataEntities context = new ExperimentDataEntities())
            {
                testExperimentCount = context.ExperimentDictionaries.Count();
            }

            Console.Out.WriteLine(string.Format("Experiment Count: {0}", testExperimentCount));
        }
        /// <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();
        }
        public List<string> GetDatabaseExperimentNames(string efConnectionString)
        {
            List<string> experimentNames;

            // Open database context and get all experiment names
            // TODO: This constructor needs to accept the passed in connection string to work...
            using (ExperimentDataEntities expDataContext = new ExperimentDataEntities())
            {
                // Get list of experiment names (note that these are sorted via ordered index on the field)
                experimentNames =
                    expDataContext.ExperimentDictionaries.Select(expConf => expConf.ExperimentName).ToList();
            }

            return experimentNames;
        }
示例#5
0
        static void Main(string[] args)
        {
            ExperimentDataEntities dbContext = new ExperimentDataEntities();

            ExperimentDictionary dictionary =
                dbContext.ExperimentDictionaries.Single(expName => expName.ExperimentName == "Experiment 48");

            int maxRun =
                dictionary.NoveltyExperimentEvaluationDatas.Max(x => x.Run);

            NoveltyExperimentEvaluationData ne = new NoveltyExperimentEvaluationData();

            ne.ExperimentDictionaryID = 1;
            ne.Generation = 2;
            ne.SpecieCount = 10;
            ne.AsexualOffspringCount = 5;
            ne.SexualOffspringCount = 5;
            ne.TotalOffspringCount = 10;
            ne.InterspeciesOffspringCount = 5;
            ne.MaxFitness = 100;
            ne.MeanFitness = 50.5;
            ne.MeanSpecieChampFitness = 40.23;
            ne.MaxComplexity = 20;
            ne.MeanComplexity = 15.8;
            ne.MinSpecieSize = 3;
            ne.MaxSpecieSize = 30;

            //ne.TotalEvaluations = 300;
            ne.TotalEvaluations = null;

            //ne.EvaluationsPerSecond = 15;
            ne.EvaluationsPerSecond = null;

            ne.ChampGenomeID = 1;
            ne.ChampGenomeBirthGeneration = 5;
            ne.ChampGenomeConnectionGeneCount = 12;
            ne.ChampGenomeNeuronGeneCount = 5;
            ne.ChampGenomeTotalGeneCount = 17;

            //ne.ChampGenomeEvaluationCount = 13;
            ne.ChampGenomeEvaluationCount = null;

            ne.ChampGenomeBehavior1 = null;
            ne.ChampGenomeBehavior2 = null;

            dbContext.NoveltyExperimentEvaluationDatas.Add(ne);
            dbContext.SaveChanges();
        }
        /// <summary>
        ///     Instantiates a new database context (opens the connection) and gets the experiment configuration key.
        /// </summary>
        public virtual void Open()
        {
            // Open the database connection
            DbContext = new ExperimentDataEntities();

            // Query for the experiment configuration entity
            ExperimentConfiguration =
                DbContext.ExperimentDictionaries.Single(expName => expName.ExperimentName == ExperimentConfigurationName);
        }
        /// <summary>
        ///     Retrieves the total number of primary evaluations executes by mazes and navigators at the given experiment
        ///     run/batch.
        /// </summary>
        /// <param name="experimentId">The experiment that was executed.</param>
        /// <param name="run">The run number of the given experiment.</param>
        /// <param name="batch">The batch number of the given run.</param>
        /// <returns>The total number of primary evaluations from both the maze and navigator queues.</returns>
        public static int GetTotalPrimaryEvaluationsAtBatch(int experimentId, int run, int batch)
        {
            int mazeEvaluations = 0, navigatorEvaluations = 0;
            bool querySuccess = false;
            int retryCnt = 0;

            while (querySuccess == false && retryCnt <= MaxQueryRetryCnt)
            {
                try
                {
                    using (ExperimentDataEntities context = new ExperimentDataEntities())
                    {
                        // Get the total maze evaluations at the given batch
                        mazeEvaluations =
                            context.CoevolutionMCSMazeExperimentEvaluationDatas.Where(
                                mazeData =>
                                    mazeData.ExperimentDictionaryID == experimentId && mazeData.Run == run &&
                                    mazeData.Generation == batch).Select(mazeData => mazeData.TotalEvaluations).First();

                        // Get the total navigator evaluations at the given batch
                        navigatorEvaluations =
                            context.CoevolutionMCSNavigatorExperimentEvaluationDatas.Where(
                                navigatorData =>
                                    navigatorData.ExperimentDictionaryID == experimentId && navigatorData.Run == run &&
                                    navigatorData.Generation == batch &&
                                    navigatorData.RunPhase.RunPhaseName == RunPhase.Primary.ToString())
                                .Select(navigatorData => navigatorData.TotalEvaluations)
                                .Single();
                    }

                    querySuccess = true;
                }
                catch (Exception e)
                {
                    HandleQueryException(MethodBase.GetCurrentMethod().ToString(), retryCnt++, e);
                }
            }

            return mazeEvaluations + navigatorEvaluations;
        }
        /// <summary>
        ///     Retrieves the total number of initialization evaluations that were performed for the given experiment run.
        /// </summary>
        /// <param name="experimentId">The experiment that was executed.</param>
        /// <param name="run">The run number of the given experiment.</param>
        /// <returns>The total number of initialization evaluations.</returns>
        public static int GetInitializationEvaluationsForRun(int experimentId, int run)
        {
            int initEvaluations = 0;
            bool querySuccess = false;
            int retryCnt = 0;

            while (querySuccess == false && retryCnt <= MaxQueryRetryCnt)
            {
                try
                {
                    // Query for the maximum initialization evaluations
                    using (ExperimentDataEntities context = new ExperimentDataEntities())
                    {
                        initEvaluations =
                            context.CoevolutionMCSNavigatorExperimentEvaluationDatas.Where(
                                navigatorData =>
                                    navigatorData.ExperimentDictionaryID == experimentId && navigatorData.Run == run &&
                                    navigatorData.RunPhase.RunPhaseName == RunPhase.Initialization.ToString())
                                .Max(navigatorData => navigatorData.TotalEvaluations);
                    }

                    querySuccess = true;
                }
                catch (Exception e)
                {
                    HandleQueryException(MethodBase.GetCurrentMethod().ToString(), retryCnt++, e);
                }
            }

            return initEvaluations;
        }
        /// <summary>
        ///     Maps applicable entity fields for the MCS 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)
        {
            // Combine and sort the loggable elements
            LoggableElement[] combinedElements = ExtractLoggableElementArray(EvolutionFieldElements.NumFieldElements,
                loggableElements);

            MCSExperimentEvaluationData mcsData = new MCSExperimentEvaluationData
            {
                ExperimentDictionaryID = ExperimentConfiguration.ExperimentDictionaryID,
                Run = Run
            };

            mcsData.Generation =
                (int)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.Generation.Position].Value,
                        mcsData.Generation.GetType());
            mcsData.RunPhase_FK = RunPhaseKey;

            mcsData.PopulationSize =
                (int)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.PopulationSize.Position].Value,
                        mcsData.PopulationSize.GetType());

            mcsData.OffspringCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.TotalOffspringCount.Position].Value,
                        mcsData.OffspringCount.GetType());

            mcsData.MaxComplexity =
                (int)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.MaxComplexity.Position].Value,
                        mcsData.MaxComplexity.GetType());
            mcsData.MeanComplexity =
                (double)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.MeanComplexity.Position].Value,
                        mcsData.MeanComplexity.GetType());

            mcsData.TotalEvaluations =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.TotalEvaluations.Position].Value,
                        typeof (int));
            mcsData.EvaluationsPerSecond =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.EvaluationsPerSecond.Position].Value,
                        typeof (int));

            mcsData.ClosestGenomeID =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeGenomeId.Position].Value,
                        mcsData.ClosestGenomeID.GetType());

            mcsData.ClosestGenomeConnectionGeneCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeConnectionGeneCount.Position].Value,
                        mcsData.ClosestGenomeConnectionGeneCount.GetType());
            mcsData.ClosestGenomeNeuronGeneCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeNeuronGeneCount.Position].Value,
                        mcsData.ClosestGenomeNeuronGeneCount.GetType());
            mcsData.ClosestGenomeTotalGeneCount =
                (int)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeTotalGeneCount.Position].Value,
                        mcsData.ClosestGenomeTotalGeneCount.GetType());

            mcsData.ClosestGenomeDistanceToTarget =
                (double)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeDistanceToTarget.Position].Value,
                        typeof (double));

            mcsData.ClosestGenomeEndPositionX =
                (double)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeBehaviorX.Position].Value,
                        typeof (double));
            mcsData.ClosestGenomeEndPositionY =
                (double)
                    Convert.ChangeType(
                        combinedElements[EvolutionFieldElements.ChampGenomeBehaviorY.Position].Value,
                        typeof (double));

            mcsData.ClosestGenomeXml =
                (string)
                    Convert.ChangeType(combinedElements[EvolutionFieldElements.ChampGenomeXml.Position].Value,
                        typeof (string));

            // Initialize new DB context and persist new record
            using (ExperimentDataEntities experimentContext = new ExperimentDataEntities
            {
                Configuration = {AutoDetectChangesEnabled = false, ValidateOnSaveEnabled = false}
            })
            {
                bool commitSuccessful = false;

                while (commitSuccessful == false)
                {
                    try
                    {
                        // Add the new evaluation data
                        experimentContext.MCSExperimentEvaluationDatas.Add(mcsData);

                        // Save the changes
                        experimentContext.SaveChanges();

                        commitSuccessful = true;
                    }
                    catch (Exception)
                    {
                        // Retry until record is successfully committed
                    }
                }
            }
        }
        /// <summary>
        ///     Writes the given evaluation results to the experiment database.
        /// </summary>
        /// <param name="experimentId">The experiment that was executed.</param>
        /// <param name="run">The run number of the given experiment.</param>
        /// <param name="batch">The batch number of the given run.</param>
        /// <param name="runPhase">
        ///     Indicates whether this is part of the initialization or primary experiment phase.
        /// </param>
        /// <param name="evaluationUnits">The evaluation results to persist.</param>
        /// <param name="commitPageSize">The number of records that are committed within a single batch/context.</param>
        private static void WriteNavigatorMazeEvaluationDataToDatabase(int experimentId, int run, int batch,
            RunPhase runPhase,
            IList<MazeNavigatorEvaluationUnit> evaluationUnits, int commitPageSize)
        {
            // Page through the result set, committing each in the specified batch size
            for (int curPage = 0; curPage <= evaluationUnits.Count/commitPageSize; curPage++)
            {
                IList<CoevolutionMCSMazeNavigatorResult> serializedResults =
                    new List<CoevolutionMCSMazeNavigatorResult>(commitPageSize);

                // Go ahead and lookup the run phase key for all of the records
                // (instead of hitting the database on every iteration of the below loop)
                int runPhaseKey = GetRunPhaseKey(runPhase);

                // Build a list of serialized results
                foreach (
                    MazeNavigatorEvaluationUnit evaluationUnit in
                        evaluationUnits.Skip(curPage*commitPageSize).Take(commitPageSize))
                {
                    serializedResults.Add(new CoevolutionMCSMazeNavigatorResult
                    {
                        ExperimentDictionaryID = experimentId,
                        Run = run,
                        Generation = batch,
                        RunPhase_FK = runPhaseKey,
                        MazeGenomeID = evaluationUnit.MazeId,
                        NavigatorGenomeID = evaluationUnit.AgentId,
                        IsMazeSolved = evaluationUnit.IsMazeSolved,
                        NumTimesteps = evaluationUnit.NumTimesteps
                    });
                }

                // Create a new context and persist the batch
                using (ExperimentDataEntities context = new ExperimentDataEntities())
                {
                    // Auto-detect changes and save validation are switched off to speed things up
                    context.Configuration.AutoDetectChangesEnabled = false;
                    context.Configuration.ValidateOnSaveEnabled = false;

                    context.CoevolutionMCSMazeNavigatorResults.AddRange(serializedResults);
                    context.SaveChanges();
                }
            }
        }
        /// <summary>
        ///     Maps applicable entity fields for the MCS experiment organism 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)
        {
            // Combine and sort the loggable elements
            LoggableElement[] combinedElements = ExtractLoggableElementArray(EvaluationFieldElements.NumFieldElements,
                loggableElements);

            MCSExperimentOrganismStateData mcsData = new MCSExperimentOrganismStateData
            {
                ExperimentDictionaryID = ExperimentConfiguration.ExperimentDictionaryID,
                Run = Run
            };

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

            // Initialize new DB context and persist new record
            using (ExperimentDataEntities experimentContext = new ExperimentDataEntities
            {
                Configuration = {AutoDetectChangesEnabled = false, ValidateOnSaveEnabled = false}
            })
            {
                bool commitSuccessful = false;

                while (commitSuccessful == false)
                {
                    try
                    {
                        // Add the new organism state data
                        experimentContext.MCSExperimentOrganismStateDatas.Add(mcsData);

                        // Save the changes
                        experimentContext.SaveChanges();

                        commitSuccessful = true;
                    }
                    catch (Exception)
                    {
                        // Retry until record is successfully committed
                    }
                }
            }
        }
        /// <summary>
        ///     Writes the given trajectory diversity results to the experiment database.
        /// </summary>
        /// <param name="experimentId">The experiment that was executed.</param>
        /// <param name="run">The run number of the given experiment.</param>
        /// <param name="batch">The batch number of the given run.</param>
        /// <param name="evaluationUnits">The evaluation results to persist.</param>
        /// <param name="commitPageSize">The number of records that are committed within a single batch/context.</param>
        private static void WriteTrajectoryDataToDatabase(int experimentId, int run, int batch,
            IList<MazeNavigatorEvaluationUnit> evaluationUnits, int commitPageSize)
        {
            // Page through the result set, committing each in the specified batch size
            for (int curPage = 0; curPage <= evaluationUnits.Count/commitPageSize; curPage++)
            {
                IList<CoevolutionMCSFullTrajectory> serializedResults =
                    new List<CoevolutionMCSFullTrajectory>(commitPageSize);

                // Build a list of serialized results
                foreach (
                    MazeNavigatorEvaluationUnit evaluationUnit in
                        evaluationUnits.Skip(curPage*commitPageSize).Take(commitPageSize))
                {
                    for (int idx = 0; idx < evaluationUnit.AgentTrajectory.Count(); idx += 2)
                    {
                        serializedResults.Add(new CoevolutionMCSFullTrajectory
                        {
                            ExperimentDictionaryID = experimentId,
                            Run = run,
                            Generation = batch,
                            Timestep = ((idx/2) + 1), // this is the timestep
                            MazeGenomeID = evaluationUnit.MazeId,
                            NavigatorGenomeID = evaluationUnit.AgentId,
                            XPosition = Convert.ToDecimal(evaluationUnit.AgentTrajectory[idx]),
                            YPosition = Convert.ToDecimal(evaluationUnit.AgentTrajectory[idx + 1])
                        });
                    }
                }

                // Create a new context and persist the batch
                using (ExperimentDataEntities context = new ExperimentDataEntities())
                {
                    // Auto-detect changes and save validation are switched off to speed things up
                    context.Configuration.AutoDetectChangesEnabled = false;
                    context.Configuration.ValidateOnSaveEnabled = false;

                    context.CoevolutionMCSFullTrajectories.AddRange(serializedResults);
                    context.SaveChanges();
                }
            }
        }
        /// <summary>
        ///     Retrieves the primary key associated with the given run phase.
        /// </summary>
        /// <param name="runPhase">The run phase for which to lookup the key.</param>
        /// <returns>The key (in the "RunPhase" database table) for the given run phase object.</returns>
        private static int GetRunPhaseKey(RunPhase runPhase)
        {
            int runPhaseKey = 0;
            bool querySuccess = false;
            int retryCnt = 0;

            while (querySuccess == false && retryCnt <= MaxQueryRetryCnt)
            {
                try
                {
                    // Query for the run phase key
                    using (ExperimentDataEntities context = new ExperimentDataEntities())
                    {
                        runPhaseKey =
                            context.RunPhases.First(runPhaseData => runPhaseData.RunPhaseName == runPhase.ToString())
                                .RunPhaseID;
                    }

                    querySuccess = true;
                }
                catch (Exception e)
                {
                    HandleQueryException(MethodBase.GetCurrentMethod().ToString(), retryCnt++, e);
                }
            }

            return runPhaseKey;
        }
        /// <summary>
        ///     Retrieves the navigator genome data (i.e. evaluation statistics and XML) for the entirety of a given
        ///     run/experiment.
        /// </summary>
        /// <param name="experimentId">The experiment that was executed.</param>
        /// <param name="run">The run number of the given experiment.</param>
        /// <param name="runPhase">
        ///     Indicates whether this is part of the initialization or primary experiment phase.
        /// </param>
        /// <returns>The navigator genome data.</returns>
        public static IList<CoevolutionMCSNavigatorExperimentGenome> GetNavigatorGenomeData(int experimentId, int run,
            RunPhase runPhase)
        {
            IList<CoevolutionMCSNavigatorExperimentGenome> navigatorGenomes = null;
            bool querySuccess = false;
            int retryCnt = 0;

            while (querySuccess == false && retryCnt <= MaxQueryRetryCnt)
            {
                try
                {
                    // Query for the distinct navigator genomes logged during the run
                    using (ExperimentDataEntities context = new ExperimentDataEntities())
                    {
                        navigatorGenomes = context.CoevolutionMCSNavigatorExperimentGenomes.Where(
                            expData =>
                                expData.ExperimentDictionaryID == experimentId && expData.Run == run &&
                                expData.RunPhase.RunPhaseName == runPhase.ToString())
                            .GroupBy(expData => expData.GenomeID)
                            .Select(expDataGroup => expDataGroup.OrderBy(expData => expData.Generation).FirstOrDefault())
                            .ToList();
                    }

                    querySuccess = true;
                }
                catch (Exception e)
                {
                    HandleQueryException(MethodBase.GetCurrentMethod().ToString(), retryCnt++, e);
                }
            }

            return navigatorGenomes;
        }
        /// <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>
        ///     Retrieves the list of maze/navigator combinations that were successful for the given experiment, run, and batch.
        /// </summary>
        /// <param name="experimentId">The experiment that was executed.</param>
        /// <param name="run">The run number of the given experiment.</param>
        /// <param name="batch">The batch number of the given run.</param>
        /// <returns>The list of maze/navigator combinations that were successful for the given experiment, run, and batch.</returns>
        public static IList<CoevolutionMCSMazeNavigatorResult> GetSuccessfulNavigations(int experimentId, int run,
            int batch)
        {
            IList<CoevolutionMCSMazeNavigatorResult> navigationResults = null;
            bool querySuccess = false;
            int retryCnt = 0;

            while (querySuccess == false && retryCnt <= MaxQueryRetryCnt)
            {
                try
                {
                    using (ExperimentDataEntities context = new ExperimentDataEntities())
                    {
                        // Get only the combination of navigators and mazes that resulted in a successful navigation
                        navigationResults = context.CoevolutionMCSMazeNavigatorResults.Where(
                            nav =>
                                experimentId == nav.ExperimentDictionaryID && run == nav.Run && batch == nav.Generation &&
                                RunPhase.Primary.ToString().Equals(nav.RunPhase.RunPhaseName) && nav.IsMazeSolved)
                            .ToList();
                    }

                    querySuccess = true;
                }
                catch (Exception e)
                {
                    HandleQueryException(MethodBase.GetCurrentMethod().ToString(), retryCnt++, e);
                }
            }

            return navigationResults;
        }
        /// <summary>
        ///     Retrieves specie assignments for the given navigator genome IDs and experiment, run, and batch.
        /// </summary>
        /// <param name="experimentId">The experiment that was executed.</param>
        /// <param name="run">The run number of the given experiment.</param>
        /// <param name="batch">The batch number of the given run.</param>
        /// <param name="runPhase">Indicates whether this is part of the initialization or primary experiment phase.</param>
        /// <param name="navigatorGenomeIds">The navigator genome IDs to group into species.</param>
        /// <returns>Specie assignments for the given navigator genome IDs and experiment, run, and batch.</returns>
        public static List<SpecieGenomesGroup> GetSpecieAssignmentsForNavigatorGenomeIds(int experimentId, int run,
            int batch, RunPhase runPhase, IList<int> navigatorGenomeIds)
        {
            var navigatorSpecieGenomesGroups = new List<SpecieGenomesGroup>();
            bool querySuccess = false;
            int retryCnt = 0;

            while (querySuccess == false && retryCnt <= MaxQueryRetryCnt)
            {
                try
                {
                    using (ExperimentDataEntities context = new ExperimentDataEntities())
                    {
                        // Get the species to which the navigators are assigned and group by species
                        var specieGroupedNavigators =
                            context.CoevolutionMCSNavigatorExperimentGenomes.Where(
                                nav =>
                                    experimentId == nav.ExperimentDictionaryID && run == nav.Run &&
                                    batch == nav.Generation && runPhase.ToString().Equals(nav.RunPhase.RunPhaseName) &&
                                    navigatorGenomeIds.Contains(nav.GenomeID))
                                .Select(nav => new {nav.SpecieID, nav.GenomeID})
                                .GroupBy(nav => nav.SpecieID)
                                .ToList();

                        // Build list of navigator specie genome groups
                        navigatorSpecieGenomesGroups.AddRange(
                            specieGroupedNavigators.Select(
                                specieGenomesGroup =>
                                    new SpecieGenomesGroup((int) specieGenomesGroup.Key,
                                        specieGenomesGroup.Select(gg => gg.GenomeID).ToList())));
                    }

                    querySuccess = true;
                }
                catch (Exception e)
                {
                    HandleQueryException(MethodBase.GetCurrentMethod().ToString(), retryCnt++, e);
                }
            }

            return navigatorSpecieGenomesGroups;
        }
        /// <summary>
        ///     Retrieves specie assignments for the given maze genome IDs and experiment, run, and batch.
        /// </summary>
        /// <param name="experimentId">The experiment that was executed.</param>
        /// <param name="run">The run number of the given experiment.</param>
        /// <param name="batch">The batch number of the given run.</param>
        /// <param name="mazeGenomeIds">The maze genome IDs to group into species.</param>
        /// <returns>Specie assignments for the given maze genome IDs and experiment, run, and batch.</returns>
        public static List<SpecieGenomesGroup> GetSpecieAssignmentsForMazeGenomeIds(int experimentId, int run, int batch,
            IList<int> mazeGenomeIds)
        {
            var mazeSpecieGenomesGroups = new List<SpecieGenomesGroup>();
            bool querySuccess = false;
            int retryCnt = 0;

            while (querySuccess == false && retryCnt <= MaxQueryRetryCnt)
            {
                try
                {
                    using (ExperimentDataEntities context = new ExperimentDataEntities())
                    {
                        // Get the species to which the mazes are assigned and group by species
                        var specieGroupedMazes =
                            context.CoevolutionMCSMazeExperimentGenomes.Where(
                                maze =>
                                    experimentId == maze.ExperimentDictionaryID && run == maze.Run &&
                                    batch == maze.Generation && mazeGenomeIds.Contains(maze.GenomeID))
                                .Select(maze => new {maze.SpecieID, maze.GenomeID})
                                .GroupBy(maze => maze.SpecieID)
                                .ToList();

                        // Build list of maze specie genome groups
                        mazeSpecieGenomesGroups.AddRange(
                            specieGroupedMazes.Select(
                                specieGenomesGroup =>
                                    new SpecieGenomesGroup((int) specieGenomesGroup.Key,
                                        specieGenomesGroup.Select(gg => gg.GenomeID).ToList())));
                    }

                    querySuccess = true;
                }
                catch (Exception e)
                {
                    HandleQueryException(MethodBase.GetCurrentMethod().ToString(), retryCnt++, e);
                }
            }

            return mazeSpecieGenomesGroups;
        }
        /// <summary>
        ///     Retrieves the number of runs that were executed for a given experiment.
        /// </summary>
        /// <param name="experimentId">The experiment for which to compute the number of corresponding runs.</param>
        /// <returns>The number of runs that were executed for the given experiment.</returns>
        public static int GetNumRuns(int experimentId)
        {
            int numRuns = 0;
            bool querySuccess = false;
            int retryCnt = 0;

            while (querySuccess == false && retryCnt <= MaxQueryRetryCnt)
            {
                try
                {
                    // Query for the number of runs for the given experiment
                    using (ExperimentDataEntities context = new ExperimentDataEntities())
                    {
                        numRuns = context.CoevolutionMCSMazeExperimentEvaluationDatas.Where(
                            expData => expData.ExperimentDictionaryID == experimentId)
                            .Select(row => row.Run)
                            .Distinct()
                            .Count();
                    }

                    querySuccess = true;
                }
                catch (Exception e)
                {
                    HandleQueryException(MethodBase.GetCurrentMethod().ToString(), retryCnt++, e);
                }
            }

            return numRuns;
        }
        /// <summary>
        ///     Retrieves the navigator genome data (i.e. evaluation statistics and XML) for a particular batch of a given
        ///     run/experiemnt.
        /// </summary>
        /// <param name="experimentId">The experiment that was executed.</param>
        /// <param name="run">The run number of the given experiment.</param>
        /// <param name="batch">The batch number of the given run.</param>
        /// <param name="runPhase">
        ///     Indicates whether this is part of the initialization or primary experiment phase.
        /// </param>
        /// <param name="navigatorGenomeIds">The navigator genome IDs by which to filter the query result set (optional).</param>
        /// <returns>The navigator genome data.</returns>
        public static IList<CoevolutionMCSNavigatorExperimentGenome> GetNavigatorGenomeData(int experimentId, int run,
            int batch, RunPhase runPhase, IList<int> navigatorGenomeIds = null)
        {
            IList<CoevolutionMCSNavigatorExperimentGenome> navigatorGenomes = null;
            bool querySuccess = false;
            int retryCnt = 0;

            while (querySuccess == false && retryCnt <= MaxQueryRetryCnt)
            {
                try
                {
                    using (ExperimentDataEntities context = new ExperimentDataEntities())
                    {
                        // Query for navigator genomes logged during the current batch and constrained by the given set of genome IDs
                        if (navigatorGenomeIds != null)
                        {
                            navigatorGenomes =
                                context.CoevolutionMCSNavigatorExperimentGenomes.Where(
                                    expData =>
                                        navigatorGenomeIds.Contains(expData.GenomeID) &&
                                        expData.ExperimentDictionaryID == experimentId && expData.Run == run &&
                                        expData.Generation == batch &&
                                        expData.RunPhase.RunPhaseName == runPhase.ToString())
                                    .ToList();
                        }
                        // Otherwise, query for all navigator genomes logged during the current batch
                        else
                        {
                            navigatorGenomes =
                                context.CoevolutionMCSNavigatorExperimentGenomes.Where(
                                    expData =>
                                        expData.ExperimentDictionaryID == experimentId && expData.Run == run &&
                                        expData.Generation == batch &&
                                        expData.RunPhase.RunPhaseName == runPhase.ToString())
                                    .ToList();
                        }
                    }

                    querySuccess = true;
                }
                catch (Exception e)
                {
                    HandleQueryException(MethodBase.GetCurrentMethod().ToString(), retryCnt++, e);
                }
            }

            return navigatorGenomes;
        }
        /// <summary>
        ///     Looks up an experiment configuration given the unique experiment name.
        /// </summary>
        /// <param name="experimentName">The experiment name whose configuration to lookup.</param>
        /// <returns>The corresponding experiment configuration (i.e. experiment dictionary).</returns>
        public static ExperimentDictionary LookupExperimentConfiguration(string experimentName)
        {
            ExperimentDictionary experimentConfiguration = null;
            bool querySuccess = false;
            int retryCnt = 0;

            while (querySuccess == false && retryCnt <= MaxQueryRetryCnt)
            {
                try
                {
                    // Query for the experiment configuration given the name (which is guaranteed to be unique)
                    using (ExperimentDataEntities context = new ExperimentDataEntities())
                    {
                        experimentConfiguration =
                            context.ExperimentDictionaries.Single(expName => expName.ExperimentName == experimentName);
                    }

                    querySuccess = true;
                }
                catch (Exception e)
                {
                    HandleQueryException(MethodBase.GetCurrentMethod().ToString(), retryCnt++, e);
                }
            }

            return experimentConfiguration;
        }
        /// <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();
        }