/// <summary> /// Validates that a gene is connected to an input node. /// </summary> /// <param name="gene">The gene being validated.</param> /// <param name="pathsChecked">A list of genes that have been traversed in the recursion.</param> /// <param name="excludeFrozen">Exclude frozen genes from validation (true network).</param> /// <returns>True if the gene is connected to an input node.</returns> private bool ValidateGeneBackward(Gene gene, List <Gene> pathsChecked, bool excludeFrozen) { NodeInformation origin = NodePool.FindById(gene.link.InNode); pathsChecked.Add(gene); if (origin.IsInput()) { return(true); } foreach (var path in Genes.Where(x => x.link.OutNode == gene.link.InNode && !pathsChecked.Contains(x))) { if (excludeFrozen && path.Frozen) { continue; } if (ValidateGeneBackward(path, pathsChecked, excludeFrozen)) { return(true); } } return(false); }
public void MutateGeneReExpress() { List <IGene> unexpressedGenes = Genes.Where(g => !g.IsExpressed).ToList(); if (unexpressedGenes.Any()) { unexpressedGenes[new Random().Next(unexpressedGenes.Count)].MutateExpressionEnable(); } }
public IGene MutateAddGene(IEnumerable <IGene> genePool) { // Select two nodes at random to connect List <INode> nodeOutCandidates = Nodes.ToList(); if (!GenomeParameters.AllowOutputOutGenes) { nodeOutCandidates = nodeOutCandidates.Where(n => n.Type != NodeType.Output).ToList(); } INode nodeOut = nodeOutCandidates[new Random().Next(nodeOutCandidates.Count)]; // Get existing connections for this node List <IGene> existingConnectionsIn = Genes.Where(cg => cg.NodeIn == nodeOut).ToList(); List <IGene> existingConnectionsOut = Genes.Where(cg => cg.NodeOut == nodeOut).ToList(); // Discover nodes where no connection currently exists List <INode> nodeInCandidates = Nodes .Except(existingConnectionsIn.Select(g => g.NodeOut)) .Except(existingConnectionsOut.Select(g => g.NodeIn)).ToList(); // Don't allow input to input or output to output connections if (nodeOut.Type == NodeType.Input || nodeOut.Type == NodeType.Output) { nodeInCandidates = nodeInCandidates.Where(n => n.Type != nodeOut.Type).ToList(); } if (nodeOut.Type == NodeType.Hidden || nodeOut.Type == NodeType.Output) { nodeInCandidates = nodeInCandidates.Where(n => n.Type != NodeType.Input).ToList(); } if (nodeInCandidates.Count > 0) { INode selectedNodeIn = nodeInCandidates[new Random().Next(nodeInCandidates.Count)]; IGene existingGene = genePool.FirstOrDefault(gp => gp.NodeIn.Id == selectedNodeIn.Id && gp.NodeOut.Id == nodeOut.Id); // Create the connection IGene gene = new Gene( nodeOut, selectedNodeIn, existingGene != null ? existingGene.Innovation : GetNextInnovation() ); Genes.Add(gene); return(gene); } return(null); }
/// <summary> /// Remove a neuron from the network, including its connections. /// </summary> public Neuron RemoveNode(Neuron targetNeuron) { var genesToRemove = Genes.Where(x => x.StartNode == targetNeuron || x.EndNode == targetNeuron); foreach (var gene in genesToRemove) { gene.Disconnect(); } Genes = Genes.Except(genesToRemove).ToList(); Neurons.Remove(targetNeuron); return(targetNeuron); }
public double[] Activate(double[] inputs, Func <double, double> activator = null) { // Reset any previous activations Nodes.ToList().ForEach(n => n.ResetActivation()); // Activate all of our input nodes Nodes.Where(n => n.Type == NodeType.Input).ToList().ForEach(n => n.Activate(inputs[n.ActivationIndex])); // Traverse the network and activate each node List <INode> activationQueue = Nodes.Where(n => !n.IsActivated).ToList(); // Set Activator activator = activator ?? Activators.ReLU; while (activationQueue.Any()) { INode node = activationQueue.First(); List <IGene> genes = Genes.Where(g => g.NodeIn == node && g.IsExpressed).ToList(); activationQueue.Remove(node); // Remove any genes with unactivated Node Outs if (genes.Any(g => !g.NodeOut.IsActivated)) { genes.RemoveAll(g => !g.NodeOut.IsActivated); // Re-activate this node later activationQueue.Add(node); } node.Activate(activator(genes.Sum(g => g.Weight * g.NodeOut.Activation))); } return(Nodes.Where(n => n.Type == NodeType.Output) .OrderBy(n => n.ActivationIndex) .Select(n => n.Activation) .ToArray()); }
/// <summary> /// Validates that a gene is connected to an output node. /// </summary> /// <param name="gene">The gene being validated.</param> /// <param name="pathsChecked">A list of genes that have been traversed in the recursion.</param> /// <param name="excludeFrozen">Exclude frozen genes from validation (true network).</param> /// <returns>True if the gene is connected to an output node.</returns> private bool ValidateGeneForward(Gene gene, List <Gene> pathsChecked, bool excludeFrozen) { pathsChecked.Add(gene); if (NodePool.FindById(gene.link.OutNode).Type == NodeType.OUTPUT) { return(true); } foreach (var path in Genes.Where(x => x.link.InNode == gene.link.OutNode && !pathsChecked.Contains(x))) { if (excludeFrozen && path.Frozen) { continue; } if (ValidateGeneForward(path, pathsChecked, excludeFrozen)) { return(true); } } return(false); }
public List <IGene> GetExpressedGenesByNodeOut(INode nodeOut) { return(Genes.Where(g => g.NodeOut == nodeOut && g.IsExpressed).ToList()); }