/// <summary> /// Breed /// </summary> private void Breed() { // Logs Setup int weightMutationNb = 0; int addConnectionNb = 0; int addNodeNb = 0; int enableDisableConnectionNb = 0; _mutationLogs = ""; while (_nextEvaluationGenomes.Count() < _config.populationSize) { Genome child = null; Genome mom = null; Genome dad = null; // Get Child Species species = null; int maxToKeep = ((_config.populationSize * _config.percentageToKeep) / 100) - 1; if (_config.species) { species = GetRandomSpecies(_r); } if (_config.crossover) { if (species != null) { mom = GetRandomGenome(species, _r); dad = GetRandomGenome(species, _r); } else { mom = _genomes[UnityEngine.Random.Range(0, maxToKeep)]; dad = _genomes[UnityEngine.Random.Range(0, maxToKeep)]; } // Crossover between Mom & Dad child = mom.Fitness >= dad.Fitness ? Genome.Crossover(mom, dad, _r, _config.disabledConnectionInheritChance) : Genome.Crossover(dad, mom, _r, _config.disabledConnectionInheritChance); } else { child = species != null ? new Genome(GetRandomGenome(species, _r)) : new Genome(_genomes[UnityEngine.Random.Range(0, maxToKeep)]); } // Weights Mutation if ((float)_r.NextDouble() < _config.mutationRate) { child.WeightsMutation(_r); weightMutationNb++; } if (_config.genomeMutations) { // Add Connection Mutation if ((float)_r.NextDouble() < _config.addConnectionRate) { // If for Logs if (child.AddConnectionMutation(_r, _connectionInnovation, 10)) { addConnectionNb++; } } // Add Node Mutation if ((float)_r.NextDouble() < _config.addNodeRate) { child.AddNodeMutation(_r, _connectionInnovation, _nodeInnovation); addNodeNb++; } // Enable/Disable a Random Connection if ((float)_r.NextDouble() < _config.enableDisableRate) { // If for Logs if (child.EnableOrDisableRandomConnection()) { enableDisableConnectionNb++; } } } // Add Child to Next Evaluation Genomes _nextEvaluationGenomes.Add(child); } _mutationLogs += string.Format( "Weights Mutation: {0}, Add Connection: {1}, Add Node: {2}, Enable/Disable Connection: {3}\nCrossover is {4}, Genome Mutations is {5}, Species is {6}", weightMutationNb, addConnectionNb, addNodeNb, enableDisableConnectionNb, _config.crossover, _config.genomeMutations, _config.species ); _genomes.Clear(); _genomes = new List <Genome>(_nextEvaluationGenomes); _nextEvaluationGenomes = new List <Genome>(); }
/// <summary> /// Breed /// </summary> private Genome Breed(Genome mom = null, Genome dad = null) { Genome child = null; // Get Child if (dad != null && mom != null) { // Crossover between Mom & Dad if (mom.Fitness >= dad.Fitness) { child = Genome.Crossover(mom, dad, _r, _config.disabledConnectionInheritChance); } else { child = Genome.Crossover(dad, mom, _r, _config.disabledConnectionInheritChance); } } else { int maxToKeep = ((_currentPop * _config.percentageToKeep) / 100) - 1; mom = _genomes[UnityEngine.Random.Range(0, maxToKeep)]; dad = _genomes[UnityEngine.Random.Range(0, maxToKeep)]; // Crossover between Mom & Dad if (mom.Fitness >= dad.Fitness) { child = Genome.Crossover(mom, dad, _r, _config.disabledConnectionInheritChance); } else { child = Genome.Crossover(dad, mom, _r, _config.disabledConnectionInheritChance); } } // Weights Mutation if ((float)_r.NextDouble() < _config.mutationRate) { child.WeightsMutation(_r); } if (_config.genomeMutations) { // Add Connection Mutation if ((float)_r.NextDouble() < _config.addConnectionRate) { child.AddConnectionMutation(_r, _connectionInnovation, 10); } // Add Node Mutation if ((float)_r.NextDouble() < _config.addNodeRate) { child.AddNodeMutation(_r, _connectionInnovation, _nodeInnovation); } // Enable/Disable a Random Connection if ((float)_r.NextDouble() < _config.enableDisableRate) { child.EnableOrDisableRandomConnection(); } } return(child); }