/// <summary> /// Crossover 2 Genomes /// </summary> /// <param name="moreFitParent">Parent with the most Fitness of the 2 Parents</param> /// <param name="lessFitParent">Second Parent</param> /// <param name="r">Random</param> /// <param name="disabledConnectionInheritChance">Disabled Connection Inherit Chance</param> /// <returns>Child Genome</returns> public static Genome Crossover(Genome moreFitParent, Genome lessFitParent, Random r, float disabledConnectionInheritChance) { Genome child = new Genome(moreFitParent.NewWeightRange, moreFitParent.PerturbingProbability); // Add More Fit Parent Nodes to Child foreach (NodeGene moreFitParentNode in moreFitParent.Nodes.Values) { child.AddNodeGene(new NodeGene(moreFitParentNode)); } // Add a mix of Parents Connections to Child foreach (ConnectionGene moreFitParentConnection in moreFitParent.Connections.Values) { ConnectionGene childConnectionGene = null; if (lessFitParent.Connections.ContainsKey(moreFitParentConnection.InnovationId)) // Matching Connection => Select randomly one of the parents Connection { ConnectionGene lessFitParentConnection = lessFitParent.Connections[moreFitParentConnection.InnovationId]; bool disabled = !moreFitParentConnection.IsEnable || !lessFitParentConnection.IsEnable; childConnectionGene = r.Next(100) < 50 ? new ConnectionGene(moreFitParentConnection) : new ConnectionGene(lessFitParentConnection); if (disabled && ((float)r.NextDouble() < disabledConnectionInheritChance)) { childConnectionGene.IsEnable = false; } } else // Disjoint or excess Connection => Select More Fit Parent Connection { childConnectionGene = new ConnectionGene(moreFitParentConnection); } child.AddConnectionGene(childConnectionGene); } return(child); }
/** * @param parent1 More fit parent * @param parent2 Less fit parent */ public Genome Crossover(Genome parent1, Genome parent2) { Genome child = new Genome(); foreach (NodeGene parentNode in parent1.Nodes.Values) { child.AddNodeGene(parentNode.Copy()); } foreach (ConnectionGene parentNode in parent1.Connections.Values) { if (parent2.Connections.ContainsValue(parentNode)) // matching gene { ConnectionGene childConGene = (Random.Range(0f, 1f) >= 0.5) ? parentNode.Copy() : parent2.Connections[parentNode.Innovation].Copy(); child.AddConnectionGene(childConGene); } else // disjoint or excess gene { ConnectionGene childConGene = parentNode.Copy(); child.AddConnectionGene(childConGene); } } return(child); }