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 }); }
private void TopologyMutationToBoth_OnClick() { if (Parent1Genome != null && Parent2Genome != null) { MutateTopology(Parent1GV, Parent1Genome); Parent2Genome.Nodes.Clear(); Parent2Genome.InputNodes.Clear(); Parent2Genome.HiddenNodes.Clear(); Parent2Genome.OutputNodes.Clear(); foreach (Node n in Parent1Genome.Nodes.Values) { Node newNode = new Node(n.Id, n.Type); Parent2Genome.Nodes.Add(n.Id, newNode); if (n.Type == NodeType.Input) { Parent2Genome.InputNodes.Add(newNode); } if (n.Type == NodeType.Hidden) { Parent2Genome.HiddenNodes.Add(newNode); } if (n.Type == NodeType.Output) { Parent2Genome.OutputNodes.Add(newNode); } } Parent2Genome.Connections.Clear(); foreach (Connection c in Parent1Genome.Connections.Values) { Node fromNode = Parent2Genome.Nodes[c.FromNode.Id]; Node toNode = Parent2Genome.Nodes[c.ToNode.Id]; Connection newCon = new Connection(c.Id, fromNode, toNode); newCon.Enabled = c.Enabled; newCon.Weight = c.Weight; fromNode.OutConnections.Add(newCon); toNode.InConnections.Add(newCon); Parent2Genome.Connections.Add(c.Id, newCon); } Parent2Genome.CalculateDepths(); Parent2GV.VisualizeGenome(Parent2Genome, false, true); } }
public NewConnectionMutation AddConnection(Genome genome, List <NewConnectionMutation> mutations) { List <Connection> candidateConnections = FindCandidateConnections(genome); Connection newConnection = candidateConnections[Random.Next(candidateConnections.Count)]; // Check if this exact mutation has already been done int newConnectionId; List <NewConnectionMutation> existingMutations = mutations.Where(x => (x.FromNodeId == newConnection.FromNode.Id && x.ToNodeId == newConnection.ToNode.Id) || (x.FromNodeId == newConnection.ToNode.Id && x.ToNodeId == newConnection.FromNode.Id) ).ToList(); if (existingMutations.Count > 0) { newConnectionId = existingMutations[0].NewConnectionId; } else { newConnectionId = ConnectionId++; } newConnection.Id = newConnectionId; newConnection.Weight = (float)(Random.NextDouble() * 2 - 1); newConnection.FromNode.OutConnections.Add(newConnection); newConnection.ToNode.InConnections.Add(newConnection); genome.Connections.Add(newConnectionId, newConnection); genome.CalculateDepths(); return(new NewConnectionMutation() { FromNodeId = newConnection.FromNode.Id, ToNodeId = newConnection.ToNode.Id, NewConnectionId = newConnection.Id }); }