}//End of Selection()

        internal KNPSpecimen Tournament(KNPSpecimen[] population, int tournamentSize)
        {
            Random      random       = new Random();
            KNPSpecimen fittest      = new KNPSpecimen();
            double      fittestScore = Double.MinValue;

            KNPSpecimen[] contestants      = new KNPSpecimen[tournamentSize];
            int           randomContestant = random.Next(populationSize);

            for (int i = 0; i < tournamentSize; i++)
            {
                while (Array.Find(contestants, c => object.ReferenceEquals(c, population[randomContestant])) != null)
                {
                    randomContestant = random.Next(populationSize);
                }
                contestants[i] = population[randomContestant];
            }
            double contestantScore;

            foreach (KNPSpecimen contestant in contestants)
            {
                contestantScore = contestant.Evaluate(problem);
                if (contestantScore > fittestScore)
                {
                    fittestScore = contestantScore;
                    fittest      = new KNPSpecimen((sbyte[])contestant.Genotype.Clone(), testdata);
                }
            }
            return(fittest);
        }//End of Tournament
        internal KNPSpecimen[] Initialize()
        {
            //create initial genotypes
            Random rnd = new Random();

            sbyte[] initialGenotype = new sbyte[testdata.ItemCount * testdata.KnapsackCount];
            for (int i = 0; i < testdata.ItemCount * testdata.KnapsackCount; i++)
            {
                if (i < INITIAL_GENOTYPE_PROBABILITY * testdata.ItemCount * testdata.KnapsackCount)
                {
                    initialGenotype[i] = 1;
                }
                else
                {
                    initialGenotype[i] = 0;
                }
            }
            population = new KNPSpecimen[populationSize];
            for (int i = 0; i < populationSize; i++)
            {
                sbyte[]     shuffledGenotype = initialGenotype.OrderBy(x => rnd.Next()).ToArray(); //shuffle initial genotype
                KNPSpecimen grandpa          = new KNPSpecimen(shuffledGenotype, testdata);
                grandpa.Genotype = grandpa.FixGenotype(shuffledGenotype);
                population[i]    = grandpa;
            }

            indexOfCurrentPopulation = 0;
            indexOfBestPopulation    = 0;
            bestScore = double.MinValue;

            return(population);
        }
        }//End of Mutation()

        internal KNPSpecimen[] Selection()
        {
            KNPSpecimen[] newPopulation = new KNPSpecimen[populationSize];
            for (int i = 0; i < populationSize; i++)
            {
                newPopulation[i] = Tournament(population, tournamentSize); //tournament selection method
                //newPopulation[i] = Roulette(population); //Roulette selection method
                //newPopulation[i] = RandomSpecimen(population); //'Random' selection method
            }
            return(newPopulation);
        }//End of Selection()