/// <inheritdoc /> public void Iteration() { if (!_initialized) { PreIteration(); } if (Population.Species.Count == 0) { throw new EncogError("Population is empty, there are no species."); } IterationNumber++; // Clear new population to just best genome. _newPopulation.Clear(); _newPopulation.Add(BestGenome); _oldBestGenome = BestGenome; // execute species in parallel IList <EAWorker> threadList = new List <EAWorker>(); foreach (ISpecies species in Population.Species) { int numToSpawn = species.OffspringCount; // Add elite genomes directly if (species.Members.Count > 5) { var idealEliteCount = (int)(species.Members.Count * EliteRate); int eliteCount = Math.Min(numToSpawn, idealEliteCount); for (int i = 0; i < eliteCount; i++) { IGenome eliteGenome = species.Members[i]; if (_oldBestGenome != eliteGenome) { numToSpawn--; if (!AddChild(eliteGenome)) { break; } } } } // now add one task for each offspring that each species is allowed while (numToSpawn-- > 0) { var worker = new EAWorker(this, species); threadList.Add(worker); } } // run all threads and wait for them to finish Parallel.ForEach(threadList, currentTask => currentTask.PerformTask()); // validate, if requested if (ValidationMode) { if (_oldBestGenome != null && !_newPopulation.Contains(_oldBestGenome)) { throw new EncogError( "The top genome died, this should never happen!!"); } if (BestGenome != null && _oldBestGenome != null && BestComparer.IsBetterThan(_oldBestGenome, BestGenome)) { throw new EncogError( "The best genome's score got worse, this should never happen!! Went from " + _oldBestGenome.Score + " to " + BestGenome.Score); } } _speciation.PerformSpeciation(_newPopulation); // purge invalid genomes Population.PurgeInvalidGenomes(); }
/// <inheritdoc /> public void Iteration() { if (!_initialized) { PreIteration(); } if (Population.Species.Count == 0) { throw new EncogError("Population is empty, there are no species."); } IterationNumber++; // Clear new population to just best genome. _newPopulation.Clear(); _newPopulation.Add(BestGenome); _oldBestGenome = BestGenome; // execute species in parallel IList<EAWorker> threadList = new List<EAWorker>(); foreach (ISpecies species in Population.Species) { int numToSpawn = species.OffspringCount; // Add elite genomes directly if (species.Members.Count > 5) { var idealEliteCount = (int) (species.Members.Count*EliteRate); int eliteCount = Math.Min(numToSpawn, idealEliteCount); for (int i = 0; i < eliteCount; i++) { IGenome eliteGenome = species.Members[i]; if (_oldBestGenome != eliteGenome) { numToSpawn--; if (!AddChild(eliteGenome)) { break; } } } } // now add one task for each offspring that each species is allowed while (numToSpawn-- > 0) { var worker = new EAWorker(this, species); threadList.Add(worker); } } // run all threads and wait for them to finish Parallel.ForEach(threadList, currentTask => currentTask.PerformTask()); // validate, if requested if (ValidationMode) { if (_oldBestGenome != null && !_newPopulation.Contains(_oldBestGenome)) { throw new EncogError( "The top genome died, this should never happen!!"); } if (BestGenome != null && _oldBestGenome != null && BestComparer.IsBetterThan(_oldBestGenome, BestGenome)) { throw new EncogError( "The best genome's score got worse, this should never happen!! Went from " + _oldBestGenome.Score + " to " + BestGenome.Score); } } _speciation.PerformSpeciation(_newPopulation); // purge invalid genomes Population.PurgeInvalidGenomes(); }