public IEnumerable <Individual> Apply(IEnumerable <Individual> source) { var prms = ParamsProvider(this); var inp = source.ToArray(); var elite = Elitism.SelectElite(inp, prms.ElitismFraction).ToArray(); if (elite.Length % 2 != 0) { throw new InvalidOperationException("Elitism fraction must result in an even number of individuals"); } var selected = Selection.Roulette(inp, inp.Length - elite.Length); var crossed = Crossover.UniformCrossoverPop(selected); var mutated = Mutation.MutatePop(crossed, prms.MutationFraction, RandomValueProvider); var retPop = elite.Concat(mutated).ToArray(); history.Add(CalcStats(prms, inp, retPop)); return(retPop); }