/// <summary> /// Mutates a random connection splitting it with a node. /// </summary> public void Mutate_Node() { ConnectionGene connectionGene = Connections.GetRandomElement(); if (connectionGene == null) { return; } NodeGene from = connectionGene.From; NodeGene to = connectionGene.To; NodeGene created = NEAT.CreateNode(); created.X = (from.X + to.X) / 2; created.Y = (from.Y + to.Y) / 2 + random.NextDouble() * 0.1 + .05; Nodes.Add(created); ConnectionGene created_connectionGene_1 = NEAT.CreateConnection(from, created); ConnectionGene created_connectionGene_2 = NEAT.CreateConnection(created, to); Connections.Remove(connectionGene); Connections.Add(created_connectionGene_1); Connections.Add(created_connectionGene_2); created_connectionGene_1.Weight = 1; //Default weight. created_connectionGene_2.Weight = connectionGene.Weight; //Old connection's weight. created_connectionGene_2.Enabled = connectionGene.Enabled; //Old enabled state. }
/// <summary> /// Constructs a connection gene with the given innovation number. /// </summary> /// <param name="from">The NodeGene to connect from.</param> /// <param name="to">The NodeGene to connect to.</param> /// <param name="innovation_number">The innovation number.</param> public ConnectionGene(NodeGene from, NodeGene to, int innovation_number) : base(innovation_number) { From = from; To = to; Enabled = true; }
/// <summary> /// Mutates the genome by creating a new connection. /// </summary> public void Mutate_Link() { for (int i = 0; i < NEAT.LINK_ATTEMPTS; ++i) { NodeGene nodeGene_a = Nodes.GetRandomElement(); NodeGene nodeGene_b = Nodes.GetRandomElement(); if (nodeGene_a.X == nodeGene_b.X) { continue; } ConnectionGene connectionGene; if (nodeGene_a.X < nodeGene_b.X) { connectionGene = new ConnectionGene(nodeGene_a, nodeGene_b, 0); //Temp innovation number. } else { connectionGene = new ConnectionGene(nodeGene_b, nodeGene_a, 0); //Temp innovation number. } if (Connections.Contains(connectionGene)) { continue; } connectionGene = NEAT.CreateConnection(connectionGene.From, connectionGene.To); connectionGene.Weight = NEAT.WEIGHT_RANDOM + (random.NextDouble() * 2 - 1); Connections.Add_Sorted_Gene(connectionGene); //This needs to be sorted otherwise something breaks. return; } }