Example #1
0
        public void BuildArchive(IEvolutionState state, IList <Individual> oldInds, IList <Individual> newInds, int archiveSize)
        {
            // step 1: load the archive with the pareto-nondominated front
            var archive  = new List <Individual>();
            var nonFront = new List <Individual>();

            MultiObjectiveFitness.PartitionIntoParetoFront(oldInds, archive, nonFront);
            var currentArchiveSize = archive.Count;

            // step 2: if the archive isn't full, load the remainder with the fittest individuals (using customFitnessMetric) that aren't in the archive yet
            if (currentArchiveSize < archiveSize)
            {
                // BRS : The following uses Individual's IComparable implementation based on Fitness.
                // The fitter individuals will be earlier
                nonFront.SortByFitnessDescending();
                var len = archiveSize - currentArchiveSize;
                for (var i = 0; i < len; i++)
                {
                    archive.Add(nonFront[i]);
                    currentArchiveSize++;
                }
            }

            // step 3: if the archive is OVERFULL, iterate as follows:
            //              step 3a: remove the k-closest individual in the archive
            //var evaluator = ((ISPEA2Evaluator)(state.Evaluator));
            //var inds = archive.ToArray();

            while (currentArchiveSize > archiveSize)
            {
                var closest      = archive[0];
                var closestIndex = 0;
                var closestD     = CalculateDistancesFromIndividual(closest, oldInds);

                for (var i = 1; i < currentArchiveSize; i++)
                {
                    var competitor  = archive[i];
                    var competitorD = CalculateDistancesFromIndividual(competitor, oldInds);

                    for (var k = 0; k < oldInds.Count; k++)
                    {
                        if (closestD[i] > competitorD[i])
                        {
                            closest      = competitor;
                            closestD     = competitorD;
                            closestIndex = k;
                            break;
                        }
                        else if (closestD[i] < competitorD[i])
                        {
                            break;
                        }
                    }
                }

                // remove him destructively -- put the top guy in his place and remove the top guy.  This is O(1)
                archive[closestIndex] = archive[archive.Count - 1];
                archive.RemoveAt(archive.Count - 1);

                currentArchiveSize--;
            }

            // step 4: put clones of the archive in the new individuals
            var arr = archive.ToArray();

            for (var i = 0; i < archiveSize; i++)
            {
                newInds[newInds.Count - archiveSize + i] = (Individual)arr[i].Clone();
            }
        }