private void Breed(ref INeuralNetwork[] orderedNetworks)
        {
            var top        = orderedNetworks.Take((orderedNetworks.Length - 1) / 2).ToArray();
            var newnetwork = new List <INeuralNetwork>();

            for (int i = 0; i < _speciesCount; i++)
            {
                var index = i % (top.Length - 1);
                if (index < top.Length)
                {
                    newnetwork.Add((INeuralNetwork)top[index].Clone());
                }
            }
            NeuralNetworks  = newnetwork;
            orderedNetworks = FitnessVal.Maximize ? NeuralNetworks.OrderByDescending(p => p.Error).ToArray() : NeuralNetworks.OrderBy(p => p.Error).ToArray();
        }
        public IGeneration EvolveGeneration()
        {
#if Roslyn
            Parallel.ForEach(NeuralNetworks, p =>
            {
                var fitness = FitnessVal.EvaluateFitness(p);
                p.Error     = fitness;
            });
#endif
#if Bridge
            foreach (var neuralNetwork in NeuralNetworks)
            {
                var fitness = FitnessVal.EvaluateFitness(neuralNetwork);
                neuralNetwork.Error = fitness;
            }
#endif
            var orderedNetworks = FitnessVal.Maximize ? NeuralNetworks.OrderByDescending(p => p.Error).ToArray() : NeuralNetworks.OrderBy(p => p.Error).ToArray();
            //keep top 50
            //todo: copy top 50 networks and evolve the new networks

            var gen = new Generation(orderedNetworks, orderedNetworks[0], orderedNetworks[orderedNetworks.Length - 1], orderedNetworks[(orderedNetworks.Length - 1) / 2], Generation);
            Breed(ref orderedNetworks);
            var r = orderedNetworks.ToList();
            r.Reverse();
            var reverse = r.Take((int)(orderedNetworks.Length - orderedNetworks.Length * 0.1));
#if Roslyn
            Parallel.ForEach(reverse, Mutate);
#endif
#if Bridge
            foreach (var neuralNetwork in reverse)
            {
                Mutate(neuralNetwork);
            }
#endif

            OnGenerationFinished(gen);

            Generation++;
            return(gen);
        }