public static Genome CrossOver(Genome parent1, Genome parent2, Fitter f) { Genome child = new Genome(); var rand = new Random(); // Add Disjoint and Excess Connections from Fitter Parent if (f == Fitter.Parent1) { // Add all nodes from the fitter parent foreach (Node n in parent1.Nodes.Values) { child.AddNodeCopy(n); } foreach (Connection c in parent1.Connections.Values) { if (!parent2.Connections.ContainsKey(c.Innovation)) { child.AddConnectionCopy(c); } } } else { foreach (Node n in parent2.Nodes.Values) { child.AddNodeCopy(n); } foreach (Connection c in parent2.Connections.Values) { if (!parent1.Connections.ContainsKey(c.Innovation)) { child.AddConnectionCopy(c); } } } // Go through again to add all the matching gene randomly foreach (Connection c1 in parent1.Connections.Values) { foreach (Connection c2 in parent2.connections.Values) { // If matching gene --> pick randomly (50/50) if (c1.Innovation == c2.Innovation) { if (rand.Next(0, 2) == 0) { child.AddConnectionCopy(c1); } else { child.AddConnectionCopy(c2); } // Randomly enable disabled inherited connection if (!c1.Expressed && !c2.Expressed) { double r = rand.NextDouble(); if (r < NEATController.ENABLE_CHANCE) { c2.Expressed = true; } } } } } return(child); }