/// <summary> /// Approves a node gene for inclusion in the child chromosome. /// </summary> /// <param name="selected">The selected edge gene.</param> /// <param name="approvedNodeGenes">The approved node genes.</param> /// <param name="seen">The node gene seen tracker.</param> private void ApproveNodeGenes(NeuralChromosome.EdgeGene selected, ref List <NeuralChromosome.NodeGene> approvedNodeGenes, ref bool[] seen) { if (!seen[selected.Input.ID]) { approvedNodeGenes.Add(selected.Input); seen[selected.Input.ID] = true; } if (!seen[selected.Output.ID]) { approvedNodeGenes.Add(selected.Output); seen[selected.Output.ID] = true; } }
/// <summary> /// Internal invocation the mutation operator. /// </summary> /// <param name="chromosome">The chromosome.</param> /// <returns>The new DNA.</returns> protected override IChromosome InternalInvoke(NeuralChromosome chromosome) { var innovationTracker = NeuralChromosome.GetInnovationTracker(chromosome.InnovationTrackerName); var genes = chromosome.CloneGenes(); var nodeGenes = genes.Item1; var edgeGenes = genes.Item2; //No edge genes in the genotype yet. Return original chromosome. if (edgeGenes.Count == 0) { return(new NeuralChromosome(nodeGenes, edgeGenes, chromosome.InnovationTrackerName, chromosome.C1, chromosome.C2, chromosome.C3, chromosome.ActivationFunction)); } var index = Session.Instance.Stochastic.Next(edgeGenes.Count); var selectedEdge = edgeGenes[index]; var sourceNode = selectedEdge.Input; var targetNode = selectedEdge.Output; selectedEdge.Enabled = false; var nodeId = innovationTracker.GetNextNodeInnovationNumber(selectedEdge.ID); var newNode = new NeuralChromosome.NodeGene(nodeId, NeuralChromosome.NodeGene.NodeType.Hidden); var edgeId1 = innovationTracker.GetNextEdgeInnovationNumber(sourceNode.ID, newNode.ID); var newEdge1 = new NeuralChromosome.EdgeGene(edgeId1, selectedEdge.Input, newNode, 1, true); var edgeId2 = innovationTracker.GetNextEdgeInnovationNumber(newNode.ID, targetNode.ID); var newEdge2 = new NeuralChromosome.EdgeGene(edgeId2, newNode, selectedEdge.Output, selectedEdge.Weight, true); nodeGenes.Add(newNode); edgeGenes.Add(newEdge1); edgeGenes.Add(newEdge2); return(new NeuralChromosome(nodeGenes, edgeGenes, chromosome.InnovationTrackerName, chromosome.C1, chromosome.C2, chromosome.C3, chromosome.ActivationFunction)); }
/// <summary> /// Internal invocation the mutation operator. /// </summary> /// <param name="chromosome">The chromosome.</param> /// <returns>The new DNA.</returns> protected override IChromosome InternalInvoke(NeuralChromosome chromosome) { var innovationTracker = NeuralChromosome.GetInnovationTracker(chromosome.InnovationTrackerName); var genes = chromosome.CloneGenes(); var nodeGenes = genes.Item1; var edgeGenes = genes.Item2; var sourceIndex = Session.Instance.Stochastic.Next(nodeGenes.Count); var source = nodeGenes[sourceIndex]; var targetIndex = Session.Instance.Stochastic.Next(nodeGenes.Count); var target = nodeGenes[targetIndex]; var index = targetIndex; while (edgeGenes.Any(edge => edge.Input == source && edge.Output == target)) { index = (index + 1) % nodeGenes.Count; target = nodeGenes[index]; // Source node connects to all other nodes. Return original chromosome. if (index == targetIndex) { return(new NeuralChromosome(nodeGenes, edgeGenes, chromosome.InnovationTrackerName, chromosome.C1, chromosome.C2, chromosome.C3, chromosome.ActivationFunction)); } } var edgeId = innovationTracker.GetNextEdgeInnovationNumber(source.ID, target.ID); var weight = Session.Instance.Stochastic.NextDouble(); var newEdge = new NeuralChromosome.EdgeGene(edgeId, source, target, weight, true); edgeGenes.Add(newEdge); return(new NeuralChromosome(nodeGenes, edgeGenes, chromosome.InnovationTrackerName, chromosome.C1, chromosome.C2, chromosome.C3, chromosome.ActivationFunction)); }