SLinkGene(SLinkGene original) { Enabled = original.Enabled; InnovationID = original.InnovationID; FromNeuron = original.FromNeuron; ToNeuron = original.ToNeuron; Weight = original.Weight; IsRecurrent = original.IsRecurrent; }
MutateWeights(float mutationRate, float chanceOfReplacement, float maxPertubation) { for (int i = 0; i < m_vecLinks.Count; i++) { SLinkGene connection = m_vecLinks[i]; if (Random.value < mutationRate) { if (Random.value < chanceOfReplacement) { connection.Weight = Random.Range(-1.0f, 1.0f); } else { connection.Weight += Random.Range(-1.0f, 1.0f) * maxPertubation; } } } }
CreatePhenotype(int depth) { // Delete previous phenotype assigned to this genome. DeletePhenotype(); List <SNeuron> neurons = new List <SNeuron> (); // Add the neuron genes to the phenotype neurons. for (int i = 0; i < m_vecNeurons.Count; i++) { SNeuronGene neuron = m_vecNeurons[i]; neurons.Add(new SNeuron(neuron.Type, neuron.ID, neuron.SplitY, neuron.SplitX, neuron.ActivationResponse)); } // Create the links for the phenotype. for (int i = 0; i < m_vecLinks.Count; i++) { SLinkGene link = m_vecLinks[i]; // Ignore the disabled links if (link.Enabled) { SNeuron fromNeuron = neurons[GetNeuronIndexById(link.FromNeuron)]; SNeuron toNeuron = neurons[GetNeuronIndexById(link.ToNeuron)]; SLink newLink = new SLink(link.Weight, fromNeuron, toNeuron, link.IsRecurrent); fromNeuron.linksFrom.Add(newLink); toNeuron.linksTo.Add(newLink); } } m_Phenotype = new CNeuralNet(neurons, depth); return(m_Phenotype); }
SelectGenesToBreed(CGenome mum, CGenome dad, ParentType best, List <SLinkGene> babyGenes, List <int> neuronIDs) { List <SLinkGene> mumLinks = mum.GetLinks(); List <SLinkGene> dadLinks = dad.GetLinks(); using (IEnumerator <SLinkGene> mumEnumerator = mumLinks.GetEnumerator()) using (IEnumerator <SLinkGene> dadEnumerator = dadLinks.GetEnumerator()) { bool hasMumMore = mumEnumerator.MoveNext(); bool hasDadMore = dadEnumerator.MoveNext(); SLinkGene selectedGene = mumEnumerator.Current; while (hasMumMore || hasDadMore) { if (!hasMumMore && hasDadMore) { if (best == ParentType.Dad) { selectedGene = dadEnumerator.Current; } hasDadMore = dadEnumerator.MoveNext(); } else if (!hasDadMore && hasMumMore) { if (best == ParentType.Mum) { selectedGene = mumEnumerator.Current; } hasMumMore = mumEnumerator.MoveNext(); } else if (mumEnumerator.Current.InnovationID < dadEnumerator.Current.InnovationID) { if (best == ParentType.Mum) { selectedGene = mumEnumerator.Current; } hasMumMore = mumEnumerator.MoveNext(); } else if (dadEnumerator.Current.InnovationID < mumEnumerator.Current.InnovationID) { if (best == ParentType.Dad) { selectedGene = dadEnumerator.Current; } hasDadMore = dadEnumerator.MoveNext(); } else if (dadEnumerator.Current.InnovationID == mumEnumerator.Current.InnovationID) { if (Random.value < 0.5f) { selectedGene = mumEnumerator.Current; } else { selectedGene = dadEnumerator.Current; } hasMumMore = mumEnumerator.MoveNext(); hasDadMore = dadEnumerator.MoveNext(); } if (babyGenes.Count == 0) { babyGenes.Add(new SLinkGene(selectedGene)); } else { if (babyGenes[babyGenes.Count - 1].InnovationID != selectedGene.InnovationID) { babyGenes.Add(new SLinkGene(selectedGene)); } } AddNeuronID(selectedGene.FromNeuron, neuronIDs); AddNeuronID(selectedGene.ToNeuron, neuronIDs); } } }
AddLink(float mutationRate, float chanceOfLooped, CInnovation innovations, int numTriesToFindLoop, int numTriesToAddLink) { if (Random.value > mutationRate) { return; } int neuron1_ID = -1; int neuron2_ID = -1; // If this flag is true a recurrent link is added. bool setRecurrent = false; // There is a chance that this will be a looped recurrent link // (i.e a neuron that has a link directly to itself). if (Random.value < chanceOfLooped) { setRecurrent = AddLoopedRecurrentLink(out neuron1_ID, out neuron2_ID, numTriesToFindLoop); } else { AddNonReccurentLink(out neuron1_ID, out neuron2_ID, numTriesToAddLink); } if (neuron1_ID < 0 || neuron2_ID < 0) { return; } // Does the database already hold a similar innovation? int innovationID = innovations.CheckInnovation(neuron1_ID, neuron2_ID, InnovationType.NewLink); // Check if this link is a recurrent link (non-looped). // If the link feeds backward it is a recurrent link. // // A backward link is characterized with the fact that the from // neuron has a greater SplitY value than the to neuron. if (m_vecNeurons[GetNeuronIndexById(neuron1_ID)].SplitY > m_vecNeurons[GetNeuronIndexById(neuron2_ID)].SplitY) { setRecurrent = true; } if (innovationID < 0) { // This innovation does not exist so we add a new innovation // to the database with a id so we can later refer to it by // its new id. The new link gene will be tagged with this id. innovations.CreateNewInnovation(neuron1_ID, neuron2_ID, InnovationType.NewLink); innovationID = innovations.NextInnovationID() - 1; } // Assign the innovation id to a new link gene. SLinkGene newGene = new SLinkGene(neuron1_ID, neuron2_ID, true /* enable */, innovationID, Random.Range(-1.0f, 1.0f) /* initial weight */, setRecurrent); m_vecLinks.Add(newGene); }