Ejemplo n.º 1
0
 public override void InitializePopulation()
 {
     population.Initialize();
     bestAchieved    = population.GetBestIndividual();
     biggestAchieved = population.GetBiggestIndividual();
 }
Ejemplo n.º 2
0
 public static bool isMoreThanConnectionsIn(this int limit, NEATIndividual indie1, NEATIndividual indie2)
 {
     return(indie1.genome.connectionGenes.Count < limit && indie2.genome.connectionGenes.Count < limit);
 }
Ejemplo n.º 3
0
        public static float DifferenceTo(this NEATIndividual indie1, NEATIndividual indie2)
        {
            float difference = 0.0f;

            float excessVar         = 0.0f;
            float disjointVar       = 0.0f;
            float functionVar       = 0.0f;
            float weightDiffSum     = 0.0f;
            int   sameConnGeneCount = 0;

            var shortestNodeSequence = indie1.genome.nodeGenes.Count < indie2.genome.nodeGenes.Count ? indie1.genome.nodeGenes.Count : indie2.genome.nodeGenes.Count;
            var nodes1    = indie1.genome.nodeGenes;
            var nodes2    = indie2.genome.nodeGenes;
            int nodeIndex = 0;

            while (nodeIndex < shortestNodeSequence)
            {
                var node1 = nodes1[nodeIndex];
                var node2 = nodes2[nodeIndex];
                if (node1.geneID == node2.geneID)
                {
                    if (node1.type == NodeType.Hidden)
                    {
                        if (node2.type != NodeType.Hidden)
                        {
                            throw new Exception("gene describing totally different things");
                        }
                        else
                        {
                            functionVar += ActivationFunction.GetFunctionDifference(((HiddenNodeGene)node1).Function.Type, ((HiddenNodeGene)node2).Function.Type);
                        }
                    }
                }
                else
                {
                    difference += 0.1f;
                }
                nodeIndex++;
            }

            var longestGeneSequence  = NeatGenome.GetMostConnected(indie1.genome, indie2.genome).connectionGenes;
            var shortestGeneSequence = NeatGenome.GetLeastConnected(indie1.genome, indie2.genome).connectionGenes;

            int disjointID = shortestGeneSequence[shortestGeneSequence.Count - 1].geneID;


            int shortIndex = 0;

            foreach (ConnectionGene gene in longestGeneSequence)
            {
                if (shortIndex < shortestGeneSequence.Count)
                {
                    var shortGene = shortestGeneSequence[shortIndex];
                    if (gene.geneID == shortGene.geneID)
                    {
                        sameConnGeneCount++;
                        weightDiffSum += gene.GetWeightDifference(shortGene);
                    }
                    else
                    {
                        if (gene.geneID < disjointID)
                        {
                            disjointID++;
                        }
                        else if (gene.geneID > disjointID)
                        {
                            excessVar++;
                        }
                    }
                }
                else
                {
                    if (gene.geneID < disjointID)
                    {
                        disjointID++;
                    }
                    else if (gene.geneID > disjointID)
                    {
                        excessVar++;
                    }
                    else
                    {
                        sameConnGeneCount++;
                        weightDiffSum += gene.GetWeightDifference(shortestGeneSequence[shortestGeneSequence.Count - 1]);
                    }
                }
                shortIndex++;
            }

            int N = 1;

            if (!EAParameters.SetNToOneLimit.isMoreThanConnectionsIn(indie1, indie2))
            {
                N = longestGeneSequence.Count;
            }
            excessVar   /= N;
            disjointVar /= N;

            difference += excessVar * EAParameters.ExcessSimilarityWeight;
            difference += disjointVar * EAParameters.DisjointSimilarityWeight;
            difference += functionVar * EAParameters.FunctionSimilarityWeight;
            difference += (weightDiffSum / sameConnGeneCount) * EAParameters.WeightDifferenceSimilarityWeight;
            return(difference);
        }
Ejemplo n.º 4
0
 /** Add the individual to the next generation of this subspecies */
 public void AddNewGenIndividual(NEATIndividual neatInd)
 {
     NewGenIndividuals.Add(neatInd);
     neatInd.Subspecies = this;
 }
Ejemplo n.º 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);
        }
Ejemplo n.º 6
0
        public virtual void Evaluate(IEvolutionState state, Individual ind, int subpopulation, int threadnum)
        {
            if (ind.Evaluated)
            {
                return;
            }

            if (!(ind is NEATIndividual))
            {
                state.Output.Fatal("Whoa! It's not a NEATIndividual!!!", null);
            }

            NEATIndividual neatInd = (NEATIndividual)ind;

            if (!(neatInd.Fitness is SimpleFitness))
            {
                state.Output.Fatal("Whoa! It's not a SimpleFitness!!!", null);
            }

            //The four possible input combinations to xor
            //The first number is for biasing
            double[][] input =
            {
                new [] { 1.0, 0.0, 0.0 }, // output 0
                new [] { 1.0, 0.0, 1.0 }, //        1
                new [] { 1.0, 1.0, 0.0 }, //        1
                new [] { 1.0, 1.0, 1.0 }, //        0
            };

            double[] output      = new double[4];
            double[] expectedOut = { 0.0, 1.0, 1.0, 0.0 };

            NEATNetwork net = neatInd.CreateNetwork();

            int netDepth = net.MaxDepth();

            // Load and activate the network on each input
            for (int i = 0; i < input.Length; i++)
            {
                net.LoadSensors(input[i]);

                for (int relax = 0; relax < netDepth; relax++)
                {
                    net.Activate(state);
                }

                // only have one output, so let's get it
                output[i] = net.GetOutputResults()[0];

                net.Flush();
            }


            // calculate fitness

            double errorSum = 0;

            for (int i = 0; i < output.Length; i++)
            {
                errorSum += Math.Abs(output[i] - expectedOut[i]);
            }

            double fitness = (4.0 - errorSum) * (4.0 - errorSum);

            // this is from the original code for counting as ideal
            bool ideal = true;

            for (int i = 0; i < output.Length; i++)
            {
                if (Math.Abs(output[i] - expectedOut[i]) > 0.5)
                {
                    ideal = false;
                    break;
                }
            }

            ((SimpleFitness)neatInd.Fitness).SetFitness(state, fitness, ideal);
            neatInd.Evaluated = true;
        }
Ejemplo n.º 7
0
        /**
         * This function gives a measure of compatibility between two Genomes by
         * computing a linear combination of 3 characterizing variables of their
         * compatibilty. The 3 variables represent PERCENT DISJOINT GENES, PERCENT
         * EXCESS GENES, MUTATIONAL DIFFERENCE WITHIN MATCHING GENES. So the formula
         * for compatibility is:
         * disjointCoeff*numDisjoint+excessCoeff*numExcess+mutdiffCoeff*numMatching.
         */
        public double Compatibility(NEATIndividual a, NEATIndividual b)
        {
            int    numExcess    = 0;
            int    numMatching  = 0;
            int    numDisjoint  = 0;
            double mutTotalDiff = 0.0;
            // pointer for two genome
            int i = 0, j = 0;

            while (!(i == a.genome.Length && j == b.genome.Length))
            {
                // if genome a is already finished, move b's pointer
                if (i == a.genome.Length)
                {
                    j++;
                    numExcess++;
                }
                // if genome b is already finished, move a's pointer
                else if (j == b.genome.Length)
                {
                    i++;
                    numExcess++;
                }
                else
                {
                    int aInno = ((NEATGene)a.genome[i]).InnovationNumber;
                    int bInno = ((NEATGene)b.genome[j]).InnovationNumber;
                    if (aInno == bInno)
                    {
                        numMatching++;
                        double mutDiff = Math.Abs(((NEATGene)a.genome[i]).MutationNumber -
                                                  ((NEATGene)b.genome[j]).MutationNumber);
                        mutTotalDiff += mutDiff;
                        i++;
                        j++;
                    }
                    // innovation number do not match, skip this one
                    else if (aInno < bInno)
                    {
                        i++;
                        numDisjoint++;
                    }
                    else if (bInno < aInno)
                    {
                        j++;
                        numDisjoint++;
                    }
                }
            }

            // Return the compatibility number using compatibility formula
            // Note that mutTotalDiff/numMatching gives the AVERAGE
            // difference between mutationNums for any two matching Genes
            // in the Genome

            // We do not normalize the terms in here due to the following reason

            // If you decide to use the species compatibility coefficients and
            // thresholds from my own .ne settings files (provided with my NEAT
            // release), then do not normalize the terms in the compatibility
            // function, because I did not do this with my .ne files. In other
            // words, even though my papers suggest normalizing (dividing my number
            // of genes), since I didn't do that the coefficients that I used will
            // not work the same for you if you normalize. If you strongly desire to
            // normalize, you will need to find your own appropriate coefficients
            // and threshold.

            // see the comments above on NEAT page
            // https://www.cs.ucf.edu/~kstanley/neat.html

            // Normalizing for genome size
            // return (disjointCoeff*(numDisjoint/maxGenomeSize)+
            // excessCoeff*(numExcess/maxGenomeSize)+
            // mutDiffCoeff*(mutTotalDiff/numMatching));

            double compatibility = DisjointCoeff * (numDisjoint / 1.0);

            compatibility += ExcessCoeff * (numExcess / 1.0);
            compatibility += MutDiffCoeff * (mutTotalDiff / ((double)numMatching));



            return(compatibility);
        }
Ejemplo n.º 8
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);
        }