/// <summary>
		/// Default Constructor.
		/// </summary>
		public EvolutionAlgorithm(Population pop, IPopulationEvaluator populationEvaluator, NeatParameters neatParameters)
		{
			this.pop = pop;
			this.populationEvaluator = populationEvaluator;
			this.neatParameters = neatParameters;
			neatParameters_Normal = neatParameters;

			neatParameters_PrunePhase = new NeatParameters(neatParameters);
			neatParameters_PrunePhase.pMutateAddConnection = 0.0;
            neatParameters_PrunePhase.pMutateAddNode = 0.0;
            neatParameters_PrunePhase.pMutateAddModule = 0.0;
            neatParameters_PrunePhase.pMutateConnectionWeights = 0.33;
			neatParameters_PrunePhase.pMutateDeleteConnection = 0.33;
			neatParameters_PrunePhase.pMutateDeleteSimpleNeuron = 0.33;

			// Disable all crossover as this has a tendency to increase complexity, which is precisely what
			// we don't want during a pruning phase.
			neatParameters_PrunePhase.pOffspringAsexual = 1.0;
			neatParameters_PrunePhase.pOffspringSexual = 0.0;
			
			if(neatParameters.multiobjective) {
				this.multiobjective=new Multiobjective.Multiobjective(neatParameters);
				neatParameters.compatibilityThreshold=100000000.0; //disable speciation w/ multiobjective
			}
			
            if(neatParameters.noveltySearch)
            {
                if(neatParameters.noveltyHistogram)
                {
                    this.noveltyFixed = new noveltyfixed(neatParameters.archiveThreshold);
                    this.histogram = new noveltyhistogram(neatParameters.histogramBins);
					noveltyInitialized=true;
                    InitialisePopulation();
                }
                
                if(neatParameters.noveltyFixed || neatParameters.noveltyFloat)
                {
                    this.noveltyFixed = new noveltyfixed(neatParameters.archiveThreshold);
                    InitialisePopulation();
                    noveltyFixed.initialize(this.pop);
					noveltyInitialized=true;
			        populationEvaluator.EvaluatePopulation(pop, this);			
			        UpdateFitnessStats();
			        DetermineSpeciesTargetSize();
                }
               
            }
            else
            {
			InitialisePopulation();
			}
		}
		/// <summary>
		/// Default Constructor.
		/// </summary>
		public EvolutionAlgorithm(Population pop, IPopulationEvaluator populationEvaluator, NeatParameters neatParameters)
		{
			this.pop = pop;
			this.populationEvaluator = populationEvaluator;
			this.neatParameters = neatParameters;
			neatParameters_Normal = neatParameters;

			neatParameters_PrunePhase = new NeatParameters(neatParameters);
			neatParameters_PrunePhase.pMutateAddConnection = 0.0;
            neatParameters_PrunePhase.pMutateAddNode = 0.0;
            neatParameters_PrunePhase.pMutateAddModule = 0.0;
            neatParameters_PrunePhase.pMutateConnectionWeights = 0.33;
			neatParameters_PrunePhase.pMutateDeleteConnection = 0.33;
			neatParameters_PrunePhase.pMutateDeleteSimpleNeuron = 0.33;

			// Disable all crossover as this has a tendency to increase complexity, which is precisely what
			// we don't want during a pruning phase.
			neatParameters_PrunePhase.pOffspringAsexual = 1.0;
			neatParameters_PrunePhase.pOffspringSexual = 0.0;

            if (neatParameters.mapelites)
            {
                meInitialisePopulation();
                meGridInit(pop);
                Console.WriteLine("Mapelites stuff has been initialized. Oh btw, we're doing mapelites.");
                if (neatParameters.me_simpleGeneticDiversity)
                {
                    Console.WriteLine("Mapelites reinforced by the power of 51MPLE gENET1C d1VER51TY!!!!1  *fireworks* *applause* *receive phd*");
                }
                if (neatParameters.me_noveltyPressure)
                {
                    Console.WriteLine("Mapelites now with NOVELTY PRESSURE! (>'')>");
                }
            } // Skip all that other stupid shit if we are doing MapElites
            else if (neatParameters.NS2)
            {
                if (neatParameters.NS1) ns1 = true;

                ns2InitializePopulation();
                if (neatParameters.track_me_grid)
                {
                    Console.WriteLine("Initializing mapelites-style-grid genome tracking..");
                    meGridInit(pop);
                }
                Console.WriteLine("Novelty Search 2.0 has been initialized.");
            } // Skip the code jungle below if we are doing Novelty Search 2.0
            else if (neatParameters.NSLC) // (Steady-State NSLC -- NEW!!)
            {
                // TODO: JUSTIN: SS-NSLC GOES HERE!
                ns1 = true;
                ns2InitializePopulation();
                if (neatParameters.track_me_grid)
                {
                    Console.WriteLine("Initializing mapelites-style-grid genome tracking..");
                    meGridInit(pop);
                }
                Console.WriteLine("Initializing STEADY STATE -- NSLC! NEW! This is a thing that is happening now. You cannot stop it. Relax.");
                // TODO: INITIALIZATION for SS-NSLC (is like NS1... but make it separate so we can stop being so intertwined. cleaner is better, yo)


            } // Skip the nasty quagmire of unverified bogus rotten banana sandwiches if doing Steady-State NSLC
            else
            {
                if (neatParameters.multiobjective)
                {
                    this.multiobjective = new Multiobjective.Multiobjective(neatParameters);
                    neatParameters.compatibilityThreshold = 100000000.0; //disable speciation w/ multiobjective
                }

                if (neatParameters.noveltySearch)
                {
                    if (neatParameters.noveltyHistogram)
                    {
                        this.noveltyFixed = new noveltyfixed(neatParameters.archiveThreshold);
                        this.histogram = new noveltyhistogram(neatParameters.histogramBins);
                        noveltyInitialized = true;
                        InitialisePopulation();
                    }

                    if (neatParameters.noveltyFixed || neatParameters.noveltyFloat)
                    {
                        this.noveltyFixed = new noveltyfixed(neatParameters.archiveThreshold);
                        InitialisePopulation();
                        noveltyFixed.initialize(this.pop);
                        noveltyInitialized = true;
                        populationEvaluator.EvaluatePopulation(pop, this);
                        UpdateFitnessStats();
                        DetermineSpeciesTargetSize();
                    }

                    if (neatParameters.track_me_grid)
                    {
                        Console.WriteLine("Initializing mapelites-style-grid genome tracking..");
                        meGridInit(pop); // JUSTIN: Trying to add grid-tracking to NS1
                    }

                }
                else
                {
                    InitialisePopulation();

                    if (neatParameters.track_me_grid)
                    {
                        Console.WriteLine("Initializing mapelites-style-grid genome tracking..");
                        meGridInit(pop); // JUSTIN: Trying to add grid-tracking to fitness-based search
                    }
                }
            }
		}