Exemplo n.º 1
0
        public void AssignCrowdingDistance_InfiniteReferencePoint_Works()
        {
            ParetoFrontMetrics.AssignCrowdingDistance(new[]
                                                      { moTestInd, indParetoEqual1, indParetoEqual2, indParetoEqual3 },
                                                      "crowdingDistance",
                                                      minimise,
                                                      moTestInd.SolutionVector.Select(i => double.MaxValue));

            Assert.True(moTestInd.GetProperty <double>("crowdingDistance") > 1e300);
            Assert.True(indParetoEqual1.GetProperty <double>("crowdingDistance") > 1e300);
            // Crowding distance should be 0.09/0.1 + 0.18/0.2 + 0.09/0.1
            Assert.True(Math.Abs(indParetoEqual2.GetProperty <double>("crowdingDistance") - 2.7) < 1e-6);
            Assert.True(indParetoEqual3.GetProperty <double>("crowdingDistance") > 1e300);
        }
Exemplo n.º 2
0
        public void AssignCrowdingDistance_InsideReferencePoint_Works()
        {
            ParetoFrontMetrics.AssignCrowdingDistance(new[]
                                                      { moTestInd, indParetoEqual1, indParetoEqual2, indParetoEqual3 },
                                                      "crowdingDistance",
                                                      minimise,
                                                      new[] { WorstSolution1 + 0.1, WorstSolution2 - 0.02, WorstSolution3 + 0.1 });

            // Best for objective 3
            Assert.True(moTestInd.GetProperty <double>("crowdingDistance") > 1e300);
            // Out of bounds on objective 2
            Assert.Equal(0.0, indParetoEqual1.GetProperty <double>("crowdingDistance"));
            // Crowding distance should be 0.09/0.1 + 0.16/0.18 + 0.09/0.1
            Assert.True(Math.Abs(indParetoEqual2.GetProperty <double>("crowdingDistance") - 2.68888889) < 1e-6);
            // Best for objective 2
            Assert.True(indParetoEqual3.GetProperty <double>("crowdingDistance") > 1e300);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Performs the fitness calculation based on:
        /// 1) Non-dominated sorting into Pareto Fronts;
        /// 2) Crowding distance assignment and comparison
        /// </summary>
        /// <remarks>
        /// If the number of individuals provided is less than the population size provided in the constructor,
        /// then only a simple fitness assignment is performed (assumes this is used during initial population
        /// creation: <see cref="EvolutionaryAlgorithm"/>).
        /// </remarks>
        /// <param name="individuals">All individuals to be considered for fitness calculation.</param>
        public void CalculateAndAssignFitness(IEnumerable <Individual> individuals)
        {
            var inds = individuals as Individual[] ?? individuals.ToArray();

            if (inds.Length <= populationSize)
            {
                // Don't bother with Pareto Front calculation, it's too time consuming.
                // Just assign sum of ranks on each objective.
                for (var m = 0; m < inds[0].SolutionVector.Length; m++)
                {
                    var individualsOrderedByThisObjective = inds.OrderBy(i => i.SolutionVector.ElementAt(m) * (minimise[m] ? 1 : -1)).ToArray();
                    for (int o = 0; o < individualsOrderedByThisObjective.Count(); o++)
                    {
                        individualsOrderedByThisObjective[o].SetFitness(o + individualsOrderedByThisObjective[o].Fitness);
                    }
                }
                return;
            }

            if (useReferencePoint & double.IsInfinity(referencePoint.ElementAt(0)))
            {
                // Calculate a reference point
                for (var m = 0; m < inds[0].SolutionVector.Length; m++)
                {
                    // Use the worst value found for each objective, after the initial population generation.
                    referencePoint[m] = minimise[m]
                        ? inds.Max(i => i.SolutionVector.ElementAt(m))
                        : inds.Min(i => i.SolutionVector.ElementAt(m));
                }
            }

            // Calculate Pareto Fronts
            sorter.PerformSort(inds, minimise);

            // Go through, assigning fitness
            var paretoFront         = 1;
            var currentParetoFront  = inds.Where(i => i.GetProperty <int>(OptimiserPropertyNames.ParetoFront) == paretoFront).ToArray();
            var individualsAssessed = 0;

            while (currentParetoFront.Length > 0)
            {
                foreach (var ind in currentParetoFront)
                {
                    ind.SetFitness(paretoFront);
                }

                if (individualsAssessed < populationSize && individualsAssessed + currentParetoFront.Length > populationSize)
                {
                    // We're in the Pareto Front which partially overlaps with the population size.
                    // Perform crowding distance assignment
                    ParetoFrontMetrics.AssignCrowdingDistance(currentParetoFront, CrowdingDistance,
                                                              minimise, referencePoint);
                    var sortedParetoFront = currentParetoFront
                                            .OrderByDescending(i => i.GetProperty <double>(CrowdingDistance))
                                            .ToArray();
                    var crowdingComparison = 0.0;
                    for (int i = 1; i < sortedParetoFront.Length; i++)
                    {
                        if (sortedParetoFront[i - 1].GetProperty <double>(CrowdingDistance) >
                            sortedParetoFront[i].GetProperty <double>(CrowdingDistance))
                        {
                            crowdingComparison += 1.0 / (currentParetoFront.Length + 10.0); // Small enough that we won't end up more than 1 in total...
                        }
                        sortedParetoFront[i].SetFitness(sortedParetoFront[i].Fitness + crowdingComparison);
                    }
                }

                individualsAssessed += currentParetoFront.Length;

                // Get next Pareto Front
                paretoFront++;
                currentParetoFront = inds.Where(i => i.GetProperty <int>(OptimiserPropertyNames.ParetoFront) == paretoFront).ToArray();
            }
        }