/// <summary> /// Mutates a random connection by inverting its current Enabled status. /// </summary> public void Mutate_LinkToggle() { if (ConnectionGenes.Count == 0) //There are no connections, nothing to toggle. { return; } ConnectionGene connectionGene = ConnectionGenes.RandomValue(Random).Take(1).ElementAt(0); if (connectionGene != null) { connectionGene.Enabled = !connectionGene.Enabled; } }
/// <summary> /// Mutates a random connection by shifting its weight up or down by a radom value. Creates connection if there is none. /// </summary> public void Mutate_WeightShift() { if (ConnectionGenes.Count == 0) { Mutate_Link(); } else { ConnectionGene connectionGene = ConnectionGenes.RandomValue(Random).Take(1).ElementAt(0); if (connectionGene != null) { connectionGene.Weight = connectionGene.Weight + Pedigree.Mutation_WeightShift * (Random.NextDouble() * 2 - 1); } } }
/// <summary> /// Mutates a random connection splitting it with a node. /// </summary> public void Mutate_Node() { if (NodeGenes.Count >= Pedigree.MaxNodes) { return; //Do nothing if we have max nodes. } else if (ConnectionGenes.Count == 0) { return; //Literally cannot make a node. } ConnectionGene connectionGene = ConnectionGenes.RandomValue(Random).Take(1).ElementAt(0); if (connectionGene == null) { return; } NodeGene from = NodeGenes[connectionGene.ConnectionGenePattern.From.InnovationNumber]; NodeGene to = NodeGenes[connectionGene.ConnectionGenePattern.To.InnovationNumber]; NodeGene created = Pedigree.Create_NodeGene(connectionGene); if (NodeGenes.ContainsKey(created.NodeGenePattern.InnovationNumber)) { return; //TODO maybe retry here as well? } NodeGenes.Add(created.NodeGenePattern.InnovationNumber, created); ConnectionGene created_connectionGene_1 = Pedigree.Create_ConnectionGene(from, created, 1, true); //Default weight of 1. ConnectionGene created_connectionGene_2 = Pedigree.Create_ConnectionGene(created, to, connectionGene.Weight, connectionGene.Enabled); ConnectionGenes.Remove(connectionGene.ConnectionGenePattern.InnovationNumber); ConnectionGenes.Add(created_connectionGene_1.ConnectionGenePattern.InnovationNumber, created_connectionGene_1); ConnectionGenes.Add(created_connectionGene_2.ConnectionGenePattern.InnovationNumber, created_connectionGene_2); }