public static Chromosome Cross(Tuple<Chromosome, Chromosome> pair, Random random)
 {
     IList<double> values;
     UniformDistribution uniform = new UniformDistribution(Interval.FromEndpoints(0, 1));
     DiscreteUniformDistribution discrete = new DiscreteUniformDistribution(0, 1);
     double randomNumber = uniform.GetRandomValue(random);
     if (randomNumber <= SELECTION_1_PROBABILITY) // whole arithmetic recombination
         values = pair.Item1.Values.Zip(pair.Item2.Values, (x, y) => (x + y) / 2).ToList();
     else if (randomNumber <= SELECTION_1_PROBABILITY + SELECTION_2_PROBABILITY) // discrete recombination
         values = pair.Item1.Values.Zip(pair.Item2.Values, (x, y) => discrete.GetRandomValue(random) == 0 ? x : y).ToList();
     else // simple arithmetic recombination
         values = pair.Item1.Values.Zip(pair.Item2.Values, (x, y) => pair.Item1.Values.IndexOf(x) < pair.Item1.Values.Count / 2 ? x : (x + y) / 2).ToList();
     return new Chromosome(values);
 }
 public static Tuple<Chromosome, Chromosome> Select(IList<Chromosome> population, Random random, out Chromosome worst)
 {
     SortedSet<Chromosome> tournament = new SortedSet<Chromosome>();
     DiscreteUniformDistribution discrete = new DiscreteUniformDistribution(0, population.Count - 1);
     while (tournament.Count < K)
     {
         int index = discrete.GetRandomValue(random);
         tournament.Add(population[index]);
     }
     worst = tournament.Max;
     tournament.Remove(worst);
     double sumFitness;
     CalculateFitness(tournament, out sumFitness);
     Chromosome parent1 = SelectParent(tournament, sumFitness, random);
     tournament.Remove(parent1);
     CalculateFitness(tournament, out sumFitness);
     Chromosome parent2 = SelectParent(tournament, sumFitness, random);
     return new Tuple<Chromosome, Chromosome>(parent1, parent2);
 }