Ejemplo n.º 1
0
        public IGenome loadNextNetworkFromSelected()
        {
            GenomeList gl = genomeListDictionary[CurrentGenomePool];

            //there is nobody currently selected, send in a rando, or you could always look for historically selected objects, or something like that
            if (gl.Count == 0)
            {
                return(noSelectedNetworks());
            }

            //now we need to choose the parents, we can do sexual or asexual reproduction as well.
            //We can also merge more than 2 parents, but we won't do that for now

            if (gl.Count == 1)
            {
                return(asexualNetwork(gl));
            }
            else
            {
                if (r.NextDouble() < ChanceOfAsexual)
                {
                    return(asexualNetwork(gl));
                }
                else
                {
                    return(sexualNetwork(gl));
                }
            }
        }
Ejemplo n.º 2
0
        public static GenomeList CreateGenomeListAddedInputs(NeatGenome seedGenome, int length, NeatParameters neatParameters, IdGenerator idGenerator)
        {
            //Build the list.
            GenomeList genomeList = new GenomeList();

            // Use the seed directly just once.
            NeatGenome newGenome = new NeatGenome(seedGenome, idGenerator.NextGenomeId);

            //genomeList.Add(newGenome);

            // For the remainder we alter the weights.
            for (int i = 0; i < length; i++)
            {
                newGenome = new NeatGenome(seedGenome, idGenerator.NextGenomeId);

                // Reset the connection weights
                foreach (ConnectionGene connectionGene in newGenome.ConnectionGeneList)
                {
                    connectionGene.Weight = (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0;
                }
                newGenome.ConnectionGeneList.Add(new ConnectionGene(idGenerator.NextInnovationId, 5, newGenome.NeuronGeneList[Utilities.Next(newGenome.NeuronGeneList.Count - 7) + 7].InnovationId, (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0));
                newGenome.ConnectionGeneList.Add(new ConnectionGene(idGenerator.NextInnovationId, 6, newGenome.NeuronGeneList[Utilities.Next(newGenome.NeuronGeneList.Count - 7) + 7].InnovationId, (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0));
                genomeList.Add(newGenome);
            }

            //

            return(genomeList);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a genomeList from a random start, or using a list of seed genome IDs
        /// </summary>
        /// <param name="popSize"></param>
        /// <param name="parentGenomeIDs"></param>
        /// <returns></returns>
        public GenomeList createGenomeList(int popSize, AssessGenotypeFunction genoAssess, List <long> parentGenomeIDs = null)
        {
            //must return a genome list!
            GenomeList gl;

            //if we have parents, add their genomes to our starting genomelist
            if (parentGenomeIDs != null)
            {
                GenomeList seeds = new GenomeList(); seeds.AddRange(getGenomesFromIDs(parentGenomeIDs).Values);
                gl = new GenomeList();
                gl.AddRange(GenomeFactory.CreateGenomeListPreserveIDs(seeds, popSize, neatParams, idgen, genoAssess));
            }
            else
            {
                //we don't have any seeds, we need to form our own initial population
                gl = GenomeFactory.CreateGenomeListPreserveIDs(neatParams, idgen,
                                                               cppnInputs, cppnOutputs, neatParams.pInitialPopulationInterconnections, popSize,
                                                               genoAssess);
            }

            //add each genome to our list of generated genomes, yo.
            //gl.ForEach(genome => allGeneratedGenomes.Add(genome));

            //now we are free to return the genomes
            return(gl);
        }
Ejemplo n.º 4
0
        public static GenomeList CreateGenomeListPreserveIDs(NeatParameters neatParameters, IdGenerator idGenerator,
                                                             int inputNeuronCount, int outputNeuronCount, float connectionProportion, int length, AssessGenotypeFunction assess)
        {
            GenomeList genomeList = new GenomeList();

            int testCount = 0; int maxTests = 5;

            //for (int i = 0; i < length; i++)
            while (genomeList.Count < length)
            {
                IGenome genome = CreateGenomePreserveID(neatParameters, idGenerator, inputNeuronCount, outputNeuronCount, connectionProportion);

                if (assess != null && assess(genome) && testCount++ < maxTests)
                {
                    //after adding the genome, reset test count
                    genomeList.Add(genome);
                    testCount = 0;
                }
                else if (assess == null)
                {
                    genomeList.Add(genome);
                }
                else if (testCount >= maxTests)
                {
                    genomeList.Add(genome);
                    testCount = 0;
                }
            }

            return(genomeList);
        }
Ejemplo n.º 5
0
        public static GenomeList CreateGenomeList(Population seedPopulation, int length, NeatParameters neatParameters, IdGenerator idGenerator)
        {
            //Build the list.
            GenomeList genomeList = new GenomeList();
            int        seedIdx    = 0;

            for (int i = 0; i < length; i++)
            {
                NeatGenome newGenome = new NeatGenome((NeatGenome)seedPopulation.GenomeList[seedIdx], idGenerator.NextGenomeId);

                // Reset the connection weights
                foreach (ConnectionGene connectionGene in newGenome.ConnectionGeneList)
                {
                    connectionGene.Weight = (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0;
                }

                genomeList.Add(newGenome);

                if (++seedIdx >= seedPopulation.GenomeList.Count)
                {                       // Back to first genome.
                    seedIdx = 0;
                }
            }
            return(genomeList);
        }
Ejemplo n.º 6
0
        public EvolutionAlgorithm initializeEvolutionAlgorithm(IPopulationEvaluator popEval, int popSize, AssessGenotypeFunction assess, List <long> parentGenomeIDs = null)
        {
            //have to add our seed to the parents!
            if (officialSeedGenome != null)
            {
                //if we aren't given any parents, make a new list, and add the seed
                if (parentGenomeIDs == null)
                {
                    parentGenomeIDs = new List <long>();
                }

                parentGenomeIDs.Add(officialSeedGenome.GenomeId);
            }

            //create our initial population, using seeds or not, making sure it is at least "popsize" long
            GenomeList gl = createGenomeList(popSize, assess, parentGenomeIDs);

            //now we have a genomelist full of our parents, if they didn't die in a car crash when we were young, yay!
            //also, these parents, their connections, and neurons are safely catalogued by WIN (eventually...)
            Population pop = new Population(idgen, gl);

            //create our algorithm
            evoAlgorithm = new EvolutionAlgorithm(pop, popEval, neatParams, assess);

            createExperimentDirectory();

            //send it away!
            return(evoAlgorithm);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 执行遗传算法
        /// </summary>
        public void Start()
        {
            for (int i = 0; i < maxGenerationSize; i++)
            {
                //更新适应度
                UpdateFitness();
                //按照适应度排序
                GenomeList.Sort();

                ////如果最优个体的适应性度量值=最差个体的适应性度量值
                if (GenomeList.Count == 0 || GenomeList[GenomeList.Count - 1].Fitness == GenomeList[0].Fitness)
                {
                    break;
                }

                //将第解赋值给最优个体
                if (Math.Abs(GenomeList[GenomeList.Count - 1].Fitness) < Math.Abs(GenomeList[0].Fitness))
                {
                    this.bestGenome = GenomeList[0];
                }
                else
                {
                    this.bestGenome = GenomeList[GenomeList.Count - 1];
                }

                //选择复制
                Selection();
                //繁衍子代--交叉
                Breed();
                //变异
                Mutation();
                //将下一代种群重新赋值给种群容器
                GenomeList = nextGenomeList;
            }
        }
Ejemplo n.º 8
0
 public void updatePopulationFitness(GenomeList genomePop)
 {
     for (int i = 0; i < genomePop.Count; i++)
     {
         //we might not need to make copies
         measure_against[i].RealFitness = genomePop[i].RealFitness;
     }
 }
Ejemplo n.º 9
0
 //initialize fixed novelty measure
 public noveltyfixed(double threshold)
 {
     initialized       = false;
     nearest_neighbors = 20;
     archive_threshold = threshold;
     archive           = new GenomeList();
     pending_addition  = new GenomeList();
 }
	    public static void WriteGenomeList(XmlNode parentNode, GenomeList g)
	    {
	        XmlElement xmlPopulation = XmlUtilities.AddElement(parentNode,"population");
	        
			foreach(IGenome genome in g)
			{
				genome.Write(xmlPopulation);
			}
	    }
Ejemplo n.º 11
0
 public Multiobjective(NeatParameters _np)
 {
     np=_np;
     population= new GenomeList();
     ranks=new List<RankInformation>();
     nov = new noveltyfixed(10.0);
     doNovelty=false;
     generation=0;
 }
Ejemplo n.º 12
0
 public Multiobjective(NeatParameters _np)
 {
     np         = _np;
     population = new GenomeList();
     ranks      = new List <RankInformation>();
     nov        = new noveltyfixed(10.0);
     doNovelty  = false;
     generation = 0;
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Transfer genomes from GenomeList into GenomeById.
 /// </summary>
 public void LoadWorkingDictionary()
 {
     GenomeById.Clear();
     foreach (var genome in GenomeList)
     {
         GenomeById.Add(genome.Id, genome);
     }
     GenomeList.Clear();
 }
        public static void WriteGenomeList(XmlNode parentNode, GenomeList g)
        {
            XmlElement xmlPopulation = XmlUtilities.AddElement(parentNode, "population");

            foreach (IGenome genome in g)
            {
                genome.Write(xmlPopulation);
            }
        }
Ejemplo n.º 15
0
        public static Population Read(XmlElement xmlPopulation, IGenomeReader genomeReader, IIdGeneratorFactory idGeneratorFactory)
        {
            GenomeList genomeList = new GenomeList();
            XmlNodeList listGenomes = xmlPopulation.SelectNodes("genome");
            foreach(XmlElement xmlGenome in listGenomes)
                genomeList.Add(genomeReader.Read(xmlGenome));

            IdGenerator idGenerator = idGeneratorFactory.CreateIdGenerator(genomeList);
            return new Population(idGenerator, genomeList);
        }
Ejemplo n.º 16
0
 public Multiobjective(NeatParameters _np)
 {
     np         = _np;
     population = new GenomeList();
     ranks      = new List <RankInformation>();
     nov        = new noveltyfixed(10.0);
     doNovelty  = _np.noveltySearch;
     Console.WriteLine("multiobjective novelty " + doNovelty);
     generation = 0;
 }
Ejemplo n.º 17
0
        public void update_measure(GenomeList p)
        {
            GenomeList total = new GenomeList();

            total.AddRange(p);
            total.AddRange(measure_against);
            total.AddRange(archive);

            merge_together(total, p.Count);
            Console.WriteLine("size: " + Convert.ToString(measure_against.Count));
        }
Ejemplo n.º 18
0
        public GenomeList loadMoreGenomesFromSelected(int count)
        {
            GenomeList gl = new GenomeList();

            for (int i = 0; i < count; i++)
            {
                gl.Add(loadNextNetworkFromSelected());
            }

            return(gl);
        }
Ejemplo n.º 19
0
        public void merge_together(GenomeList list, int size)
        {
            Console.WriteLine("total count: " + Convert.ToString(list.Count));

            Random     r       = new Random();
            GenomeList newList = new GenomeList();

            List <bool>   dirty   = new List <bool>();
            List <double> closest = new List <double>();

            //set default values
            for (int x = 0; x < list.Count; x++)
            {
                dirty.Add(false);
                closest.Add(Double.MaxValue);
            }
            //now add the first individual randomly to the new population
            int last_added = r.Next() % list.Count;

            dirty[last_added] = true;
            newList.Add(list[last_added]);

            while (newList.Count < size)
            {
                double mostNovel      = 0.0;
                int    mostNovelIndex = 0;
                for (int x = 0; x < list.Count; x++)
                {
                    if (dirty[x])
                    {
                        continue;
                    }
                    double dist_to_last = BehaviorDistance.Distance(((NeatGenome.NeatGenome)list[x]).Behavior,
                                                                    ((NeatGenome.NeatGenome)list[last_added]).Behavior);
                    if (dist_to_last < closest[x])
                    {
                        closest[x] = dist_to_last;
                    }

                    if (closest[x] > mostNovel)
                    {
                        mostNovel      = closest[x];
                        mostNovelIndex = x;
                    }
                }

                dirty[mostNovelIndex] = true;
                newList.Add(new NeatGenome.NeatGenome((NeatGenome.NeatGenome)list[mostNovelIndex], 0));
                last_added = mostNovelIndex;
            }

            measure_against = newList;
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Construct a GenomeList. This can be used to construct a new Population object.
        /// </summary>
        /// <param name="evolutionAlgorithm"></param>
        /// <param name="inputNeuronCount"></param>
        /// <param name="outputNeuronCount"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static GenomeList CreateGenomeList(NeatParameters neatParameters, IdGenerator idGenerator, int inputNeuronCount, int outputNeuronCount, float connectionProportion, int length, bool neatBrain = false)
        {
            GenomeList genomeList = new GenomeList();

            for (int i = 0; i < length; i++)
            {
                idGenerator.ResetNextInnovationNumber();
                genomeList.Add(CreateGenome(neatParameters, idGenerator, inputNeuronCount, outputNeuronCount, connectionProportion, neatBrain));
            }

            return(genomeList);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Construct a GenomeList. This can be used to construct a new Population object.
        /// </summary>
        /// <param name="evolutionAlgorithm"></param>
        /// <param name="inputNeuronCount"></param>
        /// <param name="outputNeuronCount"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        // Schrum: Added outputsPerPolicy
        public static GenomeList CreateGenomeList(NeatParameters neatParameters, IdGenerator idGenerator, int inputNeuronCount, int outputNeuronCount, int outputsPerPolicy, float connectionProportion, int length)
        {
            GenomeList genomeList = new GenomeList();

            for (int i = 0; i < length; i++)
            {
                idGenerator.ResetNextInnovationNumber();
                // Schrum: Added outputsPerPolicy
                genomeList.Add(CreateGenome(neatParameters, idGenerator, inputNeuronCount, outputNeuronCount, outputsPerPolicy, connectionProportion));
            }

            return(genomeList);
        }
        public static Population Read(XmlElement xmlPopulation, IGenomeReader genomeReader, IIdGeneratorFactory idGeneratorFactory)
        {
            GenomeList  genomeList  = new GenomeList();
            XmlNodeList listGenomes = xmlPopulation.SelectNodes("genome");

            foreach (XmlElement xmlGenome in listGenomes)
            {
                genomeList.Add(genomeReader.Read(xmlGenome));
            }

            IdGenerator idGenerator = idGeneratorFactory.CreateIdGenerator(genomeList);

            return(new Population(idGenerator, genomeList));
        }
Ejemplo n.º 23
0
        /// <summary>
        /// 更新群体适应度
        /// </summary>
        private void UpdateFitness()
        {
            //计算适应度
            if (fitnessCalculator == null)
            {
                throw new Exception("没有初始化 FitnessFunction 委托");
            }
            foreach (Genome genome in genomeList)
            {
                fitnessCalculator(genome);
            }

            //按照适应度排序
            GenomeList.Sort();
        }
Ejemplo n.º 24
0
        public void initialize(GenomeList p)
        {
            initialized = true;

            measure_against = new GenomeList();

            if (p != null)
            {
                for (int i = 0; i < p.Count; i++)
                {
                    //we might not need to make copies
                    measure_against.Add(new NeatGenome.NeatGenome((NeatGenome.NeatGenome)p[i], 0));
                }
            }
        }
Ejemplo n.º 25
0
        public void initialize(GenomeList p)
        {
            initialized = true;

            measure_against = new GenomeList();

            if (p != null)
            {
                for (int i = 0; i < p.Count; i++)
                {
                    //we might not need to make copies
                    //Paul: removed copies to make it easier to read the realfitness from the indiviudals, without making a million update calls
                    measure_against.Add(p[i]);    //new NeatGenome.NeatGenome((NeatGenome.NeatGenome)p[i],i));
                }
            }
        }
        public static Population Read(XmlElement xmlPopulation, IGenomeReader genomeReader, IIdGeneratorFactory idGeneratorFactory, int index)
        {
            GenomeList genomeList = new GenomeList();
            XmlNodeList listGenomes = xmlPopulation.SelectNodes("genome");
            int i = 0;
            foreach (XmlElement xmlGenome in listGenomes)
            {
                if (i == index)
                {
                    genomeList.Add(genomeReader.Read(xmlGenome));
                    break;
                }
                i++;
            }

            IdGenerator idGenerator = idGeneratorFactory.CreateIdGenerator(genomeList);
            return new Population(idGenerator, genomeList);
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Construct a GenomeList. This can be used to construct a new Population object.
        /// </summary>
        /// <param name="evolutionAlgorithm"></param>
        /// <param name="inputNeuronCount"></param>
        /// <param name="outputNeuronCount"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public GenomeList CreateGenomeList()
        {
            GenomeList genomeList = new GenomeList();

            INetwork cppn;

            foreach (NeatGenome cppnGenome in listOfCppnGenomes)
            {
                // Decode the CPPN genome into a CPPN
                cppn = cppnGenome.Decode(new BipolarSigmoid());

                // Use the CPPN in tandem with the HyperNEAT substrate to generate a genome for the controller
                // and add the controller's genome to the genome list
                genomeList.Add(Chromaria.Simulator.controllerSubstrate.generateGenome(cppn));
            }

            return(genomeList);
        }
Ejemplo n.º 28
0
        /// <summary>
        /// What we do when we want asexual reproduction from a collection of genomes
        /// </summary>
        /// <param name="potentials"></param>
        /// <returns></returns>
        private IGenome asexualNetwork(GenomeList potentials)
        {
            //select a random genome for asexual reprodcution
            IGenome genome = randomGenome(potentials);

            //make note of any new additions, we'll have to verify this with the WIN server in some fashion
            //in the future, we will need to do something with this information, for now, that's not necessarily an issue
            Hashtable newConnectionTable = new Hashtable();
            Hashtable newNeuronGeneTable = new Hashtable();

            //shazam, create an asexual genome
            IGenome offspring = ((NeatGenome.NeatGenome)genome).CreateOffspring_Asexual(neatParams, idgen, newNeuronGeneTable, newConnectionTable);

            //make sure to note this in our evolution manager (that we created this object)
            //allGeneratedGenomes.Add(offspring);

            //after noting its creation, we return
            return(offspring);
        }
Ejemplo n.º 29
0
        //currently not used, calculates genomic novelty objective for protecting innovation
        //uses a rough characterization of topology, i.e. number of connections in the genome
        public void calculateGenomicNovelty(GenomeList measureUs)
        {
            double sum      = 0.0;
            int    max_conn = 0;

            foreach (IGenome x in measureUs)
            {
                double minDist = 10000000.0;

                NeatGenome.NeatGenome xx = (NeatGenome.NeatGenome)x;
                double        difference = 0.0;
                double        delta      = 0.0;
                List <double> distances  = new List <double>();
                if (xx.ConnectionGeneList.Count > max_conn)
                {
                    max_conn = xx.ConnectionGeneList.Count;
                }
                //int ccount=xx.ConnectionGeneList.Count;
                foreach (IGenome y in measureUs)
                {
                    if (x == y)
                    {
                        continue;
                    }
                    NeatGenome.NeatGenome yy = (NeatGenome.NeatGenome)y;
                    double d = xx.compat(yy, np);
                    //if(d<minDist)
                    //	minDist=d;
                    distances.Add(d);
                }
                distances.Sort();
                int    sz        = Math.Min(distances.Count, 10);
                double diversity = 0.0;
                for (int i = 0; i < sz; i++)
                {
                    diversity += distances[i];
                }
                //xx.objectives[xx.objectives.Length-1] = diversity;
                xx.geneticDiversity = diversity;
                sum += diversity;
            }
            //Console.WriteLine("Diversity: " + sum/population.Count + " " + max_conn);
        }
Ejemplo n.º 30
0
        /// <summary>
        /// What we do when we want to choose at least 2 parents to mate
        /// </summary>
        /// <param name="potentials"></param>
        /// <returns></returns>
        private IGenome sexualNetwork(GenomeList potentials)
        {
            IGenome parent1 = randomGenome(potentials);
            IGenome parent2 = randomGenome(potentials);

            int attemptCount = 0;

            //make sure you aren't combining the same individual
            while (parent1 == parent2 && attemptCount++ < maxRandomAttempts)
            {
                parent2 = randomGenome(potentials);
            }

            //make babies directly with parent1 and parent2
            //We'll need to make note of these changes as well in WIN -- not sure where to store this location
            IGenome genome = ((NeatGenome.NeatGenome)parent1).CreateOffspring_Sexual(neatParams, idgen, parent2);

            //allGeneratedGenomes.Add(genome);

            return(genome);
        }
Ejemplo n.º 31
0
 /// <summary>
 /// Random genome from a genomelist, simple function helper to call
 /// </summary>
 /// <param name="potentials"></param>
 /// <returns></returns>
 private IGenome randomGenome(GenomeList potentials)
 {
     return potentials[r.Next(potentials.Count)];
 }
Ejemplo n.º 32
0
		/// <summary>
		/// Create an IdGeneratoy by interrogating the provided population of Genomes.
		/// This routine also fixes any duplicate IDs that are found in the
		/// population.
		/// </summary>
		/// <param name="pop"></param>
		/// <returns></returns>
		public IdGenerator CreateIdGenerator(GenomeList genomeList)
		{
			uint maxGenomeId=0;
			uint maxInnovationId=0;

			// First pass: Determine the current maximum genomeId and innovationId.
			foreach(NeatGenome genome in genomeList)
			{
				if(genome.GenomeId > maxGenomeId)
					maxGenomeId = genome.GenomeId;

				// Neuron IDs actualy come from the innovation IDs generator, so although they 
				// aren't used as historical markers we should count them as innovation IDs here.
				foreach(NeuronGene neuronGene in genome.NeuronGeneList)
				{
					if(neuronGene.InnovationId > maxInnovationId)
						maxInnovationId = neuronGene.InnovationId;
				}

				foreach(ConnectionGene connectionGene in genome.ConnectionGeneList)
				{
					if(connectionGene.InnovationId > maxInnovationId)
						maxInnovationId = connectionGene.InnovationId;
				}
			}

			if(maxGenomeId==uint.MaxValue)
			{	 //reset to zero.
				maxGenomeId=0;
			}
			else
			{	// Increment to next available ID.
				maxGenomeId++;
			}

			if(maxInnovationId==uint.MaxValue)
			{	 //reset to zero.
				maxInnovationId=0;
			}
			else
			{	// Increment to next available ID.
				maxInnovationId++;
			}

			// Create an IdGenerator using the discovered maximum IDs.
			IdGenerator idGenerator = new IdGenerator(maxGenomeId, maxInnovationId);

			// Second pass: Check for duplicate genome IDs.
			Hashtable genomeIdTable = new Hashtable();
			Hashtable innovationIdTable = new Hashtable();
			foreach(NeatGenome genome in genomeList)
			{
				if(genomeIdTable.Contains(genome.GenomeId))
				{	// Assign this genome a new Id.
					genome.GenomeId = idGenerator.NextGenomeId;
				}
				//Register the ID.
				genomeIdTable.Add(genome.GenomeId, null);
			}
						
			return idGenerator;
		}
        // Dump the contents of the ME Grid to a GenomeList (e.g. for printing at the end of a run)
        //  (should be okay to call this even if grid is empty, e.g. not doing MapElites)
        // MAPELITES TODO: add a "grid location" property (some coordinates) to all genomes so that when we save the grid, it can be easily reconstructed, visually. this will be junk if not using MapElites. w/e
        public GenomeList meDumpGrid()
        {
            GenomeList rval = new GenomeList();
            IGenome[] allgenomes = new IGenome[meGrid.Count];
            meGrid.Values.CopyTo(allgenomes, 0);

            foreach (IGenome g in allgenomes)
            {
                rval.Add(g);
            }

            return rval;
        }
Ejemplo n.º 34
0
		public Multiobjective (NeatParameters _np)
		{
			np=_np;
			population= new GenomeList();
			ranks=new List<RankInformation>();
			nov = new noveltyfixed(10.0);
			doNovelty=_np.noveltySearch;
			Console.WriteLine("multiobjective novelty " + doNovelty);
			generation=0;
		}
Ejemplo n.º 35
0
        public static GenomeList CreateGenomeListPreserveIDs(NeatParameters neatParameters, IdGenerator idGenerator, 
            int inputNeuronCount, int outputNeuronCount, float connectionProportion, int length, AssessGenotypeFunction assess)
        {
            GenomeList genomeList = new GenomeList();

            int testCount = 0; int maxTests = 5;

            //for (int i = 0; i < length; i++)
            while(genomeList.Count < length)
            {
                    IGenome genome = CreateGenomePreserveID(neatParameters, idGenerator, inputNeuronCount, outputNeuronCount, connectionProportion);

                    if (assess != null && assess(genome) && testCount++ < maxTests)
                    {
                        //after adding the genome, reset test count
                        genomeList.Add(genome);
                        testCount = 0;
                    }
                    else if (assess == null)
                        genomeList.Add(genome);
                    else if (testCount >= maxTests)
                    {
                        genomeList.Add(genome);
                        testCount = 0;
                    }
            }

            return genomeList;
        }
Ejemplo n.º 36
0
        public static GenomeList CreateGenomeListPreserveIDs(GenomeList seedGenomes, int length, NeatParameters neatParameters, IdGenerator idGenerator, AssessGenotypeFunction assess)
        {
            //Eventually, WIN will be brought in to maintain the genomes, for now, no need

            //Build the list.
            GenomeList genomeList = new GenomeList();

            if (length < seedGenomes.Count)
                throw new Exception("Attempting to generate a population that is smaller than the number of seeds (i.e. some seeds will be lost). Please change pop size to accomodate for all seeds.");
            NeatGenome newGenome;

            for (int i = 0; i < seedGenomes.Count; i++)
            {
                // Use each seed directly just once.
                newGenome = new NeatGenome((NeatGenome)seedGenomes[i], idGenerator.NextGenomeId);
                genomeList.Add(newGenome);
            }

            int testCount = 0; int maxTests = 5;

            // For the remainder we alter the weights.
            //for (int i = 1; i < length; i++)
            //{
            while (genomeList.Count < length)
            {
                newGenome = new NeatGenome((NeatGenome)seedGenomes[Utilities.Next(seedGenomes.Count)], idGenerator.NextGenomeId);

                // Reset the connection weights

                //in this particular instance, we would take a snapshot of the genome AFTER mutation for WIN purposes. But we don't track genomes yet
                foreach (ConnectionGene connectionGene in newGenome.ConnectionGeneList)
                    connectionGene.Weight += (0.1 - Utilities.NextDouble() * 0.2);

                //!connectionGene.Weight = (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange/2.0;
                //Console.WriteLine((0.1 - Utilities.NextDouble() * 0.2));
                //newGenome.ConnectionGeneList.Add(new ConnectionGene(idGenerator.NextInnovationId,5,newGenome.NeuronGeneList[Utilities.Next(newGenome.NeuronGeneList.Count-7)+7].InnovationId ,(Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange/2.0));
                //newGenome.ConnectionGeneList.Add(new ConnectionGene(idGenerator.NextInnovationId, 6, newGenome.NeuronGeneList[Utilities.Next(newGenome.NeuronGeneList.Count - 7) + 7].InnovationId, (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0));
                //if we have an assess function, it should be used for generating this individual!

                if (assess != null && assess(newGenome) && testCount++ < maxTests)
                {
                    //after adding the genome, reset test count
                    genomeList.Add(newGenome);
                    testCount = 0;
                }
                else if (assess == null)
                    genomeList.Add(newGenome);
                else if (testCount >= maxTests)
                {
                    genomeList.Add(newGenome);
                    testCount = 0;
                }
            }

            //

            return genomeList;
        }
Ejemplo n.º 37
0
        public GenomeList loadMoreGenomesFromSelected(int count)
        {
            GenomeList gl = new GenomeList();

            for (int i = 0; i < count; i++)
                gl.Add(loadNextNetworkFromSelected());

            return gl;
        }
Ejemplo n.º 38
0
        /// <summary>
        /// What we do when we want to choose at least 2 parents to mate
        /// </summary>
        /// <param name="potentials"></param>
        /// <returns></returns>
        private IGenome sexualNetwork(GenomeList potentials)
        {
            IGenome parent1 = randomGenome(potentials);
            IGenome parent2 = randomGenome(potentials);

            int attemptCount = 0;
            //make sure you aren't combining the same individual
            while (parent1 == parent2 && attemptCount++ < maxRandomAttempts)
            {
                parent2 = randomGenome(potentials);
            }

            //make babies directly with parent1 and parent2
            //We'll need to make note of these changes as well in WIN -- not sure where to store this location
            IGenome genome =  ((NeatGenome.NeatGenome)parent1).CreateOffspring_Sexual(neatParams, idgen, parent2);

            //allGeneratedGenomes.Add(genome);

            return genome;
        }
Ejemplo n.º 39
0
		/// <summary>
		/// Construct a GenomeList. This can be used to construct a new Population object.
		/// </summary>
		/// <param name="evolutionAlgorithm"></param>
		/// <param name="inputNeuronCount"></param>
		/// <param name="outputNeuronCount"></param>
		/// <param name="length"></param>
		/// <returns></returns>
		public static GenomeList CreateGenomeList(NeatParameters neatParameters, IdGenerator idGenerator, int inputNeuronCount, int outputNeuronCount, float connectionProportion, int length, bool neatBrain=false)
		{
			GenomeList genomeList = new GenomeList();
			
			for(int i=0; i<length; i++)
			{
				idGenerator.ResetNextInnovationNumber();
				genomeList.Add(CreateGenome(neatParameters, idGenerator, inputNeuronCount, outputNeuronCount, connectionProportion, neatBrain));
			}

			return genomeList;
		}
Ejemplo n.º 40
0
        public void ResetPopulation(GenomeList l, EvolutionAlgorithm ea)
        {
            speciesToRemove.Clear();

            foreach(Species species in speciesTable.Values)
            {
                speciesToRemove.Add(species.SpeciesId);
            }

            int speciesBound=speciesToRemove.Count;
            for(int speciesIdx=0; speciesIdx<speciesBound; speciesIdx++)
                speciesTable.Remove(speciesToRemove[speciesIdx]);

            for(int i=0;i<l.Count;i++)
                this.AddGenomeToPopulation(ea,l[i]);

            this.RebuildGenomeList();
        }
Ejemplo n.º 41
0
 /// <summary>
 /// CPPNGenomeFactory constructor. Used to generate a minimal CPPN
 /// </summary>
 /// <param name="neatParameters"></param>
 /// <param name="idGenerator"></param>
 /// <param name="inputNeuronCount"></param>
 /// <param name="outputNeuronCount"></param>
 /// <param name="connectionProportion"></param>
 public CPPNGenomeFactory(NeatParameters neatParameters, IdGenerator idGenerator, int inputNeuronCount, int outputNeuronCount, float connectionProportion)
 {
     cppnGenerator     = new GenomeFactory();
     listOfCppnGenomes = cppnGenerator.CreateGenomeList(neatParameters, idGenerator, inputNeuronCount, outputNeuronCount, connectionProportion, Chromaria.Simulator.populationSize);
 }
Ejemplo n.º 42
0
        /// <summary>
        /// This function contains all of the pre-run logic that doesn't involve graphics.
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();

            // Create the world / region system
            // Note: The morphology must be generated in advance of the Load
            INetwork morphologyCPPN = loadCPPNFromXml(initialMorphologyFilename).Decode(ActivationFunctionFactory.GetActivationFunction("BipolarSigmoid"));

            morphology = generateMorphology(morphologyCPPN);
            redTexture = generateSolidMorphology(morphology);
            InitializeRegions();

            // Initialize a log to track some instance-specific data
            using (System.IO.StreamWriter file = new System.IO.StreamWriter("RunInfo.txt", true))
            {
                file.WriteLine("Novelty search run");
                file.WriteLine("Start time: " + DateTime.Now.ToString("HH:mm:ss tt"));
                if (freezeAfterPlanting)
                {
                    file.WriteLine("Individuals are immobilized once they attempt to plant.");
                }
                else
                {
                    file.WriteLine("Individuals are allowed to keep moving even if/after they attempt to plant.");
                }
                file.WriteLine("Morphology genome XML filename: " + initialControllerFilename);
                file.WriteLine("Behavior update interval: " + behaviorUpdateInterval);
                file.WriteLine("Planting weight: " + plantingWeight);
                file.WriteLine("Position weight: " + positionWeight);
                file.WriteLine("Population size: " + populationSize);
                file.WriteLine("Archive threshold: " + archiveThreshold);
            }

            // Initialize some static variables for the simulation
            numBidirectionalPlanters    = 0;
            numFirstTrialPlanters       = 0;
            numSecondTrialPlanters      = 0;
            numBidirectionalMisplanters = 0;
            numFirstTrialMisplanters    = 0;
            numSecondTrialMisplanters   = 0;
            firstTrial = true;

            // Set the NEAT parameters
            neatParams = new NeatParameters();
            neatParams.archiveThreshold = archiveThreshold;
            neatParams.noveltyFixed     = true;
            neatParams.noveltySearch    = true;

            // Configure the HyperNEAT substrate
            controllerSubstrate             = new ControllerSubstrate(308, 4, 108, new BipolarSigmoid());
            controllerSubstrate.weightRange = 5.0;
            controllerSubstrate.threshold   = 0.2;

            // Create a genome factory to generate a list of CPPN genomes
            cppnGenerator  = new GenomeFactory();
            idGen          = new IdGenerator();
            cppnGenomeList = cppnGenerator.CreateGenomeList(neatParams, idGen, 4, 8, 1.0f, populationSize);
            GenomeIndexOfCurrentCreature = 0;

            // Initialize the folders for storing the archive and planters
            noveltyLogsFolder = Directory.GetCurrentDirectory() + "\\archive\\" + GenomeIndexOfCurrentCreature + "\\";
            if (!Directory.Exists(noveltyLogsFolder))
            {
                Directory.CreateDirectory(noveltyLogsFolder);
            }
            plantersFolder = Directory.GetCurrentDirectory() + "\\planters\\" + GenomeIndexOfCurrentCreature + "\\";
            if (!Directory.Exists(plantersFolder))
            {
                Directory.CreateDirectory(plantersFolder);
            }

            // Create an initial population based on the genome list
            popn = new Population(idGen, cppnGenomeList);

            // Set the generation counter
            // Note: This must be kept seperately from the EA generation counter because novelty search here does't follow the traditional loop.
            generation = 1;

            // Create the EA
            // (Don't run the EA until the first generation has had a chance to go through the simulation.
            // The EA call happens in Simulator.NewGeneration().)
            ea = new EvolutionAlgorithm(popn, new ChromariaPopulationEvaluator(new ChromariaNetworkEvaluator()), neatParams);

            // Initialize the behavior trackers for this individual
            ea.Population.GenomeList[GenomeIndexOfCurrentCreature].Behavior = new BehaviorType();
            ea.Population.GenomeList[GenomeIndexOfCurrentCreature].Behavior.behaviorList = new List <double>();

            // Generate the initial creature
            int      x             = initialBoardWidth / 2;
            int      y             = initialBoardHeight / 2;
            INetwork newController = controllerSubstrate.generateGenome(ea.Population.GenomeList[GenomeIndexOfCurrentCreature].Decode(ActivationFunctionFactory.GetActivationFunction("BipolarSigmoid"))).Decode(ActivationFunctionFactory.GetActivationFunction("BipolarSigmoid"));

            if (bidirectionalTrials)
            {
                currentCreature = new NNControlledCreature(morphology, x, y, initialHeading + (float)(Math.PI / 2.0), newController, this, drawSensorField, trackPlanting, defaultNumSensors, freezeAfterPlanting);
            }
            else
            {
                currentCreature = new NNControlledCreature(morphology, x, y, initialHeading, newController, this, drawSensorField, trackPlanting, defaultNumSensors, freezeAfterPlanting);
            }
            currentCreature.DrawOrder = 1;
            indexOfCurrentCreature    = Components.Count - 1;

            // Add the creature to the simulator's region lists
            int currentPointer = Components.Count - 1;

            regions[y / regionHeight, x / regionWidth].Add(currentPointer);
            if ((x % regionWidth > (x + morphology.Width) % regionWidth) && (y % regionHeight > (y + morphology.Height) % regionHeight) && !regions[(y + morphology.Height) / regionHeight, (x + morphology.Width) / regionWidth].Contains(currentPointer))
            {
                regions[(y + morphology.Height) / regionHeight, (x + morphology.Width) / regionWidth].Add(currentPointer);
            }
            if (x % regionWidth > (x + morphology.Width) % regionWidth && !regions[(y / regionHeight), (x + morphology.Width) / regionWidth].Contains(currentPointer))
            {
                regions[(y / regionHeight), (x + morphology.Width) / regionWidth].Add(currentPointer);
            }
            if (y % regionHeight > (y + morphology.Height) % regionHeight && !(regions[(y + morphology.Height) / regionHeight, x / regionWidth].Contains(currentPointer)))
            {
                regions[(y + morphology.Height) / regionHeight, x / regionWidth].Add(currentPointer);
            }

            // Preliminarily update the creature's sensors so its first movements are actually based on what's underneath its starting position
            currentCreature.InitializeSensor();

            plantedInColoredSpace1 = false;
            plantedInColoredSpace2 = false;
            plantedInWhiteSpace1   = false;
            plantedInWhiteSpace2   = false;
            numUpdates             = 0;
        }
        /// <summary>
        /// Create an IdGeneratoy by interrogating the provided population of Genomes.
        /// This routine also fixes any duplicate IDs that are found in the
        /// population.
        /// </summary>
        /// <param name="pop"></param>
        /// <returns></returns>
        public IdGenerator CreateIdGenerator(GenomeList genomeList)
        {
            uint maxGenomeId     = 0;
            uint maxInnovationId = 0;

            // First pass: Determine the current maximum genomeId and innovationId.
            foreach (NeatGenome genome in genomeList)
            {
                if (genome.GenomeId > maxGenomeId)
                {
                    maxGenomeId = genome.GenomeId;
                }

                // Neuron IDs actualy come from the innovation IDs generator, so although they
                // aren't used as historical markers we should count them as innovation IDs here.
                foreach (NeuronGene neuronGene in genome.NeuronGeneList)
                {
                    if (neuronGene.InnovationId > maxInnovationId)
                    {
                        maxInnovationId = neuronGene.InnovationId;
                    }
                }

                foreach (ConnectionGene connectionGene in genome.ConnectionGeneList)
                {
                    if (connectionGene.InnovationId > maxInnovationId)
                    {
                        maxInnovationId = connectionGene.InnovationId;
                    }
                }
            }

            if (maxGenomeId == uint.MaxValue)
            {                    //reset to zero.
                maxGenomeId = 0;
            }
            else
            {                   // Increment to next available ID.
                maxGenomeId++;
            }

            if (maxInnovationId == uint.MaxValue)
            {                    //reset to zero.
                maxInnovationId = 0;
            }
            else
            {                   // Increment to next available ID.
                maxInnovationId++;
            }

            // Create an IdGenerator using the discovered maximum IDs.
            IdGenerator idGenerator = new IdGenerator(maxGenomeId, maxInnovationId);

            // Second pass: Check for duplicate genome IDs.
            Hashtable genomeIdTable     = new Hashtable();
            Hashtable innovationIdTable = new Hashtable();

            foreach (NeatGenome genome in genomeList)
            {
                if (genomeIdTable.Contains(genome.GenomeId))
                {                       // Assign this genome a new Id.
                    genome.GenomeId = idGenerator.NextGenomeId;
                }
                //Register the ID.
                genomeIdTable.Add(genome.GenomeId, null);
            }

            return(idGenerator);
        }
Ejemplo n.º 44
0
 /// <summary>
 /// Transfer genomes from GenomeById into GenomeList.
 /// </summary>
 public void FlushWorkingDictionary()
 {
     GenomeList.Clear();
     GenomeList.AddRange(GenomeById.Values);
     GenomeById.Clear();
 }
Ejemplo n.º 45
0
        /// <summary>
        /// What we do when we want asexual reproduction from a collection of genomes
        /// </summary>
        /// <param name="potentials"></param>
        /// <returns></returns>
        private IGenome asexualNetwork(GenomeList potentials)
        {
            //select a random genome for asexual reprodcution
            IGenome genome = randomGenome(potentials);

            //make note of any new additions, we'll have to verify this with the WIN server in some fashion
            //in the future, we will need to do something with this information, for now, that's not necessarily an issue
            Hashtable newConnectionTable = new Hashtable();
            Hashtable newNeuronGeneTable = new Hashtable();

            //shazam, create an asexual genome
            IGenome offspring = ((NeatGenome.NeatGenome)genome).CreateOffspring_Asexual(neatParams, idgen, newNeuronGeneTable, newConnectionTable);

            //make sure to note this in our evolution manager (that we created this object)
            //allGeneratedGenomes.Add(offspring);

            //after noting its creation, we return
            return offspring;
        }
Ejemplo n.º 46
0
        public static GenomeList CreateGenomeListAddedInputs(NeatGenome seedGenome, int length, NeatParameters neatParameters, IdGenerator idGenerator)
        {
            //Build the list.
            GenomeList genomeList = new GenomeList();

            // Use the seed directly just once.
            NeatGenome newGenome = new NeatGenome(seedGenome, idGenerator.NextGenomeId);
            //genomeList.Add(newGenome);

            // For the remainder we alter the weights.
            for (int i = 0; i < length; i++)
            {
                newGenome = new NeatGenome(seedGenome, idGenerator.NextGenomeId);

                // Reset the connection weights
                foreach (ConnectionGene connectionGene in newGenome.ConnectionGeneList)
                    connectionGene.Weight = (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0;
                newGenome.ConnectionGeneList.Add(new ConnectionGene(idGenerator.NextInnovationId, 5, newGenome.NeuronGeneList[Utilities.Next(newGenome.NeuronGeneList.Count - 7) + 7].InnovationId, (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0));
                newGenome.ConnectionGeneList.Add(new ConnectionGene(idGenerator.NextInnovationId, 6, newGenome.NeuronGeneList[Utilities.Next(newGenome.NeuronGeneList.Count - 7) + 7].InnovationId, (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0));
                genomeList.Add(newGenome);
            }

            //

            return genomeList;
        }
Ejemplo n.º 47
0
        /// <summary>
        /// Creates a genomeList from a random start, or using a list of seed genome IDs
        /// </summary>
        /// <param name="popSize"></param>
        /// <param name="parentGenomeIDs"></param>
        /// <returns></returns>
        public GenomeList createGenomeList(int popSize, AssessGenotypeFunction genoAssess, List<long> parentGenomeIDs = null)
        {
            //must return a genome list!
            GenomeList gl;

            //if we have parents, add their genomes to our starting genomelist
            if (parentGenomeIDs != null)
            {
                GenomeList seeds = new GenomeList(); seeds.AddRange(getGenomesFromIDs(parentGenomeIDs).Values);
                gl = new GenomeList();
                gl.AddRange(GenomeFactory.CreateGenomeListPreserveIDs(seeds, popSize, neatParams, idgen, genoAssess));
            }
            else
            {
                //we don't have any seeds, we need to form our own initial population
                gl = GenomeFactory.CreateGenomeListPreserveIDs(neatParams, idgen,
                    cppnInputs, cppnOutputs, neatParams.pInitialPopulationInterconnections, popSize,
                    genoAssess);
            }

            //add each genome to our list of generated genomes, yo.
            //gl.ForEach(genome => allGeneratedGenomes.Add(genome));

            //now we are free to return the genomes
            return gl;
        }
Ejemplo n.º 48
0
		public static GenomeList CreateGenomeList(Population seedPopulation, int length, NeatParameters neatParameters, IdGenerator idGenerator)
		{
			//Build the list.
			GenomeList genomeList = new GenomeList();
			int seedIdx=0;
			
			for(int i=0; i<length; i++)
			{
				NeatGenome newGenome = new NeatGenome((NeatGenome)seedPopulation.GenomeList[seedIdx], idGenerator.NextGenomeId);

				// Reset the connection weights
				foreach(ConnectionGene connectionGene in newGenome.ConnectionGeneList)
					connectionGene.Weight = (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange/2.0;

				genomeList.Add(newGenome);

				if(++seedIdx >= seedPopulation.GenomeList.Count)
				{	// Back to first genome.
					seedIdx=0;
				}
			}
			return genomeList;
		}
Ejemplo n.º 49
0
		/// <summary>
		/// Construct a GenomeList. This can be used to construct a new Population object.
		/// </summary>
		/// <param name="evolutionAlgorithm"></param>
		/// <param name="inputNeuronCount"></param>
		/// <param name="outputNeuronCount"></param>
		/// <param name="length"></param>
		/// <returns></returns>
        // Schrum: Added outputsPerPolicy
        public static GenomeList CreateGenomeList(NeatParameters neatParameters, IdGenerator idGenerator, int inputNeuronCount, int outputNeuronCount, int outputsPerPolicy, float connectionProportion, int length)
		{
			GenomeList genomeList = new GenomeList();
			
			for(int i=0; i<length; i++)
			{
				idGenerator.ResetNextInnovationNumber();
                // Schrum: Added outputsPerPolicy
				genomeList.Add(CreateGenome(neatParameters, idGenerator, inputNeuronCount, outputNeuronCount, outputsPerPolicy, connectionProportion));
			}

			return genomeList;
		}
Ejemplo n.º 50
0
 public Population(IdGenerator idGenerator, GenomeList genomeList)
 {
     this.idGenerator = idGenerator;
     this.genomeList = genomeList;
     this.populationSize = genomeList.Count;
 }
Ejemplo n.º 51
0
		//currently not used, calculates genomic novelty objective for protecting innovation
		//uses a rough characterization of topology, i.e. number of connections in the genome
		public void calculateGenomicNovelty(GenomeList measureUs) {
			double sum=0.0;
			int max_conn = 0;
		     foreach(IGenome x in measureUs) {
				    double minDist=10000000.0;

				    NeatGenome.NeatGenome xx = (NeatGenome.NeatGenome)x;
		    	    double difference=0.0;
				    double delta=0.0;
				    List<double> distances=new List<double>();
				    if(xx.ConnectionGeneList.Count > max_conn)
					    max_conn = xx.ConnectionGeneList.Count;
			    //int ccount=xx.ConnectionGeneList.Count;
			    foreach(IGenome y in measureUs) {
					if (x == y) continue;
                    NeatGenome.NeatGenome yy = (NeatGenome.NeatGenome)y;
				    double d = xx.compat(yy,np);
				    //if(d<minDist)
				    //	minDist=d;
				    distances.Add(d);
			    }
			    distances.Sort();
			    int sz=Math.Min(distances.Count,10);
			    double diversity=0.0;
			    for(int i=0;i<sz;i++)
				    diversity+=distances[i];
			    //xx.objectives[xx.objectives.Length-1] = diversity;
                xx.geneticDiversity = diversity;
			    sum+=diversity;
		    }
			//Console.WriteLine("Diversity: " + sum/population.Count + " " + max_conn);
		}
        public void PerformOneGeneration()
		{
            // JUSTIN: IF WE ARE DOING MAPELITES, BAIL AND DO THE MAPELITES CHAIN INSTEAD!
            if (neatParameters.mapelites)
            {
                mePerformOneGeneration();
                return;
            }

            // JUSTIN: IF WE ARE DOING NOVELTY SEARCH 2.0, BAIL AND DO THE NS2 CHAIN INSTEAD!
            if (neatParameters.NS2)
            {
                ns2PerformOneGeneration();
                return;
            }

            // JUSTIN: IF WE ARE DOING SS-NSLC, BAIL AND DO THE SS-NSLC CHAIN INSTEAD!
            if (neatParameters.NSLC)
            {
                nslcPerformOneGeneration(); // TODO: JUSTIN: IMPLEMENT THIS, OKAY.
                return;
            }


            // If we are tracking a ME-style grid, we have to insert the freshly-evaluated population ("batch") here, before any further processing.
            // Note: This takes negligible time.
            if (neatParameters.track_me_grid)
            {
                // Insert population into ME Grid
                
                foreach (IGenome g in pop.GenomeList)
                {
                    (g as AbstractGenome).GridCoords = bcToBinCoordinates(g.Behavior.behaviorList).ToArray();
                    UInt64 coord = cantorPairing(bcToBinCoordinates(g.Behavior.behaviorList));
                    if (!meGrid.ContainsKey(coord))
                    { // If this grid slot is empty, just go ahead and add the genome
                        meGrid[coord] = g;
                    }
                    else
                    { // If it's not empty, replace only if g has higher fitness
                        if (g.RealFitness > meGrid[coord].RealFitness)
                        { // It's higher fitness, good. Replace with the higher fit individual.
                            meGrid[coord] = g;
                        }
                        else
                        { // So sad

                        }
                    }
                }
            }






		//----- Elmininate any poor species before we do anything else. These are species with a zero target
		//		size for this generation and will therefore not have generate any offspring. Here we have to 
		//		explicitly eliminate these species, otherwise the species would persist because of elitism. 
		//		Also, the species object would persist without any genomes within it, so we have to clean it up.
		//		This code could be executed at the end of this method instead of the start, it doesn't really 
		//		matter. Except that If we do it here then the population size will be relatively constant
		//		between generations.

			/*if(pop.EliminateSpeciesWithZeroTargetSize())
			{	// If species were removed then we should recalculate population stats.
				UpdateFitnessStats();
				DetermineSpeciesTargetSize();
			}*/

		//----- Stage 1. Create offspring / cull old genomes / add offspring to population.
			bool regenerate = false;
			if(neatParameters.noveltySearch && neatParameters.noveltyFixed)
            {
                if((generation+1)%20==0)
                {
                    this.noveltyFixed.add_most_novel(pop);
                    this.noveltyFixed.update_measure(pop);
                    pop.ResetPopulation(noveltyFixed.measure_against,this);
                    pop.RedetermineSpeciation(this);
                    regenerate=true;
                }
            }

            /*for (int i = 0; i < pop.GenomeList.Count; i++)
            {
                Console.Write("!BehaviorList! ");
                foreach (double argh in pop.GenomeList[i].objectives)
                {
                    Console.Write(argh + " ");
                }
                Console.WriteLine();
            }//*/ // For some reason this crashes.. maybe there is no objectives list???

            /*Console.Write("localGenomeNovelty: ");
            foreach (IGenome g in pop.GenomeList) Console.Write(g.localGenomeNovelty + " ");
            Console.WriteLine();
            Console.Write("competition: ");
            foreach (IGenome g in pop.GenomeList) Console.Write(g.competition + " ");
            Console.WriteLine();
            Console.Write("nearestNeighbors: ");
            foreach (IGenome g in pop.GenomeList) Console.Write(g.nearestNeighbors + " ");
            Console.WriteLine();//*/

            
			if(neatParameters.multiobjective) {
                // JUSTIN: I hope this fixes it..
                if (neatParameters.noveltySearch)
                { // We are doing multiobjective novelty search, presumably NS+LC.
                    //Console.WriteLine("Adding in the NS+LC objectives"); // Add in the extra objectives (see comments below)
                    foreach (IGenome g in pop.GenomeList)
                    {
                        g.objectives = new double[6];
                        int len = g.objectives.Length;
                        //g.objectives[len - 5] = g.geneticDiversity;
                        g.objectives[len - 4] = g.RealFitness;
                        //g.objectives[len - 3] = g.competition / g.nearestNeighbors; // Local competition objective (based on real fitness)
                        g.objectives[len - 2] = g.Fitness + 0.001; // Novelty objective
                        //g.objectives[len - 1] = g.localGenomeNovelty / g.nearestNeighbors; // Local genetic diversity objective (does this work?)
                        //foreach (double d in g.objectives) Console.Write(d + " "); Console.WriteLine();
                    }
                    //Console.WriteLine("Completed adding NS+LC objectives with no problems. (" + pop.GenomeList.Count + " members)");
                }

                //Console.WriteLine("pop=" + pop.GenomeList.Count + "popMO=" + multiobjective.population.Count);
                /*foreach (IGenome g in multiobjective.population)
                {
                    Console.Write("MO_OldPop: ");
                    Console.Write(g.Fitness + " : [" + g.RealFitness + "] : ");
                    foreach (double d in g.objectives) Console.Write(d + " ");
                    Console.WriteLine();
                }//*/
                multiobjective.addPopulation(pop);
                //Console.WriteLine("pop2=" + pop.GenomeList.Count + "pop2MO=" + multiobjective.population.Count);
                /*foreach (IGenome g in multiobjective.population)
                {
                    Console.Write("MO_NewPop: ");
                    Console.Write(g.Fitness + " : [" + g.RealFitness + "] : ");
                    foreach (double d in g.objectives) Console.Write(d + " ");
                    Console.WriteLine();
                }//*/
                multiobjective.rankGenomes();
                //Console.WriteLine("pop3=" + pop.GenomeList.Count + "pop3MO=" + multiobjective.population.Count);
                /*foreach (IGenome g in multiobjective.population)
                {
                    Console.Write("MO_AfterRankingPop: ");
                    Console.Write(g.Fitness + " : [" + g.RealFitness + "] : ");
                    foreach (double d in g.objectives) Console.Write(d + " ");
                    Console.WriteLine();
                }//*/
                /*foreach (IGenome aye in pop.GenomeList)
                {
                    Console.Write("Before:"+ aye.Fitness + " : [" + aye.RealFitness + "] : ");
                    foreach (double d in aye.objectives) Console.Write(d + " ");
                    Console.WriteLine();
                }//*/
				pop.ResetPopulation(multiobjective.truncatePopulation(pop.GenomeList.Count),this);
                /*foreach (IGenome aye in pop.GenomeList)
                {
                    Console.Write("After:" + aye.Fitness + " : [" + aye.RealFitness + "] : ");
                    foreach (double d in aye.objectives) Console.Write(d + " ");
                    Console.WriteLine();
                }//*/
                //Console.WriteLine("pop4=" + pop.GenomeList.Count + "pop4MO=" + multiobjective.population.Count);
                /*foreach (IGenome g in multiobjective.population)
                {
                    Console.Write("MO_AfterTruncatePop: ");
                    Console.Write(g.Fitness + " : [" + g.RealFitness + "] : ");
                    foreach (double d in g.objectives) Console.Write(d + " ");
                    Console.WriteLine();
                }//*/
                /*foreach (IGenome g in pop.GenomeList)
                {
                    Console.Write("FinalPop: ");
                    foreach (double d in g.objectives) Console.Write(d + " ");
                    Console.WriteLine();
                }//*/
				pop.RedetermineSpeciation(this);
				UpdateFitnessStats();
				DetermineSpeciesTargetSize();
                //Console.WriteLine("DOES IT DO THIS? WHEN? SHOW ME!!");
			}
			
            if(!regenerate)
            {
			    CreateOffSpring();
			    pop.TrimAllSpeciesBackToElite();

                // JUSTIN: DEBUG
                /*Console.WriteLine("These are the newly created children. Are they zeroed out?");
                foreach (IGenome g in offspringList)
                {
                    Console.Write("RF:" + g.RealFitness + ", fit:" + g.Fitness + "misc:" + g.locality + " " + g.nearestNeighbors + " " + g.localGenomeNovelty + " " + g.geneticDiversity + " " + g.competition + ", objectives:");
                    foreach (double d in g.objectives) Console.Write(" " + d);
                    Console.WriteLine();
                }//*/ // They are.

			    // Add offspring to the population.
			    int genomeBound = offspringList.Count;
			    for(int genomeIdx=0; genomeIdx<genomeBound; genomeIdx++)
				    pop.AddGenomeToPopulation(this, offspringList[genomeIdx]);

                /*foreach (IGenome g in pop.GenomeList)
                {
                    Console.Write("RF:" + g.RealFitness + ", fit:" + g.Fitness + "misc:" + g.locality + " " + g.nearestNeighbors + " " + g.localGenomeNovelty + " " + g.geneticDiversity + " " + g.competition + ", objectives:");
                    //foreach (double d in g.objectives) Console.Write(" " + d);
                    Console.WriteLine();
                }//*/
            }
            
			// Adjust the speciation threshold to try and keep the number of species within defined limits.
            if (!neatParameters.multiobjective)
            {
                AdjustSpeciationThreshold();
            }

            //Console.WriteLine("pop5=" + pop.GenomeList.Count + "pop5MO=" + multiobjective.population.Count);
		//----- Stage 2. Evaluate genomes / Update stats.
            //Console.WriteLine("Before pop eval");
			populationEvaluator.EvaluatePopulation(pop, this);
            //Console.WriteLine("After pop eval");
            // JUSTIN: DEBUG
            /*Console.WriteLine("Here is the population rightafter being evaluated. Whats it look like?");
            foreach (IGenome g in pop.GenomeList)
            {
                Console.Write("RF:" + g.RealFitness + ", fit:" + g.Fitness + "misc:" + g.locality + " " + g.nearestNeighbors + " " + g.localGenomeNovelty + " " + g.geneticDiversity + " " + g.competition + ", objectives:");
                foreach (double d in g.objectives) Console.Write(" " + d);
                Console.WriteLine();
            }//*/ // It looked good. Objectives were all 0 0 0 0 0 0, everything else was defined.

            if (neatParameters.multiobjective && neatParameters.noveltySearch)
            {
                // Redefine all objectives in case they haven't been defined yet (new genomes) or the aux data changed (it probably did). This is especially important for genomes being added to the archive or the measure_against population.
                foreach (IGenome g in pop.GenomeList)
                {
                    g.objectives = new double[6];
                    int len = g.objectives.Length;
                    //g.objectives[len - 5] = g.geneticDiversity; // Global genetic diversity objective
                    g.objectives[len - 4] = g.RealFitness; // Global competition objective
                    //g.objectives[len - 3] = g.competition / g.nearestNeighbors; // Local competition objective
                    g.objectives[len - 2] = g.Fitness + 0.001; // Novelty objective
                    //g.objectives[len - 1] = g.localGenomeNovelty / g.nearestNeighbors; // Local genetic diversity objective
                    //foreach (double d in g.objectives) Console.Write(d + " "); Console.WriteLine();
                }
            }

			UpdateFitnessStats();
			DetermineSpeciesTargetSize();
			
			pop.IncrementGenomeAges();
			pop.IncrementSpeciesAges();
			generation++;


            // ------------------------------------------------------------------------------------------------------------------------
            // JUSTIN: 
            //   The following code saves some high fitness genomes at random, as long as they exceed a specified fitness threshold
            //   To use this functionality, edit the following parameters: 
            //
            //          SAVED_PER_GENERATION       FITNESS_SAVE_THRESHOLD       EMPTY_HOPPER_AT       
            //
            if (SAVETHINGS)
            {
                saveTicker += SAVED_PER_GENERATION;
                GenomeList tempOverThreshold = new GenomeList();
                foreach (IGenome g in pop.GenomeList)
                {
                    if (g.RealFitness > FITNESS_SAVE_THRESHOLD)
                    {
                        tempOverThreshold.Add(g);
                    }
                }
                totalOverFitnessThreshold += tempOverThreshold.Count;
                while (saveTicker >= 1)
                {
                    // Choose a random genome from tempOverThreshold to save... if possible.
                    if (tempOverThreshold.Count != 0)
                    {
                        //(int)Math.Floor(Utilities.NextDouble()*championSpecies.Count)
                        int pickMe = (int)(Math.Floor(Utilities.NextDouble() * tempOverThreshold.Count));
                        savedGenomeHopper.Add(tempOverThreshold[pickMe]);
                        tempOverThreshold.RemoveAt(pickMe);
                    }
                    saveTicker -= 1;
                } //NOTE: If no genomes are over the threshold, then no genomes are saved this tick. they are NOT made up later.
                // Potentially dump genomes to file (if there are enough)
                /*
                if (savedGenomeHopper.Count >= EMPTY_HOPPER_AT)
                { 
                    Console.WriteLine("Dumping high-fitness genomes. Total over threshold: " + totalOverFitnessThreshold);
                    dumpGoodGenomes();
                }
                 * */
            }
            // --------- Done dumping HF genomes. -------------------------------------------------- Done dumping HF genomes. ---------


			
            if(neatParameters.noveltySearch)
            {
                //Console.WriteLine("Archive size: " + this.noveltyFixed.archive.Count.ToString());
                //Console.WriteLine("MO Archive size: " + multiobjective.nov.archive.Count.ToString()); //JUSTIN: The MO archive doesn't grow... maybe call it below... or just don't use it at all...
            }
            
            if(neatParameters.noveltySearch && neatParameters.noveltyFloat)
            {
                //Console.WriteLine("I BET THIS HAPPENS: OPTION A.");
                this.noveltyFixed.initialize(pop);   
                this.noveltyFixed.addPending();
            }
            
            if(neatParameters.noveltySearch && neatParameters.noveltyFixed)
            {
                //Console.WriteLine("DOES THIS HAPPEN??????????????? NAH PROLLY NOT");
                this.noveltyFixed.addPending();
            }

            /*Console.WriteLine("Here's the measure_against. " + noveltyFixed.measure_against.Count);
            foreach (IGenome g in noveltyFixed.measure_against)
            {
                Console.Write("RF:" + g.RealFitness + ", fit:" + g.Fitness + "misc:" + g.locality + " " + g.nearestNeighbors + " " + g.localGenomeNovelty + " " + g.geneticDiversity + " " + g.competition + ", objectives:");
                foreach (double d in g.objectives) Console.Write(" " + d);
                Console.WriteLine();
            }
            Console.WriteLine("=================================== End measure_against");
            Console.WriteLine("Here's the archive. " + noveltyFixed.archive.Count);
            foreach (IGenome g in noveltyFixed.archive)
            {
                Console.Write("RF:" + g.RealFitness + ", fit:" + g.Fitness + "misc:" + g.locality + " " + g.nearestNeighbors + " " + g.localGenomeNovelty + " " + g.geneticDiversity + " " + g.competition + ", objectives:");
                foreach (double d in g.objectives) Console.Write(" " + d);
                Console.WriteLine();
            }
            Console.WriteLine("=================================== End archive");//*/ //JUSTIN: I THINK IT'S WORKING! FUUUUUUUUUUUU-N!

            
		//----- Stage 3. Pruning phase tracking / Pruning phase entry & exit.
			if(pruningModeEnabled)
			{
				if(pruningMode)
				{
					// Track the falling population complexity.
					if(pop.AvgComplexity < prunePhase_MinimumStructuresPerGenome)
					{
						prunePhase_MinimumStructuresPerGenome = pop.AvgComplexity;
						prunePhase_generationAtLastSimplification = generation;
					}

					if(TestForPruningPhaseEnd())
						EndPruningPhase();
				}
				else
				{
					if(TestForPruningPhaseBegin())
						BeginPruningPhase();
				}
			}
		}