public void beginCrossover()
        {
            _successfulCrossover = new List <TreePair>();
            _toMutate            = new List <GeneticTree>();
            foreach (var item in _toCrossover)
            {
                if (Rng.Rnd.NextDouble() < _crossoverRate)
                {
                    GeneticTree t1 = GeneticTree.deepCopy(item._first);
                    GeneticTree t2 = GeneticTree.deepCopy(item._second);
                    crossover(t1, t2);

                    _successfulCrossover.Add(new TreePair(GeneticTree.deepCopy(t1), GeneticTree.deepCopy(t2)));
                    _swapParents(t1, t2, item._first._id, item._second._id);

                    _toMutate.Add(t1);
                    _toMutate.Add(t2);
                }
                else
                {
                    _toMutate.Add(item._first);
                    _toMutate.Add(item._second);
                }
            }
        }
 public void beginMutation()
 {
     _successfulMutation = new List <GeneticTree>();
     foreach (var item in _toMutate)
     {
         item.setColor(item._nodesColor);
         item.allNodesStats(item._root, 0, "", 0);
         if (Rng.Rnd.NextDouble() < _mutationRate)
         {
             GeneticTree copy = GeneticTree.deepCopy(item);
             mutateOpportunistic(copy);
             _successfulMutation.Add(copy);
         }
         else
         {
             _newPopulation.Add(item);
         }
     }
 }
        public void beginSelection()
        {
            _newPopulation = new List <GeneticTree>();
            _toCrossover   = new List <TreePair>();
            int elitismPassNumber = (int)(_populationSize * _elitismPercentage);

            if (elitismPassNumber % 2 != 0)
            {
                elitismPassNumber++;
            }
            for (int i = 0; i < elitismPassNumber; i++)
            {
                _newPopulation.Add(GeneticTree.deepCopy(_population[i]));
            }
            switch (_selectionType)
            {
            case GpSelectionType.RANK:

                int[]  weights    = Enumerable.Range(1, (int)_populationSize).Reverse().ToArray();
                int[]  weightsRev = weights.Reverse().ToArray();
                uint[] weightSum  = new uint[_populationSize];
                weightSum[0] = _populationSize;
                for (uint i = 1; i < weightSum.Length; i++)
                {
                    weightSum[i] = _populationSize - i + weightSum[i - 1];
                }
                int sum = ((1 + (int)_populationSize)) * (int)_populationSize / 2;

                for (int i = 0; i < _populationSize - elitismPassNumber; i += 2)
                {
                    int         centil   = Rng.Rnd.Next(0, sum);
                    int         resIndex = weightsRev.First(x => weightSum[x - 1] > centil) - 1;
                    GeneticTree first    = _population[resIndex];
                    centil   = Rng.Rnd.Next(0, sum);
                    resIndex = weightsRev.First(x => weightSum[x - 1] > centil) - 1;
                    GeneticTree second = _population[resIndex];

                    _toCrossover.Add(new TreePair(GeneticTree.deepCopy(first), GeneticTree.deepCopy(second)));
                }
                break;

            case GpSelectionType.ROULETTE:

                weights    = Enumerable.Range(0, (int)_populationSize).ToArray();
                weightsRev = weights.Reverse().ToArray();
                float[] wSum = new float[(int)_populationSize];
                wSum[0] = _fitnesses[0];
                for (int i = 1; i < wSum.Length; i++)
                {
                    wSum[i] = _fitnesses[i] + wSum[i - 1];
                }
                float sumF = _fitnesses.Sum();

                for (int i = 0; i < _populationSize - elitismPassNumber; i += 2)
                {
                    double      centil   = Rng.Rnd.NextDouble() * sumF;
                    int         resIndex = weights.First(x => wSum[x] > centil);
                    GeneticTree first    = _population[resIndex];
                    centil   = Rng.Rnd.NextDouble() * sumF;
                    resIndex = weights.First(x => wSum[x] > centil);
                    GeneticTree second = _population[resIndex];

                    _toCrossover.Add(new TreePair(GeneticTree.deepCopy(first), GeneticTree.deepCopy(second)));
                }
                break;

            case GpSelectionType.TOURNAMENT:

                weights = Enumerable.Range(0, (int)_populationSize).ToArray();
                var shuffled = weights.OrderBy(x => Guid.NewGuid());

                for (int i = 0; i < _populationSize - elitismPassNumber; i += 2)
                {
                    var slice       = shuffled.Take((int)_tournamentSelectionSize);
                    var firstRandom = _population[slice.OrderByDescending(x => _fitnesses[x]).First()];
                    shuffled = weights.OrderBy(x => Guid.NewGuid());

                    slice = shuffled.Take((int)_tournamentSelectionSize);
                    var secondRandom = _population[slice.OrderByDescending(x => _fitnesses[x]).First()];
                    shuffled = weights.OrderBy(x => Guid.NewGuid());

                    _toCrossover.Add(new TreePair(GeneticTree.deepCopy(firstRandom), GeneticTree.deepCopy(secondRandom)));
                }
                break;
            }
        }