public Phenotype[] ChooseBestByRoulete(int qty)
        {
            Phenotype[] result = new Phenotype[qty];

            float totalFitness = 0;

            foreach (Phenotype phenotype in phenotypes)
            {
                totalFitness += phenotype.fitness;
            }

            KeyValuePair<Phenotype, double>[] candiates = new KeyValuePair<Phenotype, double>[phenotypes.Count];
            int i = 0;
            foreach (Phenotype phenotype in phenotypes)
            {
                double p = (rouleteBiasToTheBest + rnd.NextDouble() * (1 - rouleteBiasToTheBest)) * phenotype.fitness / totalFitness;
                candiates[i] = new KeyValuePair<Phenotype, double>(phenotype, p);
                i++;
            }

            IOrderedEnumerable<KeyValuePair<Phenotype, double>> bestCandidates = candiates.OrderByDescending(
                (KeyValuePair<Phenotype, double> candidate) => candidate.Value
            );

            int added = 0;
            foreach (KeyValuePair<Phenotype, double> candidate in bestCandidates)
            {
                result[added++] = candidate.Key;
                if (added >= qty) break;
            }

            return result;
        }
        public void AddPhenotype(float[][] genotype, float fitness)
        {
            Phenotype phenotype = new Phenotype() { genotype = genotype, fitness = fitness };
            phenotypes.AddLast(phenotype);

            if (bestPhenotype == null || bestPhenotype.fitness < phenotype.fitness) bestPhenotype = phenotype;
        }