Пример #1
0
        /** Perform a delta coding. */
        public void DeltaCoding(IEvolutionState state, int subpop, IList <NEATSubspecies> sortedSubspecies)
        {
            HighestLastChanged = 0;

            int popSize = state.Population.Subpops[subpop].InitialSize;
            int halfPop = popSize / 2;

            NEATSubspecies bestFitnessSubspecies = sortedSubspecies[0];

            // the first individual of the first subspecies can have 1/2 pop size
            // offsprings
            ((NEATIndividual)bestFitnessSubspecies.First()).SuperChampionOffspring = halfPop;
            // the first subspecies can have 1/2 pop size offspring
            bestFitnessSubspecies.ExpectedOffspring    = halfPop;
            bestFitnessSubspecies.AgeOfLastImprovement = bestFitnessSubspecies.Age;

            if (sortedSubspecies.Count >= 2)
            {
                // the second subspecies can have the other half pop size
                ((NEATIndividual)sortedSubspecies[1].First()).SuperChampionOffspring = popSize - halfPop;
                sortedSubspecies[1].ExpectedOffspring    = popSize - halfPop;
                sortedSubspecies[1].AgeOfLastImprovement = sortedSubspecies[1].Age;
                // the remainder subspecies has 0 offsprings
                for (int i = 2; i < sortedSubspecies.Count; ++i)
                {
                    sortedSubspecies[i].ExpectedOffspring = 0;
                }
            }
            else
            {
                ((NEATIndividual)bestFitnessSubspecies.First()).SuperChampionOffspring += popSize - halfPop;
                bestFitnessSubspecies.ExpectedOffspring = popSize - halfPop;
            }
        }
Пример #2
0
        /**
         * Return a clone of this subspecies, but with a empty individuals and
         * newGenIndividuals list.
         */
        public virtual object EmptyClone()
        {
            NEATSubspecies myobj = (NEATSubspecies)Clone();

            Individuals       = new List <Individual>();
            NewGenIndividuals = new List <Individual>();
            return(myobj);
        }
Пример #3
0
        public virtual object Clone()
        {
            NEATSubspecies myobj = null;

            try
            {
                myobj     = (NEATSubspecies)MemberwiseClone();
                myobj.Age = Age;
                myobj.AgeOfLastImprovement = AgeOfLastImprovement;
                myobj.MaxFitnessEver       = MaxFitnessEver;
                myobj.ExpectedOffspring    = ExpectedOffspring;
            }
            catch (CloneNotSupportedException e) // never happens
            {
                throw new InvalidOperationException();
            }
            return(myobj);
        }
Пример #4
0
        /** Assign the individual into a species, if not found, create a new one */
        public void Speciate(IEvolutionState state, Individual ind)
        {
            NEATIndividual neatInd = (NEATIndividual)ind;

            // For each individual, search for a subspecies it is compatible to
            if (Subspecies.Count == 0) // not subspecies available, create the
            // first species
            {
                NEATSubspecies newSubspecies = (NEATSubspecies)SubspeciesPrototype.EmptyClone();
                newSubspecies.Reset();
                Subspecies.Add(newSubspecies);
                newSubspecies.AddNewGenIndividual(neatInd);
            }
            else
            {
                bool found = false;
                foreach (NEATSubspecies s in Subspecies)
                {
                    NEATIndividual represent = (NEATIndividual)s.NewGenerationFirst();
                    if (represent == null)
                    {
                        represent = (NEATIndividual)s.First();
                    }

                    // found compatible subspecies, add this individual to it
                    if (Compatibility(neatInd, represent) < CompatThreshold)
                    {
                        s.AddNewGenIndividual(neatInd);
                        found = true; // change flag
                        break;        // search is over, quit loop
                    }
                }
                // if we didn't find a match, create a new subspecies
                if (!found)
                {
                    NEATSubspecies newSubspecies = (NEATSubspecies)SubspeciesPrototype.EmptyClone();
                    newSubspecies.Reset();
                    Subspecies.Add(newSubspecies);
                    newSubspecies.AddNewGenIndividual(neatInd);
                }
            }
        }
Пример #5
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);
        }
Пример #6
0
        /** Steal the babies from champion subspecies. */
        public void StealBabies(IEvolutionState state, int thread, int subpop, IList <NEATSubspecies> sortedSubspecies)
        {
            // Take away a constant number of expected offspring from the worst few
            // species
            int babiesAlreadyStolen = 0;

            for (int i = sortedSubspecies.Count - 1; i >= 0 && babiesAlreadyStolen < BabiesStolen; i--)
            {
                NEATSubspecies subs = sortedSubspecies[i];

                if (subs.Age > 5 && subs.ExpectedOffspring > 2)
                {
                    // This subspecies has enough to finish off the stolen pool
                    int babiesNeeded = BabiesStolen - babiesAlreadyStolen;
                    if (subs.ExpectedOffspring - 1 >= babiesNeeded)
                    {
                        subs.ExpectedOffspring -= babiesNeeded;
                        babiesAlreadyStolen     = BabiesStolen;
                    }
                    // Not enough here to complete the pool of stolen, then leave
                    // one individual
                    // for that subspecies
                    else
                    {
                        babiesAlreadyStolen   += subs.ExpectedOffspring - 1;
                        subs.ExpectedOffspring = 1;
                    }
                }
            }

            // Mark the best champions of the top subspecies to be the super
            // champions
            // who will take on the extra offspring for cloning or mutant cloning
            // Determine the exact number that will be given to the top three
            // They get, in order, 1/5 1/5 and 1/10 of the already stolen babies
            int[] quote = new int[3];
            quote[0] = quote[1] = BabiesStolen / 5;
            quote[2] = BabiesStolen / 10;

            int quoteIndex = 0;

            foreach (var subs in sortedSubspecies)
            {
                // Don't give to dying species even if they are champions
                if (subs.TimeSinceLastImproved() <= DropoffAge)
                {
                    if (quoteIndex < quote.Length)
                    {
                        if (babiesAlreadyStolen > quote[quoteIndex])
                        {
                            ((NEATIndividual)subs.First()).SuperChampionOffspring = quote[quoteIndex];
                            subs.ExpectedOffspring += quote[quoteIndex];
                            babiesAlreadyStolen    -= quote[quoteIndex];
                        }
                        quoteIndex++;
                    }
                    else if (quoteIndex >= quote.Length)
                    {
                        // Randomize a little which species get boosted by a super
                        // champion
                        if (state.Random[thread].NextBoolean(.9))
                        {
                            if (babiesAlreadyStolen > 3)
                            {
                                ((NEATIndividual)subs.First()).SuperChampionOffspring = 3;
                                subs.ExpectedOffspring += 3;
                                babiesAlreadyStolen    -= 3;
                            }
                            else
                            {
                                ((NEATIndividual)subs.First()).SuperChampionOffspring = babiesAlreadyStolen;
                                subs.ExpectedOffspring += babiesAlreadyStolen;
                                babiesAlreadyStolen     = 0;
                            }
                        }
                    }
                    // assiged all the stolen babies
                    if (babiesAlreadyStolen == 0)
                    {
                        break;
                    }
                }
            }


            // If any stolen babies aren't taken, give them to species #1's champion
            if (babiesAlreadyStolen > 0)
            {
                state.Output.Message("Not all stolen babies assigned, giving to the best subspecies");
                NEATSubspecies subs = Subspecies[0];
                ((NEATIndividual)subs.First()).SuperChampionOffspring += babiesAlreadyStolen;
                subs.ExpectedOffspring += babiesAlreadyStolen;
                babiesAlreadyStolen     = 0;
            }
        }
Пример #7
0
        /** Determine the offsprings for all the subspecies. */
        public void CountOffspring(IEvolutionState state, int subpop)
        {
            // Go through the organisms and add up their adjusted fitnesses to
            // compute the overall average
            double             total = 0.0;
            IList <Individual> inds  = state.Population.Subpops[subpop].Individuals;

            foreach (Individual s in inds)
            {
                total += ((NEATIndividual)s).AdjustedFitness;
            }

            double overallAverage = total / inds.Count;

            // Now compute expected number of offspring for each individual organism
            foreach (Individual i in inds)
            {
                ((NEATIndividual)i).ExpectedOffspring = ((NEATIndividual)i).AdjustedFitness
                                                        / overallAverage;
            }

            // Now add those offsprings up within each Subspecies to get the number
            // of
            // offspring per subspecies
            double skim          = 0.0;
            int    totalExpected = 0;

            foreach (NEATSubspecies s in Subspecies)
            {
                skim           = s.CountOffspring(skim);
                totalExpected += s.ExpectedOffspring;
            }



            // Need to make up for lost floating point precision in offspring
            // assignment. If we lost precision, give an extra baby to the best
            // subpecies
            if (totalExpected < inds.Count)
            {
                // Find the subspecies expecting the most
                int            maxExpected   = 0;
                int            finalExpected = 0;
                NEATSubspecies best          = null;
                foreach (NEATSubspecies s in Subspecies)
                {
                    if (s.ExpectedOffspring >= maxExpected)
                    {
                        maxExpected = s.ExpectedOffspring;
                        best        = s;
                    }
                    finalExpected += s.ExpectedOffspring;
                }

                // Give the extra offspring to the best subspecies
                // TODO: BRS: Handle possible null value!
                best.ExpectedOffspring++;
                finalExpected++;

                // If we still aren't at total, there is a problem
                // Note that this can happen if a stagnant subpecies
                // dominates the population and then gets killed off by its age
                // Then the whole population plummets in fitness
                // If the average fitness is allowed to hit 0, then we no longer
                // have an average we can use to assign offspring.
                if (finalExpected < inds.Count)
                {
                    state.Output.WarnOnce("Population has died");
                    foreach (NEATSubspecies s in Subspecies)
                    {
                        s.ExpectedOffspring = 0;
                    }
                    best.ExpectedOffspring = inds.Count;
                }
            }
        }