public void OptimizeTest()
        {
            var geneSet    = Enumerable.Range(1, 512).ToArray();
            var length     = 10;
            var maxSeconds = 2;

            double FnGetFitness(IReadOnlyList <int> genes)
            {
                var watch  = Stopwatch.StartNew();
                var count  = 0.0;
                var stdout = Console.Out;

                Console.SetOut(TextWriter.Null);
                while (watch.ElapsedMilliseconds < maxSeconds * 1000)
                {
                    var found = ApproximatePi(genes, maxSeconds);
                    if (found)
                    {
                        count += 1.0;
                    }
                }

                Console.SetOut(stdout);
                var distance = Math.Abs(genes.Sum() - 1023);
                var fraction = distance > 0 ? 1.0 / distance : distance;

                count += Math.Round(fraction, 4);
                return(count);
            }

            void FnDisplay(Chromosome <int, double> chromosome) => Console.WriteLine("{0}\t{1}",
                                                                                     string.Join(", ", chromosome.Genes), chromosome.Fitness);

            var initial = new List <int> {
                512, 256, 128, 64, 32, 16, 8, 4, 2, 1
            };

            Console.WriteLine("initial: {0} {1}", initial, FnGetFitness(initial));

            var optimalFitness = 10 * maxSeconds;
            var unused         = Genetic <int, double> .GetBest(FnGetFitness, length, optimalFitness, geneSet, FnDisplay, null,
                                                                null, null, 1, null, 600);
        }
        private static bool ApproximatePi(IReadOnlyCollection <int> bitValues, int?maxSeconds = null)
        {
            var geneSet = new[] { false, true };
            var watch   = Stopwatch.StartNew();

            void FnDispaly(Chromosome <bool, double> candidate) =>
            Display(candidate, watch, bitValues);

            double FnGetFitness(IReadOnlyList <bool> genes) =>
            GetFitness(genes, bitValues);

            var optimalFitness = Math.Round(355.0 / 113.0, 5); // = 3.14159;

            void FnMutate(List <bool> genes) =>
            Mutate(genes);

            var length = 2 * bitValues.Count;
            var best   = Genetic <bool, double> .GetBest(FnGetFitness, length, optimalFitness, geneSet, FnDispaly, FnMutate,
                                                         null, 250, 1, null, maxSeconds);

            return(optimalFitness <= best.Fitness);
        }