public static GenomeList CreateGenomeList(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 = 1; 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); }
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); }
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; }
public void addPending(bool suppressThresholdUpdate = false) { int length = pending_addition.Count; if (!suppressThresholdUpdate) { if (length == 0) { archive_threshold *= 0.95; } if (length > 5) { archive_threshold *= 1.3; } } for (int i = 0; i < length; i++) { if (measureAgainstArchive((NeatGenome.NeatGenome)pending_addition[i], false)) { archive.Add(pending_addition[i]); using (System.IO.StreamWriter file = new System.IO.StreamWriter("NoveltyLog.txt", true)) file.WriteLine(pending_addition[i].Fitness); using (System.IO.StreamWriter file = new System.IO.StreamWriter(Chromaria.Modes.NoveltySearchRun.noveltyLogsFolder + "archive.txt", true)) { // Write the genome's info to the novelty log file.WriteLine("ID: " + pending_addition[i].GenomeId); file.WriteLine("Fitness: " + pending_addition[i].Fitness); file.Write("Behavior: "); foreach (double behavior in pending_addition[i].Behavior.behaviorList) { file.Write(behavior.ToString() + ", "); } file.WriteLine(); file.WriteLine(); } // Also print out the genome itself XmlDocument doc = new XmlDocument(); XmlGenomeWriterStatic.Write(doc, (NeatGenome.NeatGenome)pending_addition[i]); FileInfo oFileInfo = new FileInfo(Chromaria.Modes.NoveltySearchRun.noveltyLogsFolder + "genome" + pending_addition[i].GenomeId + ".xml"); doc.Save(oFileInfo.FullName); } } pending_addition.Clear(); }
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); }
//add an existing population from hypersharpNEAT to the multiobjective population maintained in //this class, step taken before evaluating multiobjective population through the rank function public void addPopulation(Population p) { for (int i = 0; i < p.GenomeList.Count; i++) { bool blacklist = false; for (int j = 0; j < population.Count; j++) { if (distance(p.GenomeList[i].objectives, population[j].objectives) < 0.0001) { //JUSTIN: Changed from 0.001 (doesn't seem to help) blacklist = true; //reject a genome if it is very similar to existing genomes in pop //Console.Write("Blacklisting: "); //foreach (double bla in p.GenomeList[i].objectives) Console.Write(bla + " "); //Console.Write("vs "); //foreach (double bla in population[j].objectives) Console.Write(bla + " "); //Console.WriteLine(); break; } } if (!blacklist) //add genome if it is unique //we might not need to make copies { NeatGenome.NeatGenome copy = new NeatGenome.NeatGenome((NeatGenome.NeatGenome)p.GenomeList[i], 0); //copy.objectives = (double[])p.GenomeList[i].objectives.Clone(); //JUSTIN: Moved this to the NeatGenome copy constructor... population.Add(copy); } } }
public bool measureAgainstArchive(NeatGenome.NeatGenome neatgenome, bool addToPending) { foreach (IGenome genome in archive) { double dist = BehaviorDistance.Distance(neatgenome.Behavior, ((NeatGenome.NeatGenome)genome).Behavior); if (dist > maxDistSeen) { maxDistSeen = dist; Console.WriteLine("Most novel distance: " + maxDistSeen); } if (dist < archive_threshold) { return(false); } } if (addToPending) { pending_addition.Add(neatgenome); } return(true); }
public void GenomeCreated(IGenome genome) { //only add it if you haven't seen this genome before (might be making copies for the sake of novelty search/archive) if (allGeneratedGenomes.GenomeByID(genome.GenomeId) == null) { allGeneratedGenomes.Add(genome); } }
public bool measureAgainstArchive(NeatGenome.NeatGenome neatgenome, bool addToPending) { foreach (IGenome genome in archive) { if (BehaviorDistance.Distance(neatgenome.Behavior, ((NeatGenome.NeatGenome)genome).Behavior) < archive_threshold) { return(false); } } if (addToPending) { pending_addition.Add(neatgenome); } return(true); }
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); }
public GenomeList loadMoreGenomesFromSelected(int count) { GenomeList gl = new GenomeList(); for (int i = 0; i < count; i++) { gl.Add(loadNextNetworkFromSelected()); } return(gl); }
/// <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); }
public void addPending() { int length = pending_addition.Count; if (length == 0) { archive_threshold *= 0.95; } if (length > 5) { archive_threshold *= 1.3; } for (int i = 0; i < length; i++) { if (measureAgainstArchive((NeatGenome.NeatGenome)pending_addition[i], false)) { archive.Add(pending_addition[i]); } } pending_addition.Clear(); }
/// <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)); }
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)); } } }
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)); } } }
/// <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); }
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); }
//add an existing population from hypersharpNEAT to the multiobjective population maintained in //this class, step taken before evaluating multiobjective population through the rank function public void addPopulation(Population p) { for (int i = 0; i < p.GenomeList.Count; i++) { bool blacklist = false; for (int j = 0; j < population.Count; j++) { if (distance(p.GenomeList[i].Behavior.objectives, population[j].objectives) < 0.01) { blacklist = true; //reject a genome if it is very similar to existing genomes in pop } } if (!blacklist) //add genome if it is unique //we might not need to make copies { NeatGenome.NeatGenome copy = new NeatGenome.NeatGenome((NeatGenome.NeatGenome)p.GenomeList[i], 0); copy.objectives = (double[])p.GenomeList[i].Behavior.objectives.Clone(); population.Add(copy); } } }
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; }
/// <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; }
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); }
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(); } } }
// 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; }
public GenomeList loadMoreGenomesFromSelected(int count) { GenomeList gl = new GenomeList(); for (int i = 0; i < count; i++) gl.Add(loadNextNetworkFromSelected()); return gl; }
/// <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 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; }
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; }
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; }
public void addPending(bool suppressThresholdUpdate = false) { int length = pending_addition.Count; if (usingProbabilisticArchive) { // Do something different for probabilistic archive. No thresholds involved. Just add everyone that is pending. if (!probTournament) { for (int i = 0; i < length; i++) { archive.Add(pending_addition[i]); } pending_addition.Clear(); Console.WriteLine("Added " + length + " to the archive. Current size: " + archive.Count); } else { // Hold a diversity tournament to decide to gets added to the archive int countThem = 0; double averageAdd = 0; for (int i = 0; i + 1 < length; i = i + 2) { double first = valueAgainstArchive(pending_addition[i]); double second = valueAgainstArchive(pending_addition[i + 1]); if (first > second) { archive.Add(pending_addition[i]); averageAdd += first; } else { archive.Add(pending_addition[i + 1]); averageAdd += second; } countThem++; } // The straggler is almost never added... need a more fair method of adding stragglers. Maybe give them an early tournament against someone random? /*if (length % 2 == 1) // The last one was not considered if there was an odd number in the list. We should consider it against the average. * { * if (countThem != 0) * { * averageAdd /= countThem; * if (valueAgainstArchive(pending_addition[length - 1]) > averageAdd) * { * Console.WriteLine("Straggler added! " + valueAgainstArchive(pending_addition[length - 1]) + " beats avg " + averageAdd); * archive.Add(pending_addition[length - 1]); * } * else * { * Console.WriteLine("Straggler not added. " + valueAgainstArchive(pending_addition[length - 1]) + " loses to avg " + averageAdd); * } * } * }//*/ pending_addition.Clear(); Console.WriteLine("Added " + countThem + " (" + length + ") to the archive. Current size: " + archive.Count); } } else { if (!suppressThresholdUpdate) { if (length == 0) { archive_threshold *= 0.95; Console.WriteLine("Decreasing threshold. New: " + archive_threshold + ", adding " + length + " to archive. (" + archive.Count + ")"); } if (length > 5) { archive_threshold *= 1.3; Console.WriteLine("Increasing threshold. New: " + archive_threshold + ", adding " + length + " to archive. (" + archive.Count + ")"); } } for (int i = 0; i < length; i++) { if (measureAgainstArchive((NeatGenome.NeatGenome)pending_addition[i], false)) { archive.Add(pending_addition[i]); } } pending_addition.Clear(); } if (enforceArchiveLimit) { if (probDeletionTournament) { // Check the archive against the size limit and if it exceeds the limit, run a tournament to delete members while (archive.Count > archiveSizeLimit) { int firstIdx = archiveAddingRNG.Next(archive.Count); int secondIdx = firstIdx; while (firstIdx == secondIdx) // Make sure the indexes are unique { secondIdx = archiveAddingRNG.Next(archive.Count); } // Evaluate the candidate victims against the archive double first = valueAgainstArchive(archive[firstIdx]); double second = valueAgainstArchive(archive[secondIdx]); // Remove the one with the lower novelty score if (first < second) { archive.RemoveAt(firstIdx); //Console.WriteLine(first + " vs " + second + " : removing first."); } else { archive.RemoveAt(secondIdx); //Console.WriteLine(first + " vs " + second + " : removing second."); } } } else // No tournament, just delete randomly { while (archive.Count > archiveSizeLimit) { int firstIdx = archiveAddingRNG.Next(archive.Count); // Evaluate the candidate victims against the archive double first = valueAgainstArchive(archive[firstIdx]); archive.RemoveAt(firstIdx); } } } }