Elite selection method.
Elite selection method selects specified amount of best chromosomes to the next generation.
Inheritance: ISelectionMethod
        public MelodySequence Generate()
        {
            NoteGene baseGene = new NoteGene(GPGeneType.Function);
            baseGene.Function = NoteGene.FunctionTypes.Concatenation;
            GPCustomTree tree = new GPCustomTree(baseGene);
            if (base_seq != null)
            {
                tree.Generate(base_seq.ToArray());
                tree.Mutate();
                tree.Crossover(tree);

                int length = base_seq.Length;
                int depth = (int)Math.Ceiling(Math.Log(length, 2));
                GPCustomTree.MaxInitialLevel = depth - 2;
                GPCustomTree.MaxLevel = depth + 5;
            }
            var selection = new EliteSelection();
            pop = new Population(30, tree, fitnessFunction, selection);

            pop.AutoShuffling = true;
            pop.CrossoverRate = 0.9;
            pop.MutationRate = 0.1;

            int percentage = MaxGenerations / 100;

            for (int i = 0; i < MaxGenerations; i++)
            {
                if(i>percentage)
                {
                    if (OnPercentage != null)
                        OnPercentage(this, i, pop.FitnessAvg);
                    percentage += MaxGenerations / 100;
                }

                pop.RunEpoch();
                if ((int)(i) % 100 == 0)
                    Console.WriteLine(i / (float)MaxGenerations * 100 + "% : " + pop.FitnessAvg);
            }

            GPCustomTree best = pop.BestChromosome as GPCustomTree;
            var notes = best.GenerateNotes();
            return new MelodySequence(notes);
        }
        private void OnWorkerDoWorkEvolutionary(object sender, DoWorkEventArgs e)
        {
            ArrayList parameters = e.Argument as ArrayList;
            Debug.Assert(parameters != null);
            bool useRed = (bool)parameters[0], useGreen = (bool)parameters[1], useBlue = (bool)parameters[2];
            List<int> slotSizes = (List<int>)parameters[3];

            ProgramFitnessFunction fitnessFunction = new ProgramFitnessFunction(this.puzzle, slotSizes);
            ISelectionMethod selectionMethod = new EliteSelection();
            const int PopulationSize = 500;
            Population population = new Population(
                PopulationSize,
                new ProgramChromosome(slotSizes.Sum(), slotSizes.Count, useRed, useGreen, useBlue),
                fitnessFunction,
                selectionMethod);

            int iteration = 0;
            population.MutationRate = 0.6;
            population.CrossoverRate = 0.6;
            while (true)
            {
                population.RunEpoch();
                backgroundWorker.ReportProgress(++iteration, population.FitnessMax - 1);

                if (backgroundWorker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                if (population.FitnessMax - 1 == this.puzzle.StarsCount)
                {
                    e.Result = fitnessFunction.ChromosomeToProgram((ProgramChromosome)population.BestChromosome);
                    return;
                }
            }
        }