Ejemplo n.º 1
0
        public void NextGeneration(Species species, int numChildren)
        {
            if (numChildren == 0)
            {
                return;                   //hacky....
            }
            //replace old list with new one
            var children = new List <Genome>();
            var parents  = new List <Genome>();

            int parentCount = (int)(species.Genomes.Count * Config.survivalCutoff);

            //ensure at least one parent
            parentCount = Math.Max(parentCount, 1);

            //only add a proportion of the population to parent pool based on survival cutoff
            for (int i = 0; i < parentCount; i++)
            {
                parents.Add(species.Genomes[i]);
            }

            int asexualCount = (int)(numChildren * Config.rateAsexual);

            if (parentCount == 1)
            {
                asexualCount = numChildren;
            }


            //pick random parents and cross them to get child
            for (int i = 0; i < (numChildren - asexualCount); i++)
            {
                //don't cross the same parents
                var parent1 = parents[Config.globalRandom.Next(0, parents.Count)];
                var parent2 = parents[Config.globalRandom.Next(0, parents.Count)];


                var parentFittest = parent1.Fitness >= parent2.Fitness ? parent1 : parent2;
                //var parentWeaker = parent1.Fitness < parent2.Fitness ? parent1 : parent2;

                //create child topology from fitter parent
                var child = parentFittest.Clone();

                //randomly crossover any shared connections
                child.CrossOver(parent1, parent2);

                children.Add(child);
            }


            //asexual reproduction
            for (int i = 0; i < asexualCount; i++)
            {
                //add asexual in order of parents
                var parent1 = parents[Config.globalRandom.Next(0, parents.Count)];

                children.Add(parent1.Clone());
            }


            //mutate all the children genomes
            foreach (var child in children)
            {
                //mutate individual connection weights
                child.MutateConnectionWeights();

                //mutate add new connection
                var r1 = Config.globalRandom.NextDouble();

                if (r1 < Config.rateAddConnection)
                {
                    child.MutateAddConnection();
                }

                var r2 = Config.globalRandom.NextDouble();

                if (r2 < Config.rateAddNode)
                {
                    child.MutateAddNode(this);
                }

                //if (r2 < 0.2)
                //{
                //    child.MutateNodeType();
                //}

                //if (r2 < 0.02)
                //{
                //    child.MutateRemoveNode();
                //}
            }

            //elitism
            if (species.Genomes.Count > 5)
            {
                children[Config.globalRandom.Next(0, children.Count)] = parents[0].Clone();
            }

            species.Genomes = children;
            Genomes.AddRange(children);
        }