Beispiel #1
0
        /**
         * In NEAT, we provide the algorithm with a start individual from file,
         * after read the start individual from file, we populate the subpopulation with
         * mutated version of that template individual. The number of individual we create is
         * determined by the "pop.subpop.X.size" parameter.
         */
        public override Population InitialPopulation(IEvolutionState state, int thread)
        {
            // read in the start genome as the template
            Population p = SetupPopulation(state, thread);

            p.Populate(state, thread);

            // go through all the population and populate the NEAT subpop
            foreach (Subpopulation subpop in p.Subpops)
            {
                // NEAT uses a template to populate the population
                // we first read it in to form the population, then mutate the links
                if (subpop.Species is NEATSpecies)
                {
                    NEATSpecies species = (NEATSpecies)subpop.Species;

                    IList <Individual> inds = subpop.Individuals;
                    // get the template
                    NEATIndividual templateInd = (NEATIndividual)inds[0];
                    // clear the individuals
                    inds.Clear();

                    // spawn the individuals with template
                    int initialSize = subpop.InitialSize;
                    for (int j = 0; j < initialSize; ++j)
                    {
                        NEATIndividual newInd = species.SpawnWithTemplate(state, species, thread, templateInd);
                        inds.Add(newInd);
                    }

                    // state.output.warnOnce("Template genome found, populate the subpopulation with template individual");
                    // templateInd.printIndividual(state, 0);

                    // set the next available innovation number and node id
                    species.SetInnovationNumber(templateInd.GetGeneInnovationNumberSup());
                    species.CurrNodeId = templateInd.GetNodeIdSup();

                    // speciate
                    foreach (Individual ind in inds)
                    {
                        species.Speciate(state, ind);
                    }

                    // switch to the new generation
                    foreach (NEATSubspecies s in species.Subspecies)
                    {
                        s.ToNewGeneration();
                    }
                }
            }

            return(p);
        }
Beispiel #2
0
        /** Spawn a new individual with given individual as template. */
        public NEATIndividual SpawnWithTemplate(IEvolutionState state, NEATSpecies species, int thread, NEATIndividual ind)
        {
            // we clone but do not reset the individual, since these individuals are
            // made from template
            NEATIndividual newInd = (NEATIndividual)ind.Clone();

            // for first generation of population, we do not use the weight mutation
            // power from the file
            newInd.MutateLinkWeights(state, thread, species, 1.0, 1.0, NEATSpecies.MutationType.GAUSSIAN);
            newInd.SetGeneration(state);
            newInd.CreateNetwork(); // we create the network after we have the
            // complete genome
            return(newInd);
        }
Beispiel #3
0
        /**
         * This method simply call breedNewPopulation method in NEATSpecies,where
         * all the critical work in done.
         */
        public override Population BreedPopulation(IEvolutionState state)
        {
            Population pop = state.Population;

            for (int i = 0; i < pop.Subpops.Count; i++)
            {
                Subpopulation subpop = pop.Subpops[i];
                if (!(subpop.Species is NEATSpecies)) // uh oh
                {
                    state.Output.Fatal("To use NEATSpecies, subpopulation " + i
                                       + " must contain a NEATSpecies.  But it contains a " + subpop.Species);
                }

                NEATSpecies species = (NEATSpecies)subpop.Species;



                species.BreedNewPopulation(state, i, 0);
            }

            return(pop);
        }
Beispiel #4
0
        /**
         * Where the actual reproduce is happening, it will grab the candidate
         * parents, and calls the crossover or mutation method on these parents
         * individuals.
         */
        public bool Reproduce(IEvolutionState state, int thread, int subpop, IList <NEATSubspecies> sortedSubspecies)
        {
            if (ExpectedOffspring > 0 && Individuals.Count == 0)
            {
                state.Output.Fatal("Attempt to reproduce out of empty subspecies");
                return(false);
            }

            if (ExpectedOffspring > state.Population.Subpops[subpop].InitialSize)
            {
                state.Output.Fatal("Attempt to reproduce too many individuals");
                return(false);
            }

            NEATSpecies species = (NEATSpecies)state.Population.Subpops[subpop].Species;

            // bestIndividual of the 'this' specie is the first element of the
            // species
            // note, we already sort the individuals based on the fitness (not sure
            // if this is still correct to say)
            NEATIndividual bestIndividual = (NEATIndividual)First();



            // create the designated number of offspring for the Species one at a
            // time
            bool bestIndividualDone = false;

            for (int i = 0; i < ExpectedOffspring; ++i)
            {
                NEATIndividual newInd;

                if (bestIndividual.SuperChampionOffspring > 0)
                {
                    newInd = (NEATIndividual)bestIndividual.Clone();

                    // Most super champion offspring will have their connection
                    // weights mutated only
                    // The last offspring will be an exact duplicate of this super
                    // champion
                    // Note: Super champion offspring only occur with stolen babies!
                    // Settings used for published experiments did not use this

                    if (bestIndividual.SuperChampionOffspring > 1)
                    {
                        if (state.Random[thread].NextBoolean(0.8) || species.MutateAddLinkProb.Equals(0.0))
                        {
                            newInd.MutateLinkWeights(state, thread, species, species.WeightMutationPower, 1.0,
                                                     NEATSpecies.MutationType.GAUSSIAN);
                        }
                        else
                        {
                            // Sometime we add a link to a superchamp
                            newInd.CreateNetwork(); // make sure we have the network
                            newInd.MutateAddLink(state, thread);
                        }
                    }
                    if (bestIndividual.SuperChampionOffspring == 1)
                    {
                        if (bestIndividual.PopChampion)
                        {
                            newInd.PopChampionChild = true;
                            newInd.HighFit          = bestIndividual.Fitness.Value;
                        }
                    }

                    bestIndividual.SuperChampionOffspring--;
                }
                else if (!bestIndividualDone && ExpectedOffspring > 5)
                {
                    newInd             = (NEATIndividual)bestIndividual.Clone();
                    bestIndividualDone = true;
                }
                // Decide whether to mate or mutate
                // If there is only one individual, then always mutate
                else if (state.Random[thread].NextBoolean(species.MutateOnlyProb) || Individuals.Count == 1)
                {
                    // Choose the random parent
                    int        parentIndex = state.Random[thread].NextInt(Individuals.Count);
                    Individual parent      = Individuals[parentIndex];
                    newInd = (NEATIndividual)parent.Clone();


                    newInd.DefaultMutate((EvolutionState)state, thread);
                }
                else // Otherwise we should mate
                {
                    // random choose the first parent
                    int            parentIndex = state.Random[thread].NextInt(Individuals.Count);
                    NEATIndividual firstParent = (NEATIndividual)Individuals[parentIndex];
                    NEATIndividual secondParent;
                    // Mate within subspecies, choose random second parent
                    if (state.Random[thread].NextBoolean(1.0 - species.InterspeciesMateRate))
                    {
                        parentIndex  = state.Random[thread].NextInt(Individuals.Count);
                        secondParent = (NEATIndividual)Individuals[parentIndex];
                    }
                    else // Mate outside subspecies
                    {
                        // Select a random species
                        NEATSubspecies randomSubspecies = this;
                        // Give up if you cant find a different Species
                        int giveUp = 0;
                        while (randomSubspecies == this && giveUp < 5)
                        {
                            // Choose a random species tending towards better
                            // species
                            double value = state.Random[thread].NextGaussian() / 4;
                            if (value > 1.0)
                            {
                                value = 1.0;
                            }
                            // This tends to select better species

                            int upperBound = (int)Math.Floor(value * (sortedSubspecies.Count - 1.0) + 0.5);
                            int index      = 0;
                            while (index < upperBound)
                            {
                                index++;
                            }
                            randomSubspecies = sortedSubspecies[index];
                            giveUp++;
                        }

                        secondParent = (NEATIndividual)randomSubspecies.First();
                    }

                    newInd = firstParent.Crossover(state, thread, secondParent);


                    // Determine whether to mutate the baby's Genome
                    // This is done randomly or if the parents are the same
                    // individual
                    if (state.Random[thread].NextBoolean(1.0 - species.MateOnlyProb) || firstParent == secondParent ||
                        species.Compatibility(firstParent, secondParent).Equals(0.0))
                    {
                        newInd.DefaultMutate((EvolutionState)state, thread);
                    }
                }



                newInd.SetGeneration(state);
                newInd.CreateNetwork();

                // Add the new individual to its proper subspecies
                // this could create new subspecies
                species.Speciate(state, newInd);
            }



            return(true);
        }