Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <summary>
        /// Retrieves the node information for all nodes in the genome.
        /// </summary>
        /// <returns>A dictionary of node id / node information pairs.</returns>
        public Dictionary <int, NodeInformation> GetAllNodeInformation(bool excludeFrozen)
        {
            List <Gene> genesToUse = Genes;

            if (excludeFrozen)
            {
                genesToUse = genesToUse.Where(x => !x.Frozen).ToList();
            }

            Dictionary <int, NodeInformation> IdSet = new Dictionary <int, NodeInformation>();

            foreach (var gene in genesToUse)
            {
                if (!IdSet.ContainsKey(gene.link.InNode))
                {
                    IdSet.Add(gene.link.InNode, NodePool.FindById(gene.link.InNode));
                }
                if (!IdSet.ContainsKey(gene.link.OutNode))
                {
                    IdSet.Add(gene.link.OutNode, NodePool.FindById(gene.link.OutNode));
                }
            }

            return(IdSet);
        }
Пример #3
0
        /// <summary>
        /// Mutates a genome by breaking a connection up into two separate connections.
        /// </summary>
        /// <param name="genome">The genome to be modified.</param>
        /// <param name="innovationsSeen">A list of previously seen innovations.</param>
        /// <param name="rando">A random number generator.</param>
        public static void MutateAddNode(Genome genome, InnovationPool innovationsSeen, Random rando)
        {
            List <Gene> possibleConnections = new List <Gene>(genome.Genes);

            possibleConnections.RemoveAll(x => x.Frozen || NodePool.FindById(x.link.InNode).Type == NodeType.BIAS);

            if (possibleConnections.Count == 0)
            {
                return;
            }

            //TODO: Note in original algorithm saying uniform distribution is not optimal here.
            Gene geneToSplit = possibleConnections[rando.Next(possibleConnections.Count)];

            geneToSplit.Frozen = true;

            ActivationStyle       style      = ActivationFunctions.ChooseActivationStyle(rando);
            InnovationInformation innovation = new InnovationInformation(geneToSplit.link, style);

            int firstConId  = -1;
            int secondConId = -1;

            int registeredInnovationId = innovationsSeen.FindByInnovation(innovation);

            if (registeredInnovationId == -1)
            {
                int newNodeId = NodePool.Add(new NodeInformation(NodeType.HIDDEN, style));

                ConnectionInformation firstConnect = new ConnectionInformation(geneToSplit.link.InNode, newNodeId);
                firstConId = ConnectionPool.Add(firstConnect);

                ConnectionInformation secondConnect = new ConnectionInformation(newNodeId, geneToSplit.link.OutNode);
                secondConId = ConnectionPool.Add(secondConnect);

                innovation.NewNodeDetails.NewNodeId          = newNodeId;
                innovation.NewNodeDetails.FirstConnectionId  = firstConId;
                innovation.NewNodeDetails.SecondConnectionId = secondConId;
                innovationsSeen.Add(innovation);
            }
            else
            {
                InnovationInformation registeredInnovation = innovationsSeen.FindById(registeredInnovationId);
                firstConId  = registeredInnovation.NewNodeDetails.FirstConnectionId;
                secondConId = registeredInnovation.NewNodeDetails.SecondConnectionId;
            }

            genome.Genes.Add(new Gene(ConnectionPool.FindById(firstConId), firstConId, 1.0, false));
            genome.Genes.Add(new Gene(ConnectionPool.FindById(secondConId), secondConId, geneToSplit.Weight, false));
        }
Пример #4
0
        /// <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);
        }