public SMPSO(Problem problem, string trueParetoFront)
            : base(problem)
        {
            hy = new HyperVolume();
            MetricsUtil mu = new MetricsUtil();

            trueFront       = mu.ReadNonDominatedSolutionSet(trueParetoFront);
            trueHypervolume = hy.Hypervolume(trueFront.WriteObjectivesToMatrix(),
                                             trueFront.WriteObjectivesToMatrix(),
                                             problem.NumberOfObjectives);

            // Default configuration
            r1Max  = 1.0;
            r1Min  = 0.0;
            r2Max  = 1.0;
            r2Min  = 0.0;
            C1Max  = 2.5;
            C1Min  = 1.5;
            C2Max  = 2.5;
            C2Min  = 1.5;
            WMax   = 0.1;
            WMin   = 0.1;
            ChVel1 = -1;
            ChVel2 = -1;
        }
        public SMPSO(Problem problem,
                     List <double> variables,
                     string trueParetoFront)
            : base(problem)
        {
            r1Max  = variables[0];
            r1Min  = variables[1];
            r2Max  = variables[2];
            r2Min  = variables[3];
            C1Max  = variables[4];
            C1Min  = variables[5];
            C2Max  = variables[6];
            C2Min  = variables[7];
            WMax   = variables[8];
            WMin   = variables[9];
            ChVel1 = variables[10];
            ChVel2 = variables[11];

            hy = new HyperVolume();
            MetricsUtil mu = new MetricsUtil();

            trueFront       = mu.ReadNonDominatedSolutionSet(trueParetoFront);
            trueHypervolume = hy.Hypervolume(trueFront.WriteObjectivesToMatrix(),
                                             trueFront.WriteObjectivesToMatrix(),
                                             problem.NumberOfObjectives);
        }
Beispiel #3
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="problem">The problem</param>
 /// <param name="paretoFrontFile">Pareto front file</param>
 public QualityIndicator(Problem problem, string paretoFrontFile)
 {
     this.problem               = problem;
     Utils                      = new MetricsUtil();
     trueParetoFront            = Utils.ReadNonDominatedSolutionSet(paretoFrontFile);
     TrueParetoFrontHypervolume = new HyperVolume().Hypervolume(
         trueParetoFront.WriteObjectivesToMatrix(),
         trueParetoFront.WriteObjectivesToMatrix(),
         problem.NumberOfObjectives);
 }
Beispiel #4
0
 /// <summary>
 /// Returns the generational distance of solution set
 /// </summary>
 /// <param name="solutionSet">Solution set</param>
 /// <returns>The value of the hypervolume indicator</returns>
 public double GetGD(SolutionSet solutionSet)
 {
     return(new GenerationalDistance().CalculateGenerationalDistance(
                solutionSet.WriteObjectivesToMatrix(),
                trueParetoFront.WriteObjectivesToMatrix(),
                problem.NumberOfObjectives));
 }
        /// <summary>
        /// Runs the SMS-EMOA algorithm.
        /// </summary>
        /// <returns>A <code>SolutionSet</code> that is a set of non dominated solutions as a result of the algorithm execution</returns>
        public override SolutionSet Execute()
        {
            int    populationSize = -1;
            int    maxEvaluations = -1;
            int    evaluations;
            double offset = 100.0;

            QualityIndicator.QualityIndicator indicators = null; // QualityIndicator object
            int requiredEvaluations;                             // Use in the example of use of the indicators object (see below)

            SolutionSet population;
            SolutionSet offspringPopulation;
            SolutionSet union;

            Operator mutationOperator;
            Operator crossoverOperator;
            Operator selectionOperator;

            //Read the parameters
            JMetalCSharp.Utils.Utils.GetIntValueFromParameter(this.InputParameters, "populationSize", ref populationSize);
            JMetalCSharp.Utils.Utils.GetIntValueFromParameter(this.InputParameters, "maxEvaluations", ref maxEvaluations);
            JMetalCSharp.Utils.Utils.GetIndicatorsFromParameters(this.InputParameters, "indicators", ref indicators);
            JMetalCSharp.Utils.Utils.GetDoubleValueFromParameter(this.InputParameters, "offset", ref offset);

            //Initialize the variables
            population  = new SolutionSet(populationSize);
            evaluations = 0;

            requiredEvaluations = 0;

            //Read the operators
            mutationOperator  = Operators["mutation"];
            crossoverOperator = Operators["crossover"];
            selectionOperator = Operators["selection"];

            // Create the initial solutionSet
            Solution newSolution;

            for (int i = 0; i < populationSize; i++)
            {
                newSolution = new Solution(Problem);
                Problem.Evaluate(newSolution);
                Problem.EvaluateConstraints(newSolution);
                evaluations++;
                population.Add(newSolution);
            }

            // Generations ...
            while (evaluations < maxEvaluations)
            {
                // select parents
                offspringPopulation = new SolutionSet(populationSize);
                List <Solution> selectedParents = new List <Solution>();
                Solution[]      parents         = new Solution[0];
                while (selectedParents.Count < 2)
                {
                    object selected = selectionOperator.Execute(population);
                    try
                    {
                        Solution parent = (Solution)selected;
                        selectedParents.Add(parent);
                    }
                    catch (InvalidCastException e)
                    {
                        parents = (Solution[])selected;
                        selectedParents.AddRange(parents);
                    }
                }
                parents = selectedParents.ToArray <Solution>();

                // crossover
                Solution[] offSpring = (Solution[])crossoverOperator.Execute(parents);

                // mutation
                mutationOperator.Execute(offSpring[0]);

                // evaluation
                Problem.Evaluate(offSpring[0]);
                Problem.EvaluateConstraints(offSpring[0]);

                // insert child into the offspring population
                offspringPopulation.Add(offSpring[0]);

                evaluations++;

                // Create the solutionSet union of solutionSet and offSpring
                union = ((SolutionSet)population).Union(offspringPopulation);

                // Ranking the union (non-dominated sorting)
                Ranking ranking = new Ranking(union);

                // ensure crowding distance values are up to date
                // (may be important for parent selection)
                for (int j = 0; j < population.Size(); j++)
                {
                    population.Get(j).CrowdingDistance = 0.0;
                }

                SolutionSet lastFront = ranking.GetSubfront(ranking.GetNumberOfSubfronts() - 1);
                if (lastFront.Size() > 1)
                {
                    double[][] frontValues        = lastFront.WriteObjectivesToMatrix();
                    int        numberOfObjectives = Problem.NumberOfObjectives;
                    // STEP 1. Obtain the maximum and minimum values of the Pareto front
                    double[] maximumValues = utils.GetMaximumValues(union.WriteObjectivesToMatrix(), numberOfObjectives);
                    double[] minimumValues = utils.GetMinimumValues(union.WriteObjectivesToMatrix(), numberOfObjectives);
                    // STEP 2. Get the normalized front
                    double[][] normalizedFront = utils.GetNormalizedFront(frontValues, maximumValues, minimumValues);
                    // compute offsets for reference point in normalized space
                    double[] offsets = new double[maximumValues.Length];
                    for (int i = 0; i < maximumValues.Length; i++)
                    {
                        offsets[i] = offset / (maximumValues[i] - minimumValues[i]);
                    }
                    // STEP 3. Inverse the pareto front. This is needed because the original
                    //metric by Zitzler is for maximization problems
                    double[][] invertedFront = utils.InvertedFront(normalizedFront);
                    // shift away from origin, so that boundary points also get a contribution > 0
                    for (int j = 0, lj = invertedFront.Length; j < lj; j++)
                    {
                        var point = invertedFront[j];
                        for (int i = 0; i < point.Length; i++)
                        {
                            point[i] += offsets[i];
                        }
                    }

                    // calculate contributions and sort
                    double[] contributions = HvContributions(invertedFront);
                    for (int i = 0; i < contributions.Length; i++)
                    {
                        // contribution values are used analogously to crowding distance
                        lastFront.Get(i).CrowdingDistance = contributions[i];
                    }

                    lastFront.Sort(new CrowdingDistanceComparator());
                }

                // all but the worst are carried over to the survivor population
                SolutionSet front = null;
                population.Clear();
                for (int i = 0; i < ranking.GetNumberOfSubfronts() - 1; i++)
                {
                    front = ranking.GetSubfront(i);
                    for (int j = 0; j < front.Size(); j++)
                    {
                        population.Add(front.Get(j));
                    }
                }
                for (int i = 0; i < lastFront.Size() - 1; i++)
                {
                    population.Add(lastFront.Get(i));
                }

                // This piece of code shows how to use the indicator object into the code
                // of SMS-EMOA. In particular, it finds the number of evaluations required
                // by the algorithm to obtain a Pareto front with a hypervolume higher
                // than the hypervolume of the true Pareto front.
                if (indicators != null && requiredEvaluations == 0)
                {
                    double HV = indicators.GetHypervolume(population);
                    if (HV >= (0.98 * indicators.TrueParetoFrontHypervolume))
                    {
                        requiredEvaluations = evaluations;
                    }
                }
            }

            // Return as output parameter the required evaluations
            SetOutputParameter("evaluations", requiredEvaluations);

            // Return the first non-dominated front
            Ranking rnk = new Ranking(population);

            Result = rnk.GetSubfront(0);
            return(Result);
        }
Beispiel #6
0
 /// <summary>
 /// Returns the spread of solution set
 /// </summary>
 /// <param name="solutionSet">Solution set</param>
 /// <returns>The value of the hypervolume indicator</returns>
 public double GetSpread(SolutionSet solutionSet)
 {
     return(new Spread().CalculateSpread(solutionSet.WriteObjectivesToMatrix(),
                                         trueParetoFront.WriteObjectivesToMatrix(),
                                         problem.NumberOfObjectives));
 }
Beispiel #7
0
 /// <summary>
 /// Returns the hypervolume of solution set
 /// </summary>
 /// <param name="solutionSet">Solution set</param>
 /// <returns>The value of the hypervolume indicator</returns>
 public double GetHypervolume(SolutionSet solutionSet)
 {
     return(new HyperVolume().Hypervolume(solutionSet.WriteObjectivesToMatrix(),
                                          trueParetoFront.WriteObjectivesToMatrix(),
                                          problem.NumberOfObjectives));
 }
Beispiel #8
0
 /// <summary>
 /// Returns the epsilon indicator of solution set
 /// </summary>
 /// <param name="solutionSet">Solution set</param>
 /// <returns>The value of the hypervolume indicator</returns>
 public double GetEpsilon(SolutionSet solutionSet)
 {
     return(new Epsilon().CalcualteEpsilon(solutionSet.WriteObjectivesToMatrix(),
                                           trueParetoFront.WriteObjectivesToMatrix(),
                                           problem.NumberOfObjectives));
 }
Beispiel #9
0
        /// <summary>
        /// Calculates the hv contribution of different populations. Receives an
        /// array of populations and computes the contribution to HV of the
        /// population consisting in the union of all of them
        /// </summary>
        /// <param name="archive"></param>
        /// <param name="populations">Consisting in all the populatoins</param>
        /// <returns>HV contributions of each population</returns>
        public double[] HVContributions(SolutionSet archive, SolutionSet[] populations)
        {
            SolutionSet union;
            int         size    = 0;
            double      offset_ = 0.0;

            //determining the global size of the population
            foreach (SolutionSet population in populations)
            {
                size += population.Size();
            }

            //allocating space for the union
            union = archive;

            //determining the number of objectives
            int numberOfObjectives = union.Get(0).NumberOfObjectives;

            //writing everything in matrices
            double[][][] frontValues = new double[populations.Length + 1][][];

            frontValues[0] = union.WriteObjectivesToMatrix();
            for (int i = 0; i < populations.Length; i++)
            {
                if (populations[i].Size() > 0)
                {
                    frontValues[i + 1] = populations[i].WriteObjectivesToMatrix();
                }
                else
                {
                    frontValues[i + 1] = new double[0][];
                }
            }

            // obtain the maximum and minimum values of the Pareto front
            double[] maximumValues = GetMaximumValues(union.WriteObjectivesToMatrix(), numberOfObjectives);
            double[] minimumValues = GetMinimumValues(union.WriteObjectivesToMatrix(), numberOfObjectives);

            // normalized all the fronts
            double[][][] normalizedFront = new double[populations.Length + 1][][];
            for (int i = 0; i < normalizedFront.Length; i++)
            {
                if (frontValues[i].Length > 0)
                {
                    normalizedFront[i] = GetNormalizedFront(frontValues[i], maximumValues, minimumValues);
                }
                else
                {
                    normalizedFront[i] = new double[0][];
                }
            }

            // compute offsets for reference point in normalized space
            double[] offsets = new double[maximumValues.Length];
            for (int i = 0; i < maximumValues.Length; i++)
            {
                offsets[i] = offset_ / (maximumValues[i] - minimumValues[i]);
            }

            //Inverse all the fronts front. This is needed because the original
            //metric by Zitzler is for maximization problems
            double[][][] invertedFront = new double[populations.Length + 1][][];
            for (int i = 0; i < invertedFront.Length; i++)
            {
                if (normalizedFront[i].Length > 0)
                {
                    invertedFront[i] = InvertedFront(normalizedFront[i]);
                }
                else
                {
                    invertedFront[i] = new double[0][];
                }
            }

            // shift away from origin, so that boundary points also get a contribution > 0
            foreach (double[][] anInvertedFront in invertedFront)
            {
                foreach (double[] point in anInvertedFront)
                {
                    for (int i = 0; i < point.Length; i++)
                    {
                        point[i] += offsets[i];
                    }
                }
            }

            // calculate contributions
            double[]    contribution = new double[populations.Length];
            HyperVolume hyperVolume  = new HyperVolume();

            for (int i = 0; i < populations.Length; i++)
            {
                if (invertedFront[i + 1].Length == 0)
                {
                    contribution[i] = 0;
                }
                else
                {
                    int auxSize = 0;
                    for (int j = 0; j < populations.Length; j++)
                    {
                        if (j != i)
                        {
                            auxSize += invertedFront[j + 1].Length;
                        }
                    }

                    if (size == archive.Size())
                    {                     // the contribution is the maximum hv
                        contribution[i] = hyperVolume.CalculateHypervolume(invertedFront[0], invertedFront[0].Length, numberOfObjectives);
                    }
                    else
                    {
                        //make a front with all the populations but the target one
                        int        index = 0;
                        double[][] aux   = new double[auxSize][];
                        for (int j = 0; j < populations.Length; j++)
                        {
                            if (j != i)
                            {
                                for (int k = 0; k < populations[j].Size(); k++)
                                {
                                    aux[index++] = invertedFront[j + 1][k];
                                }
                            }
                        }
                        contribution[i] = hyperVolume.CalculateHypervolume(invertedFront[0], invertedFront[0].Length, numberOfObjectives)
                                          - hyperVolume.CalculateHypervolume(aux, aux.Length, numberOfObjectives);
                    }
                }
            }

            return(contribution);
        }
Beispiel #10
0
        /// <summary>
        /// Calculates the hv contribution of different populations. Receives an
        /// array of populations and computes the contribution to HV of the
        /// population consisting in the union of all of them
        /// </summary>
        /// <param name="populations">Consisting in all the populatoins</param>
        /// <returns>HV contributions of each population</returns>
        public double[] HVContributions(SolutionSet[] populations)
        {
            bool empty = true;

            foreach (SolutionSet population2 in populations)
            {
                if (population2.Size() > 0)
                {
                    empty = false;
                }
            }

            if (empty)
            {
                double[] contributions = new double[populations.Length];
                for (int i = 0; i < populations.Length; i++)
                {
                    contributions[i] = 0;
                }
                for (int i = 0; i < populations.Length; i++)
                {
                    Logger.Log.Info("Contributions: " + contributions[i]);
                    Console.WriteLine(contributions[i]);
                }
                return(contributions);
            }

            SolutionSet union;
            int         size    = 0;
            double      offset_ = 0.0;

            //determining the global size of the population
            foreach (SolutionSet population1 in populations)
            {
                size += population1.Size();
            }

            //allocating space for the union
            union = new SolutionSet(size);

            // filling union
            foreach (SolutionSet population in populations)
            {
                for (int j = 0; j < population.Size(); j++)
                {
                    union.Add(population.Get(j));
                }
            }

            //determining the number of objectives
            int numberOfObjectives = union.Get(0).NumberOfObjectives;

            //writing everything in matrices
            double[][][] frontValues = new double[populations.Length + 1][][];

            frontValues[0] = union.WriteObjectivesToMatrix();
            for (int i = 0; i < populations.Length; i++)
            {
                if (populations[i].Size() > 0)
                {
                    frontValues[i + 1] = populations[i].WriteObjectivesToMatrix();
                }
                else
                {
                    frontValues[i + 1] = new double[0][];
                }
            }

            // obtain the maximum and minimum values of the Pareto front
            double[] maximumValues = GetMaximumValues(union.WriteObjectivesToMatrix(), numberOfObjectives);
            double[] minimumValues = GetMinimumValues(union.WriteObjectivesToMatrix(), numberOfObjectives);

            // normalized all the fronts
            double[][][] normalizedFront = new double[populations.Length + 1][][];
            for (int i = 0; i < normalizedFront.Length; i++)
            {
                if (frontValues[i].Length > 0)
                {
                    normalizedFront[i] = GetNormalizedFront(frontValues[i], maximumValues, minimumValues);
                }
                else
                {
                    normalizedFront[i] = new double[0][];
                }
            }

            // compute offsets for reference point in normalized space
            double[] offsets = new double[maximumValues.Length];
            for (int i = 0; i < maximumValues.Length; i++)
            {
                offsets[i] = offset_ / (maximumValues[i] - minimumValues[i]);
            }

            //Inverse all the fronts front. This is needed because the original
            //metric by Zitzler is for maximization problems
            double[][][] invertedFront = new double[populations.Length + 1][][];
            for (int i = 0; i < invertedFront.Length; i++)
            {
                if (normalizedFront[i].Length > 0)
                {
                    invertedFront[i] = InvertedFront(normalizedFront[i]);
                }
                else
                {
                    invertedFront[i] = new double[0][];
                }
            }

            // shift away from origin, so that boundary points also get a contribution > 0
            foreach (double[][] anInvertedFront in invertedFront)
            {
                foreach (double[] point in anInvertedFront)
                {
                    for (int i = 0; i < point.Length; i++)
                    {
                        point[i] += offsets[i];
                    }
                }
            }

            // calculate contributions
            double[]    contribution = new double[populations.Length];
            HyperVolume hyperVolume  = new HyperVolume();

            for (int i = 0; i < populations.Length; i++)
            {
                if (invertedFront[i + 1].Length == 0)
                {
                    contribution[i] = 0;
                }
                else
                {
                    if (invertedFront[i + 1].Length != invertedFront[0].Length)
                    {
                        double[][] aux = new double[invertedFront[0].Length - invertedFront[i + 1].Length][];
                        int        startPoint = 0, endPoint;
                        for (int j = 0; j < i; j++)
                        {
                            startPoint += invertedFront[j + 1].Length;
                        }
                        endPoint = startPoint + invertedFront[i + 1].Length;
                        int index = 0;
                        for (int j = 0; j < invertedFront[0].Length; j++)
                        {
                            if (j < startPoint || j >= (endPoint))
                            {
                                aux[index++] = invertedFront[0][j];
                            }
                        }

                        contribution[i] = hyperVolume.CalculateHypervolume(invertedFront[0], invertedFront[0].Length, numberOfObjectives)
                                          - hyperVolume.CalculateHypervolume(aux, aux.Length, numberOfObjectives);
                    }
                    else
                    {
                        contribution[i] = hyperVolume.CalculateHypervolume(invertedFront[0], invertedFront[0].Length, numberOfObjectives);
                    }
                }
            }

            return(contribution);
        }