public NewNodeMutation AddNode(Genome genome, List <NewNodeMutation> mutations) { List <Connection> candidateConnections = FindCandidateConnectionsForNewNode(genome); Connection connectionToSplit = candidateConnections[Random.Next(candidateConnections.Count)]; connectionToSplit.Enabled = false; // Check if this exact mutation has already been done this evolution cycle int nodeId, toNewNodeId, fromNewNodeId; List <NewNodeMutation> existingMutations = mutations.Where(x => x.SplittedConnectionId == connectionToSplit.Id).ToList(); if (existingMutations.Count > 0) { NewNodeMutation existingMutation = existingMutations[0]; nodeId = existingMutation.NewNodeId; toNewNodeId = existingMutation.ToNewNodeConnectionId; fromNewNodeId = existingMutation.FromNewNodeConnectionId; } else { nodeId = NodeId++; toNewNodeId = ConnectionId++; fromNewNodeId = ConnectionId++; } // Create new node Node newNode = new Node(nodeId, NodeType.Hidden); // Create new connections Connection toNewNode = new Connection(toNewNodeId, connectionToSplit.FromNode, newNode); connectionToSplit.FromNode.OutConnections.Add(toNewNode); newNode.InConnections.Add(toNewNode); toNewNode.Weight = 1; Connection fromNewNode = new Connection(fromNewNodeId, newNode, connectionToSplit.ToNode); newNode.OutConnections.Add(fromNewNode); connectionToSplit.ToNode.InConnections.Add(fromNewNode); fromNewNode.Weight = connectionToSplit.Weight; genome.HiddenNodes.Add(newNode); genome.Nodes.Add(nodeId, newNode); genome.Connections.Add(toNewNodeId, toNewNode); genome.Connections.Add(fromNewNodeId, fromNewNode); genome.CalculateDepths(); return(new NewNodeMutation() { SplittedConnectionId = connectionToSplit.Id, NewNodeId = newNode.Id, ToNewNodeConnectionId = toNewNode.Id, FromNewNodeConnectionId = fromNewNode.Id }); }
public void MutateTopology(Genome g, MutationInformation info, List <NewNodeMutation> newNodeMutations, List <NewConnectionMutation> newConnectionMutations) { int possibleNewNodeMutations = FindCandidateConnectionsForNewNode(g).Count; int possibleNewConnectionMutations = FindCandidateConnections(g).Count; int allPossibleMutations = possibleNewNodeMutations + possibleNewConnectionMutations; float addNewNodeChance = (float)possibleNewNodeMutations / (float)allPossibleMutations; double rng = Random.NextDouble(); if (rng <= addNewNodeChance) { NewNodeMutation mutation = AddNode(g, newNodeMutations); if (newNodeMutations.Where(x => x.SplittedConnectionId == mutation.SplittedConnectionId).Count() == 0) { newNodeMutations.Add(mutation); } if (info != null) { info.NumNewNodeMutations++; } } else { NewConnectionMutation mutation = AddConnection(g, newConnectionMutations); if (newConnectionMutations.Where(x => (x.FromNodeId == mutation.FromNodeId && x.ToNodeId == mutation.ToNodeId) || (x.FromNodeId == mutation.ToNodeId && x.ToNodeId == mutation.FromNodeId) ).Count() == 0) { newConnectionMutations.Add(mutation); } if (info != null) { info.NumNewConnectionsMutations++; } } }