Exemple #1
0
        /// <summary>
        /// Returns a mated child of the mother and father genome.
        /// </summary>
        /// <param name="mother">A parent Genome.</param>
        /// <param name="father">A parent Genome.</param>
        /// <param name="rando">A random number generator.</param>
        /// <returns>A new genome based on the mating configuration.</returns>
        public static Genome Mate(Genome mother, Genome father, Random rando)
        {
            MatingStyle style = ChooseMatingStyle(rando);
            Genome      child;

            switch (style)
            {
            case MatingStyle.MultiPoint:
            case MatingStyle.MultiPointAverage:
                child = MateMultiPoint(style, mother, father, rando);
                break;

            case MatingStyle.SinglePoint:
                child = MateSinglePoint(style, mother, father, rando);
                break;

            default:
                throw new Exception("Mate function did not find a valid MatingStyle.");
            }

            return(child);
        }
Exemple #2
0
        /// <summary>
        /// Yarr... this be copied almost exactly as the original NEAT.
        /// In the original NEAT, none of the settings had chance this would happen.
        /// </summary>
        /// <param name="style">The specific type of multi-point mating style.</param>
        /// <param name="mother">A parent genome.</param>
        /// <param name="father">A parent genome.</param>
        /// <param name="rando">A random number generator.</param>
        /// <returns>A product of the given multi-point mating style.</returns>
        private static Genome MateSinglePoint(MatingStyle style, Genome mother, Genome father, Random rando)
        {
            mother.SortGenesByConnectionId();
            father.SortGenesByConnectionId();

            Genome largerParent  = mother;
            Genome smallerParent = father;

            if (father.Size() > mother.Size())
            {
                largerParent  = father;
                smallerParent = mother;
            }

            List <Gene> childGenes       = new List <Gene>();
            int         largerIndex      = 0;
            int         smallerIndex     = 0;
            int         crossoverPoint   = rando.Next(smallerParent.Size());
            int         crossoverCounter = 0;

            while (smallerParent.Size() != smallerIndex)
            {
                Gene chosenGene = new Gene();

                if (largerIndex == largerParent.Size())
                {
                    chosenGene.Copy(smallerParent.Genes[smallerIndex]);
                    smallerIndex++;
                }
                else if (smallerIndex == smallerParent.Size())
                {
                    //Should never happen
                    chosenGene.Copy(largerParent.Genes[largerIndex]);
                    largerIndex++;
                }
                else
                {
                    int largerGeneId  = largerParent.Genes[largerIndex].Id;
                    int smallerGeneId = smallerParent.Genes[smallerIndex].Id;

                    if (largerGeneId == smallerGeneId)
                    {
                        if (crossoverCounter < crossoverPoint)
                        {
                            chosenGene.Copy(largerParent.Genes[largerIndex]);
                        }
                        else if (crossoverCounter > crossoverPoint)
                        {
                            chosenGene.Copy(smallerParent.Genes[smallerIndex]);
                        }
                        else
                        {
                            switch (style)
                            {
                            case MatingStyle.SinglePoint:
                                //Function is equivalent to what is needed here despite the misleading name.
                                MateMultiPointAverage(chosenGene, largerParent.Genes[largerIndex], smallerParent.Genes[smallerIndex], rando);
                                break;

                            default:
                                throw new Exception("MateSinglePoint was not given a valid mating style.");
                            }
                        }


                        chosenGene.Frozen = false;
                        //The NEAT implementation did not call for a chance this would happen. It just did it. [ NEAT.1.2.1 => Genome::mate_singlepoint(...) ]
                        if (largerParent.Genes[largerIndex].Frozen || smallerParent.Genes[smallerIndex].Frozen)
                        {
                            chosenGene.Frozen = true;
                        }

                        largerIndex++;
                        smallerIndex++;
                        crossoverCounter++;
                    }
                    else if (largerGeneId < smallerGeneId)
                    {
                        if (crossoverCounter < crossoverPoint)
                        {
                            chosenGene.Copy(largerParent.Genes[largerIndex]);
                            largerIndex++;
                            crossoverCounter++;
                        }
                        else
                        {
                            chosenGene.Copy(smallerParent.Genes[smallerIndex]);
                            smallerIndex++;
                        }
                    }
                    else
                    {
                        smallerIndex++;
                        continue;
                    }
                }

                if (GeneIsUnique(chosenGene, childGenes))
                {
                    childGenes.Add(chosenGene);
                }
            }

            return(new Genome(childGenes));
        }
Exemple #3
0
        /// <summary>
        /// Logic for disjoint/excess genes between mother/father in multi-point mating styles.
        /// Delegates common genes to a more specific function.
        /// </summary>
        /// <param name="style">The specific type of multi-point mating style.</param>
        /// <param name="mother">A parent genome.</param>
        /// <param name="father">A parent genome.</param>
        /// <param name="rando">A random number generator.</param>
        /// <returns>A product of the given multi-point mating style.</returns>
        private static Genome MateMultiPoint(MatingStyle style, Genome mother, Genome father, Random rando)
        {
            mother.SortGenesByConnectionId();
            father.SortGenesByConnectionId();

            Genome strongerParent = mother;
            Genome weakerParent   = father;

            if (father.Fitness.Score > mother.Fitness.Score)
            {
                strongerParent = father;
                weakerParent   = mother;
            }

            List <Gene> childGenes    = new List <Gene>();
            int         strongerIndex = 0;
            int         weakerIndex   = 0;

            while (strongerIndex < strongerParent.Size() || weakerIndex < weakerParent.Size())
            {
                Gene chosenGene = new Gene();

                if (strongerIndex == strongerParent.Size())
                {
                    break;
                }
                else if (weakerIndex == weakerParent.Size())
                {
                    chosenGene.Copy(strongerParent.Genes[strongerIndex]);
                    strongerIndex++;
                }
                else
                {
                    int strongerGeneId = strongerParent.Genes[strongerIndex].Id;
                    int weakerGeneId   = weakerParent.Genes[weakerIndex].Id;

                    if (strongerGeneId == weakerGeneId)
                    {
                        switch (style)
                        {
                        case MatingStyle.MultiPoint:
                            MateMultiPointRegular(chosenGene, strongerParent.Genes[strongerIndex], weakerParent.Genes[weakerIndex], rando);
                            break;

                        case MatingStyle.MultiPointAverage:
                            MateMultiPointAverage(chosenGene, strongerParent.Genes[strongerIndex], weakerParent.Genes[weakerIndex], rando);
                            break;

                        default:
                            throw new Exception("MateMultiPoint was not given a valid mating style.");
                        }

                        //TODO: If both parents freeze their kid... should it be automatically frozen?
                        chosenGene.Frozen = false;
                        if (strongerParent.Genes[strongerIndex].Frozen && weakerParent.Genes[weakerIndex].Frozen)
                        {
                            chosenGene.Frozen = true;
                        }
                        else if (strongerParent.Genes[strongerIndex].Frozen || weakerParent.Genes[weakerIndex].Frozen)
                        {
                            if (rando.NextDouble() < FreezeGeneOfFrozenParentProbability)
                            {
                                chosenGene.Frozen = true;
                            }
                        }

                        strongerIndex++;
                        weakerIndex++;
                    }
                    else if (strongerGeneId < weakerGeneId)
                    {
                        chosenGene.Copy(strongerParent.Genes[strongerIndex]);
                        strongerIndex++;
                    }
                    else
                    {
                        weakerIndex++;
                        continue;
                    }
                }

                if (GeneIsUnique(chosenGene, childGenes))
                {
                    childGenes.Add(chosenGene);
                }
            }

            return(new Genome(childGenes));
        }