private void CrossOverParents(
            CandidateSolution <T, S> parent1, CandidateSolution <T, S> parent2,
            out CandidateSolution <T, S> child1, out CandidateSolution <T, S> child2)
        {
            // are we crossing over, or just copying a parent directly?
            child1 = parent1.Clone();
            child2 = parent2.Clone();

            // Do we use exact copies of parents, or crossover?
            if (Randomizer.GetDoubleFromZeroToOne() < CrossoverRate)
            {
                NodeBaseType <T, S> randomC1node, randomC2node;
                // pick a random node from both parents and clone the tree below it.
                // We don't want root nodes, since that's not really crossover, so we disallow those
                do
                {
                    randomC1node = child1.SelectRandomNode();
                } while (randomC1node == child1.Root);
                do
                {
                    randomC2node = child2.SelectRandomNode();
                } while (randomC2node == child2.Root);

                // make copies of them
                var newChild1 = randomC1node.Clone(null);
                var newChild2 = randomC2node.Clone(null);

                // create new children by swapping subtrees
                CandidateSolution <T, S> .SwapSubtrees(randomC1node, randomC2node, newChild1, newChild2);

                // and reset the pointers to the candidate
                child1.Root.SetCandidateRef(child1);
                child2.Root.SetCandidateRef(child2);
            }
        }
        private CandidateSolution <T, S> RouletteSelectParent()
        {
            // using Roulette Wheel Selection, we grab a possibility proportionate to it's fitness compared to
            // the total fitnesses of all possibilities
            double randomValue = Randomizer.GetDoubleFromZeroToOne() * totalFitness;

            for (int i = 0; i < PopulationSize; i++)
            {
                randomValue -= currentGeneration[i].Fitness;
                if (randomValue <= 0)
                {
                    return(currentGeneration[i]);
                }
            }

            return(currentGeneration[PopulationSize - 1]);
        }