Population Step(Population generation)
        {
            //Extensions.WriteColorLine(ConsoleColor.Green, "======={0} Step======", step++);

            //Console.WriteLine(generation.ToString(fitness));
            //Console.WriteLine("Population fitness sum: {0}",
            //   generation.GetPopulationFitnessSum(fitness));
            var np = new Population { Individuals = new Roulette(fitness, generation).SpinTheWheel(populationSize) };

            //Console.WriteLine(Roulette.ProbabilityToString(generation, fitness));

            //Console.WriteLine("Selected for reproducing");
            //Console.WriteLine(np.ToString(fitness));

            var h = new Harem(fitness, np);
            var newGeneration = h.Reproduce();

            //Console.WriteLine("After reproduction");
            //Console.WriteLine(newGeneration.ToString());

            //Console.WriteLine("After mutation");
            new Mutator(MachinesCount).Mutate(ref newGeneration);
            //Console.WriteLine(newGeneration.ToString());

            #if STORE_BEST_SO_FAR
            var sorted = newGeneration.Individuals.OrderBy(ComputeSchedulingTime);
            var currentBest = sorted.First();
            if (ComputeSchedulingTime(currentBest) < ComputeSchedulingTime(bestSoFar))
            {
                bestSoFar = currentBest;
            }
            #endif

            #if LOG_PLOT
            file.WriteLine("{2} {0} {1}", newGeneration.Individuals.Average(x => ComputeSchedulingTime(x)),
                newGeneration.Individuals.Min(x => ComputeSchedulingTime(x)), step);
            file.Flush();
            #endif
            return newGeneration;
        }