Esempio n. 1
0
        private void Process(GeneType geneType)
        {
            var    solutions            = _population.Solutions;
            double totalFitness         = 0.0;
            double maximumFitness       = 0.0;
            double minimumFitness       = 1.0;
            var    fitnessList          = new List <double> (_populationSize);
            double totalHammingDistance = 0.0;
            double totalFitnessDistance = 0.0;

            int [] diversityGraph = new int [BucketCount];


            //loop through each solution
            for (var sIndex = 0; sIndex < _populationSize; sIndex++)
            {
                var solution = solutions [sIndex];

                #region Storing Data for Later

                //store the values for using later on with Average and StddDev
                var currentFitness = solution.Fitness;
                totalFitness += currentFitness;
                fitnessList.Add(currentFitness);

                #endregion

                #region Max and Min

                if (currentFitness < minimumFitness)
                {
                    minimumFitness = currentFitness;
                }
                if (currentFitness > maximumFitness)
                {
                    maximumFitness = currentFitness;
                }

                #endregion

                #region Hamming Distance

                //TODO: Check that this is correct.
                //We safely compare to ourselves as this will produce a 0 result.

                //compare the current solution with all others. Note that we only need
                //to compare each once hence the shortened 'innerIndex' loop
                for (var innerIndex = sIndex; innerIndex < _populationSize; innerIndex++)
                {
                    // hamming only applies to binary chromosome
                    if (geneType == GeneType.Binary)
                    {
                        //calculate hamming distance

                        var string1 = solutions [sIndex].ToBinaryString();
                        var string2 = solutions [innerIndex].ToBinaryString();

                        //TODO: Look at converting the binary to an integer and using the bitwise function (See below)
                        for (var index = 0; index < _chromosomeLength; index++)
                        {
                            if (string1 [index] != string2 [index])
                            {
                                totalHammingDistance++;
                            }
                        }
                        //our gene is actually strored as a double.
                        //we also need to make sure we dont cause errors if a non binary chromosome is used;
                        //e.g. Here is an example in C comparing two integers

                        /*
                         * def hamming2(x,y):
                         * """Calculate the Hamming distance between two bit strings"""
                         * assert len(x) == len(y)
                         * count,z = 0,x^y
                         * while z:
                         * count += 1
                         * z &= z-1 # magic!
                         * return count
                         */

                        //end of hamming distance
                    }
                    //fitness distance (diversity via fitness

                    var fitness1 = solutions [sIndex].Fitness;
                    var fitness2 = solutions [innerIndex].Fitness;

                    totalFitnessDistance += System.Math.Abs(fitness1 - fitness2);
                }

                //Debug.Print ("Total Hamming Distance: {0}", new [] { totalHammingDistance.ToString() });
                //Debug.Print ("Total Fitness Distance: {0}", new [] { totalFitnessDistance.ToString () });


                #endregion

                #region Diversity Graph

                var bucket = (int)System.Math.Floor(currentFitness / (1.0 / BucketCount));

                //if fitness ends up being 1.0 we could end up with a bucket of 16 which would fail
                if (bucket == BucketCount)
                {
                    bucket--;
                }

                diversityGraph [bucket]++;

                /*
                 *      Each bucket will contain the number of solutions from the total number of solutions
                 *      in the population.
                 */


                #endregion
            }

            #region Hamming Distance

            // sampleSize is given by = N(N-1)/2 and is the number of chromosome comparisons
            // totalHammingDistance refers to the number of bits that are different when comparing
            // all chromosomes with each other e.g. N(N-1)/2
            // average hammiing distance starts at approximatelly: chromosomeLength/2
            // and ends up at 0 when the GA is converged

            var sampleSize = (_populationSize * (_populationSize - 1)) / 2.0;
            AverageHammingDistance = (totalHammingDistance / sampleSize);
            AverageFitnessDistance = totalFitnessDistance / sampleSize;

            //if (AverageHammingDistance < 0)
            //	throw new ApplicationException ("Hamming Distance is negative.");
            //if (AverageFitnessDistance < 0)
            //	throw new ApplicationException ("Fitness Distance is negative.");

            #endregion

            #region Duplicates

            double percentageDuplicates = 0.0;
            var    count = _population.GetDuplicates();

            if (count > 0)
            {
                percentageDuplicates = ((double)count / _populationSize) * 100;
            }

            this.Duplicates = (int)System.Math.Round(percentageDuplicates);

            #endregion

            #region Upper Quartile Count

            var uqCount = 0;

            for (var bucket = BucketCount - UpperQuartileBucketCount; bucket < BucketCount; bucket++)
            {
                uqCount += _diversityGraph [bucket];
            }

            this.UpperQuartileCount = (int)(((double)uqCount / _populationSize) * 100);

            #endregion


            #region Scale the Distribution Graph

            for (int index = 0; index < diversityGraph.Length; index++)
            {
                var bucketPercentage       = ((double)diversityGraph [index] / _populationSize) * 100;
                var bucketPercentageScaled = bucketPercentage * _diversityGraphScale;
                diversityGraph [index] = (int)(bucketPercentageScaled <= 100 ? bucketPercentageScaled : 100);
            }

            this.DiversityGraph = diversityGraph;

            #endregion

            #region Average Fitness

            if (!Math.AboutEqual(totalFitness, 0.0) && _populationSize != 0)
            {
                this.AverageFitness = totalFitness / _populationSize;
            }

            #endregion

            #region Standard Deviation

            this.StandardDeviation = CalculateStdDev(fitnessList);

            #endregion

            #region Max/Min

            this.MaximumFitness = maximumFitness;
            this.MinimumFitness = minimumFitness;

            #endregion

            this.C9Fitness = GAF.Math.ReRange(GetConsecutiveNines(maximumFitness), 0, 10, 0, 1);

            //TODO: Determine how is this derived?
            //average hamming distance is per population, and ranges from chromosomeLenth/2
            //(good estimate of initial hamming distance, see Louis & Rawlins, Predicting Convergence Time for Genetic Algorithms)
            //and 0 (fully converged).
            //e.g. with a chromsome length of 22 the range would be 22 - 0 the following rescales to 1 - 0;)
            var diversity = (AverageHammingDistance / (_chromosomeLength / 2));
            if (diversity > 100)
            {
                diversity = 100;
            }

            this.Diversity = diversity;

            var diversityF = AverageFitnessDistance / 0.5;
            if (diversityF > 100)
            {
                diversityF = 100;
            }

            this.DiversityF = diversityF;

            if (geneType == GeneType.Binary)
            {
                this.Convergence    = 1 - diversity;
                this.DiversityGraph = diversityGraph;
            }
            else
            {
                this.Convergence = 0;
                this.Diversity   = 0;
            }

            this.ConvergenceF = 1 - diversityF;
        }