Ejemplo n.º 1
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));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates an initial population.
        /// </summary>
        /// <param name="nodes">A list of NodeType-ActivationStyle pairing. The node Id will be the position in the list.</param>
        /// <param name="connections">A list of InNodeId-OutNodeId-Weight tuples.</param>
        /// <param name="populationSize">The size of the population to test.</param>
        /// <param name="rando">A random number generator for perturbing the weights.</param>
        public Population(List <Tuple <NodeType, ActivationStyle> > nodes, List <Tuple <int, int, double> > connections, int populationSize, Random rando)
        {
            TargetPopulationSize = populationSize;
            ValidateConstructorParameters(nodes.Count, connections);

            for (int i = 0; i < nodes.Count; i++)
            {
                NodePool.Add(new NodeInformation(nodes[i].Item1, nodes[i].Item2));
            }

            List <Gene> startGenes = new List <Gene>();

            foreach (var tupe in connections)
            {
                ConnectionInformation ci = new ConnectionInformation(tupe.Item1, tupe.Item2);
                startGenes.Add(new Gene(ci, ConnectionPool.Size(), tupe.Item3, false));

                InnovationInformation info = new InnovationInformation(ci);
                info.NewConnectionDetails.ConnectionId = ConnectionPool.Size();
                GenerationalInnovations.Add(info);

                ConnectionPool.Add(ci);
            }

            Genome        adam     = new Genome(startGenes);
            List <Genome> firstGen = new List <Genome>()
            {
                adam
            };

            for (int i = 1; i < TargetPopulationSize; i++)
            {
                Genome copy = new Genome(adam);
                Mutation.MutateTryAllNonStructural(copy, rando);
                firstGen.Add(copy);
            }

            SpeciateNewGeneration(firstGen);
        }