public bool[] Propagate(int[] inputs) { var inputNodes = InputNodes; if (inputs.Length != inputNodes.Count) { throw new Exception("Number of inputs does not match number of genome inputs"); } var connectionsToPropagate = ConnectionGenes.Values.Where(cg => cg.IsEnabled).ToList(); if (connectionsToPropagate.Count == 0) { return(OutputNodes.Select(x => x.Value > 0).ToArray()); } foreach (var node in NodeGenes.Values) { node.Value = 0; node.IsReady = false; } for (int i = 0; i < inputs.Length; i++) { inputNodes[i].Value = inputs[i]; inputNodes[i].IsReady = true; } while (connectionsToPropagate.Count != 0) { var propagatedConnections = new List <ConnectionGene>(); foreach (var connectionGene in connectionsToPropagate) { var previouesNode = NodeGenes[connectionGene.PreviousNodeId]; if (!previouesNode.IsReady) { continue; } var nextNode = NodeGenes[connectionGene.NextNodeId]; nextNode.Value += previouesNode.Value * connectionGene.Weight; propagatedConnections.Add(connectionGene); if (!connectionsToPropagate.Any(cg => cg.NextNodeId == connectionGene.NextNodeId && cg != connectionGene)) { nextNode.Value = ActivationFunctions.Sigmoid.Count(nextNode.Value); nextNode.IsReady = true; } } // No changes in propagation; Input values cannot be passed further if (propagatedConnections.Count == 0) { break; } foreach (var propagatedConnectionGene in propagatedConnections) { connectionsToPropagate.Remove(propagatedConnectionGene); } } return(OutputNodes.Select(x => x.Value > 0).ToArray()); }