/** * @param parent1 More fit parent * @param parent2 Less fit parent * Operating on a Genome object */ public void Crossover(Genome parent1, Genome parent2) { foreach (NodeGene parentNode in parent1.Nodes.Values) { AddNodeGene(parentNode.Copy()); } foreach (ConnectionGene parentNode in parent1.Connections.Values) { if (parent2.Connections.ContainsKey(parentNode.Innovation)) // matching gene { ConnectionGene childConGene = (Random.Range(0f, 1f) >= 0.0) ? new ConnectionGene(parentNode) : new ConnectionGene(parent2.Connections[parentNode.Innovation]); AddConnectionGene(childConGene); } else // disjoint or excess gene { ConnectionGene childConGene = parentNode.Copy(); AddConnectionGene(childConGene); } } }
public void AddConnectionGene(ConnectionGene gene) { Connections.Add(gene.Innovation, gene); }
public void AddConnectionMutation(Counter innovation, int maxAttempts) { int tries = 0; bool success = false; while (tries < maxAttempts && success == false) { tries++; int listSize = Nodes.Count; int randomNodeKey1 = Random.Range(0, listSize - 1); int randomNodeKey2 = Random.Range(0, listSize - 1); while (!Nodes.ContainsKey(randomNodeKey1) || !Nodes.ContainsKey(randomNodeKey2)) { randomNodeKey1 = Random.Range(0, listSize - 1); randomNodeKey2 = Random.Range(0, listSize - 1); } NodeGene node1 = Nodes[randomNodeKey1]; NodeGene node2 = Nodes[randomNodeKey2]; bool reversed = false; if (node1.GetType().Equals(NodeGene.NodeType.HIDDEN) && node2.GetType().Equals(NodeGene.NodeType.INPUT)) { reversed = true; } else if (node1.GetType().Equals(NodeGene.NodeType.OUTPUT) && node2.GetType().Equals(NodeGene.NodeType.HIDDEN)) { reversed = true; } else if (node1.GetType().Equals(NodeGene.NodeType.OUTPUT) && node2.GetType().Equals(NodeGene.NodeType.INPUT)) { reversed = true; } bool connectionImpossible = false; if (node1.GetType().Equals(NodeGene.NodeType.INPUT) && node2.GetType().Equals(NodeGene.NodeType.INPUT)) { connectionImpossible = true; } else if (node1.GetType().Equals(NodeGene.NodeType.OUTPUT) && node2.GetType().Equals(NodeGene.NodeType.OUTPUT)) { connectionImpossible = true; } bool connectionExists = false; foreach (ConnectionGene con in Connections.Values) { if (con.InNode == node1.ID && con.OutNode == node2.ID) { connectionExists = true; break; } else if (con.InNode == node2.ID && con.OutNode == node1.ID) { connectionExists = true; break; } } if (connectionExists || connectionImpossible) { continue; } ConnectionGene newCon = new ConnectionGene(reversed ? node2.ID : node1.ID, reversed ? node1.ID : node2.ID, Random.Range(0f, 1f), true, innovation.GetInnovation()); //Connections.Add(newCon.Innovation, newCon); AddConnectionGene(newCon); success = true; } if (success == false) { Debug.Log("Tried, but could not add more connections"); } }