public void AddIntermediateNode(LinkGene a) { a.Disabled = true; int nid = AddNode(NodeType.Intermediate); AddConnection(a.Source, nid, RandomWeight()); AddConnection(nid, a.Destination, RandomWeight()); }
public void AddConnection(int source, int destination, double weight) { var lg = new LinkGene(source, destination, weight); LinkGenotype.Add(lg); NodeGenotype[source].Outputs.Add(lg); NodeGenotype[destination].Inputs.Add(lg); }
private void AddConnection(int source, int destination, double weight, int innovation) { var lg = new LinkGene(source, destination, weight) { Innovation = innovation }; LinkGenotype.Add(lg); NodeGenotype[source].Outputs.Add(lg); NodeGenotype[destination].Inputs.Add(lg); }
public void Mutate() { // Add Node Mutation if (NEATNET.Random.NextDouble() < AddNodeMutationChance) { // There's a possibility that there aren't any links at all if (LinkGenotype.Count > 0) { // Pick random link int ridx = NEATNET.Random.Next(LinkGenotype.Count); LinkGene a = LinkGenotype[ridx]; // Add an intermediate node in the link AddIntermediateNode(a); } } // Add Link Mutation if (NEATNET.Random.NextDouble() < AddLinkMutationChance) { // Pick two unique neurons, there are guaranteed to be at least two // Starting neuron cannot be an output neuron, ending neuron cannot be an input neuron // Only connect lower nodes to higher nodes (assuming input nodes are lowest, intermediate are sorted by ID, and output are highest) // TODO Implementation is flawed, must select two nodes that are UNCONNECTED int ridxa = NEATNET.Random.Next(NextNeuronID - OutputNodeCount); if (ridxa >= InputNodeCount) { ridxa += OutputNodeCount; // skip the output nodes } int ridxb = NEATNET.Random.Next(OutputNodeCount + NextNeuronID - ridxa - 1); if (ridxb >= OutputNodeCount) { ridxb += ridxa - OutputNodeCount + 1; } else { ridxb += InputNodeCount; } if (!LinkGeneExists(ridxa, ridxb)) { AddConnection(ridxa, ridxb, RandomWeight()); } } // Link Weight Mutation for (int i = 0; i < LinkGenotype.Count; i++) { var lg = LinkGenotype[i]; if (NEATNET.Random.NextDouble() < WeightMutationChance) { if (NEATNET.Random.NextDouble() < WeightPerturbChance) { // Perturb weighting by a uniform amount lg.Weight += WeightPerturbEpsilon * RandomWeight(); } else { // Randomize weighting lg.Weight = RandomWeight(); } } } // TODO Implement other mutation types }