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); }
/// <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); }
/// <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); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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); }
/// <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); }