Example #1
0
        /// <summary>
        /// Crossover 2 Genomes
        /// </summary>
        /// <param name="moreFitParent">Parent with the most Fitness of the 2 Parents</param>
        /// <param name="lessFitParent">Second Parent</param>
        /// <param name="r">Random</param>
        /// <param name="disabledConnectionInheritChance">Disabled Connection Inherit Chance</param>
        /// <returns>Child Genome</returns>
        public static Genome Crossover(Genome moreFitParent, Genome lessFitParent, Random r, float disabledConnectionInheritChance)
        {
            Genome child = new Genome(moreFitParent.NewWeightRange, moreFitParent.PerturbingProbability);

            // Add More Fit Parent Nodes to Child
            foreach (NodeGene moreFitParentNode in moreFitParent.Nodes.Values)
            {
                child.AddNodeGene(new NodeGene(moreFitParentNode));
            }

            // Add a mix of Parents Connections to Child
            foreach (ConnectionGene moreFitParentConnection in moreFitParent.Connections.Values)
            {
                ConnectionGene childConnectionGene = null;

                if (lessFitParent.Connections.ContainsKey(moreFitParentConnection.InnovationId))    // Matching Connection => Select randomly one of the parents Connection
                {
                    ConnectionGene lessFitParentConnection = lessFitParent.Connections[moreFitParentConnection.InnovationId];
                    bool           disabled = !moreFitParentConnection.IsEnable || !lessFitParentConnection.IsEnable;
                    childConnectionGene = r.Next(100) < 50 ? new ConnectionGene(moreFitParentConnection) : new ConnectionGene(lessFitParentConnection);
                    if (disabled && ((float)r.NextDouble() < disabledConnectionInheritChance))
                    {
                        childConnectionGene.IsEnable = false;
                    }
                }
                else                                                                                // Disjoint or excess Connection => Select More Fit Parent Connection
                {
                    childConnectionGene = new ConnectionGene(moreFitParentConnection);
                }

                child.AddConnectionGene(childConnectionGene);
            }
            return(child);
        }
        /**
         * @param parent1   More fit parent
         * @param parent2   Less fit parent
         */
        public Genome Crossover(Genome parent1, Genome parent2)
        {
            Genome child = new Genome();

            foreach (NodeGene parentNode in parent1.Nodes.Values)
            {
                child.AddNodeGene(parentNode.Copy());
            }
            foreach (ConnectionGene parentNode in parent1.Connections.Values)
            {
                if (parent2.Connections.ContainsValue(parentNode)) // matching gene
                {
                    ConnectionGene childConGene = (Random.Range(0f, 1f) >= 0.5) ? parentNode.Copy() : parent2.Connections[parentNode.Innovation].Copy();
                    child.AddConnectionGene(childConGene);
                }
                else // disjoint or excess gene
                {
                    ConnectionGene childConGene = parentNode.Copy();
                    child.AddConnectionGene(childConGene);
                }
            }
            return(child);
        }