public double ComputeHypervolume(SolutionSet solutionSet, Solution referencePoint) { double hv = 0.0; if (solutionSet.Size() == 0) { hv = 0.0; } else { this.numberOfObjectives = solutionSet.Get(0).NumberOfObjectives; this.referencePoint = referencePoint; if (this.numberOfObjectives == 2) { solutionSet.Sort(new ObjectiveComparator(this.numberOfObjectives - 1, true)); hv = Get2DHV(solutionSet); } else { WFGHV wfg = new WFGHV(this.numberOfObjectives, solutionSet.Size()); Front front = new Front(solutionSet.Size(), numberOfObjectives, solutionSet); hv = wfg.GetHV(front, referencePoint); } } return(hv); }
public override Solution GetOffspring(SolutionSet solutionSet, int index) { Solution[] parents = new Solution[3]; Solution offSpring = null; try { int r1, r2; do { r1 = JMetalRandom.Next(0, solutionSet.Size() - 1); } while (r1 == index); do { r2 = JMetalRandom.Next(0, solutionSet.Size() - 1); } while (r2 == index || r2 == r1); parents[0] = solutionSet.Get(r1); parents[1] = solutionSet.Get(r2); parents[2] = solutionSet.Get(index); offSpring = (Solution)crossover.Execute(new object[] { solutionSet.Get(index), parents }); } catch (Exception ex) { Logger.Log.Error("Exception in " + this.GetType().FullName + ".GetOffSpring()", ex); Console.Error.WriteLine("Exception in " + this.GetType().FullName + ".GetOffSpring()"); } //Create a new solution, using DE return(offSpring); }
public double ComputeHypervolume(SolutionSet solutionSet) { double hv; if (solutionSet.Size() == 0) { hv = 0.0; } else { numberOfObjectives = solutionSet.Get(0).NumberOfObjectives; referencePoint = new Solution(numberOfObjectives); UpdateReferencePoint(solutionSet); if (numberOfObjectives == 2) { solutionSet.Sort(new ObjectiveComparator(numberOfObjectives - 1, true)); hv = Get2DHV(solutionSet); } else { UpdateReferencePoint(solutionSet); Front front = new Front(solutionSet.Size(), numberOfObjectives, solutionSet); hv = new WFGHV(numberOfObjectives, solutionSet.Size(), referencePoint).GetHV(front); } } return(hv); }
public void LoadFront(SolutionSet solutionSet, int notLoadingIndex) { if (notLoadingIndex >= 0 && notLoadingIndex < solutionSet.Size()) { NumberOfPoints = solutionSet.Size() - 1; } else { NumberOfPoints = solutionSet.Size(); } NPoints = NumberOfPoints; dimension = solutionSet.Get(0).NumberOfObjectives; Points = new Point[NumberOfPoints]; int index = 0; for (int i = 0; i < solutionSet.Size(); i++) { if (i != notLoadingIndex) { double[] vector = new double[dimension]; for (int j = 0; j < dimension; j++) { vector[j] = solutionSet.Get(i).Objective[j]; } Points[index++] = new Point(vector); } } }
/// <summary> /// Computes the HV contribution of the solutions /// </summary> /// <param name="solutionSet"></param> public void ComputeHVContributions(SolutionSet solutionSet) { double[] contributions = new double[solutionSet.Size()]; double solutionSetHV = 0; solutionSetHV = ComputeHypervolume(solutionSet); for (int i = 0; i < solutionSet.Size(); i++) { Solution currentPoint = solutionSet.Get(i); solutionSet.Remove(i); if (numberOfObjectives == 2) { contributions[i] = solutionSetHV - Get2DHV(solutionSet); } else { Front front = new Front(solutionSet.Size(), numberOfObjectives, solutionSet); double hv = new WFGHV(numberOfObjectives, solutionSet.Size(), referencePoint).GetHV(front); contributions[i] = solutionSetHV - hv; } solutionSet.Add(i, currentPoint); } for (int i = 0; i < solutionSet.Size(); i++) { solutionSet.Get(i).CrowdingDistance = contributions[i]; } }
/// <summary> /// Returns a matrix with distances between solutions in a <code>SolutionSet</code>. /// </summary> /// <param name="solutionSet">The <code>SolutionSet</code>.</param> /// <returns>a matrix with distances.</returns> public double[][] DistanceMatrix(SolutionSet solutionSet) { Solution solutionI, solutionJ; //The matrix of distances double[][] distance = new double[solutionSet.Size()][]; for (int i = 0; i < solutionSet.Size(); i++) { distance[i] = new double[solutionSet.Size()]; } //-> Calculate the distances for (int i = 0; i < solutionSet.Size(); i++) { distance[i][i] = 0.0; solutionI = solutionSet.Get(i); for (int j = i + 1; j < solutionSet.Size(); j++) { solutionJ = solutionSet.Get(j); distance[i][j] = this.DistanceBetweenObjectives(solutionI, solutionJ); distance[j][i] = distance[i][j]; } } //->Return the matrix of distances return(distance); }
/// <summary> /// Executes the operation /// </summary> /// <param name="obj">An object containing the population and the position (index) of the current individual</param> /// <returns>An object containing the three selected parents</returns> public override object Execute(object obj) { object[] parameters = (object[])obj; SolutionSet population = (SolutionSet)parameters[0]; int index = (int)parameters[1]; Solution[] parents = new Solution[3]; int r1, r2, r3; if (population.Size() < 4) { throw new Exception("DifferentialEvolutionSelection: the population has less than four solutions"); } do { r1 = (int)(JMetalRandom.Next(0, population.Size() - 1)); } while (r1 == index); do { r2 = (int)(JMetalRandom.Next(0, population.Size() - 1)); } while (r2 == index || r2 == r1); do { r3 = (int)(JMetalRandom.Next(0, population.Size() - 1)); } while (r3 == index || r3 == r1 || r3 == r2); parents[0] = population.Get(r1); parents[1] = population.Get(r2); parents[2] = population.Get(r3); return(parents); }
/// <summary> /// Computes the feasibility ratio /// </summary> /// <param name="solutionSet"></param> /// <returns>The ratio of feasible solutions</returns> private double MeanOveralViolation(SolutionSet solutionSet) { double aux = 0.0; for (int i = 0; i < solutionSet.Size(); i++) { aux += Math.Abs(solutionSet.Get(i).NumberOfViolatedConstraints *solutionSet.Get(i).OverallConstraintViolation); } return(aux / (double)solutionSet.Size()); }
/// <summary> /// Performs the operation /// </summary> /// <param name="obj">Object representing a SolutionSet.</param> /// <returns>An object representing a <code>SolutionSet<code> with the selected parents</returns> public override object Execute(object obj) { SolutionSet population = (SolutionSet)obj; int populationSize = (int)Parameters["populationSize"]; SolutionSet result = new SolutionSet(populationSize); //->Ranking the union Ranking ranking = new Ranking(population); int remain = populationSize; int index = 0; SolutionSet front = null; population.Clear(); //-> Obtain the next front front = ranking.GetSubfront(index); while ((remain > 0) && (remain >= front.Size())) { //Asign crowding distance to individuals distance.CrowdingDistanceAssignment(front, problem.NumberOfObjectives); //Add the individuals of this front for (int k = 0; k < front.Size(); k++) { result.Add(front.Get(k)); } //Decrement remaint remain = remain - front.Size(); //Obtain the next front index++; if (remain > 0) { front = ranking.GetSubfront(index); } } //-> remain is less than front(index).size, insert only the best one if (remain > 0) { // front containt individuals to insert distance.CrowdingDistanceAssignment(front, problem.NumberOfObjectives); front.Sort(crowdingComparator); for (int k = 0; k < remain; k++) { result.Add(front.Get(k)); } remain = 0; } return(result); }
/// <summary> /// Computes the feasibility ratio /// </summary> /// <param name="solutionSet"></param> /// <returns>The ratio of feasible solutions</returns> private double FeasibilityRatio(SolutionSet solutionSet) { double aux = 0.0; for (int i = 0; i < solutionSet.Size(); i++) { if (solutionSet.Get(i).OverallConstraintViolation < 0) { aux = aux + 1.0; } } return(aux / (double)solutionSet.Size()); }
/// <summary> /// Return the index of the nearest solution in the solution set to a given solution /// </summary> /// <param name="solution"></param> /// <param name="solutionSet"></param> /// <returns>The index of the nearest solution; -1 if the solutionSet is empty</returns> public int IndexToNearestSolutionInSolutionSpace(Solution solution, SolutionSet solutionSet) { int index = -1; double minimumDistance = double.MaxValue; try { for (int i = 0; i < solutionSet.Size(); i++) { double distance = 0; distance = this.DistanceBetweenSolutions(solution, solutionSet.Get(i)); if (distance < minimumDistance) { minimumDistance = distance; index = i; } } } catch (Exception ex) { Logger.Log.Error("Exception in " + this.GetType().FullName + ".IndexToNearestSolutionInSolutionSpace()", ex); Console.WriteLine("Exception in " + this.GetType().FullName + ".IndexToNearestSolutionInSolutionSpace()"); } return(index); }
/// <summary> /// Computes the HV of a solution set. /// REQUIRES: The problem is bi-objective /// REQUIRES: The archive is ordered in descending order by the second objective /// </summary> /// <param name="solutionSet"></param> /// <returns></returns> public double Get2DHV(SolutionSet solutionSet) { double hv = 0.0; if (solutionSet.Size() > 0) { hv = Math.Abs((solutionSet.Get(0).Objective[0] - referencePoint.Objective[0]) * (solutionSet.Get(0).Objective[1] - referencePoint.Objective[1])); for (int i = 1; i < solutionSet.Size(); i++) { double tmp = Math.Abs((solutionSet.Get(i).Objective[0] - referencePoint.Objective[0]) * (solutionSet.Get(i).Objective[1] - solutionSet.Get(i - 1).Objective[1])); hv += tmp; } } return(hv); }
public int GetLessContributorHV(SolutionSet set) { Front wholeFront = new Front(); wholeFront.LoadFront(set, -1); int index = 0; double contribution = double.PositiveInfinity; for (int i = 0; i < set.Size(); i++) { double[] v = new double[set.Get(i).NumberOfObjectives]; for (int j = 0; j < v.Length; j++) { v[j] = set.Get(i).Objective[j]; } Point p = new Point(v); double aux = this.GetExclusiveHV(wholeFront, i); if ((aux) < contribution) { index = i; contribution = aux; } set.Get(i).CrowdingDistance = aux; } return(index); }
/// <summary> /// Updates the grid limits considering the solutions contained in a <code>SolutionSet</code>. /// </summary> /// <param name="solutionSet">The <code>SolutionSet</code> considered.</param> private void UpdateLimits(SolutionSet solutionSet) { //Init the lower and upper limits for (int obj = 0; obj < objectives; obj++) { //Set the lower limits to the max real lowerLimits[obj] = double.MaxValue; //Set the upper limits to the min real upperLimits[obj] = double.MinValue; } //Find the max and min limits of objetives into the population for (int ind = 0; ind < solutionSet.Size(); ind++) { Solution tmpIndividual = solutionSet.Get(ind); for (int obj = 0; obj < objectives; obj++) { if (tmpIndividual.Objective[obj] < lowerLimits[obj]) { lowerLimits[obj] = tmpIndividual.Objective[obj]; } if (tmpIndividual.Objective[obj] > upperLimits[obj]) { upperLimits[obj] = tmpIndividual.Objective[obj]; } } } }
public override Solution GetOffspring(SolutionSet solutionSet, SolutionSet archive) { Solution[] parents = new Solution[2]; Solution offSpring = null; try { parents[0] = (Solution)selection.Execute(solutionSet); if (archive.Size() > 0) { parents[1] = (Solution)selection.Execute(archive); } else { parents[1] = (Solution)selection.Execute(solutionSet); } Solution[] children = (Solution[])crossover.Execute(parents); offSpring = children[0]; //Create a new solution, using DE } catch (Exception ex) { Logger.Log.Error("Error in: " + this.GetType().FullName + ".GetOffspring()", ex); Console.Error.WriteLine("Error in: " + this.GetType().FullName); } return(offSpring); }
/// <summary> /// Assigns fitness for all the solutions. /// </summary> public void FitnessAssign() { double[] strength = new double[solutionSet.Size()]; double[] rawFitness = new double[solutionSet.Size()]; double kDistance; //Calculate the strength value // strength(i) = |{j | j <- SolutionSet and i dominate j}| for (int i = 0; i < solutionSet.Size(); i++) { for (int j = 0; j < solutionSet.Size(); j++) { if (dominance.Compare(solutionSet.Get(i), solutionSet.Get(j)) == -1) { strength[i] += 1.0; } } } //Calculate the raw fitness // rawFitness(i) = |{sum strenght(j) | j <- SolutionSet and j dominate i}| for (int i = 0; i < solutionSet.Size(); i++) { for (int j = 0; j < solutionSet.Size(); j++) { if (dominance.Compare(solutionSet.Get(i), solutionSet.Get(j)) == 1) { rawFitness[i] += strength[j]; } } } // Add the distance to the k-th individual. In the reference paper of SPEA2, // k = sqrt(population.size()), but a value of k = 1 recommended. See // http://www.tik.ee.ethz.ch/pisa/selectors/spea2/spea2_documentation.txt int k = 1; for (int i = 0; i < distanceMatrix.Length; i++) { Array.Sort(distanceMatrix[i]); kDistance = 1.0 / (distanceMatrix[i][k] + 2.0); // Calcule de D(i) distance solutionSet.Get(i).Fitness = rawFitness[i] + kDistance; } }
/// <summary> /// Tries to update the reference set one with a <code>Solution</code>. /// </summary> /// <param name="solution">The <code>Solution</code></param> /// <returns>true if the <code>Solution</code> has been inserted, false /// otherwise.</returns> public bool RefSet1Test(Solution solution) { bool dominated = false; int flag; int i = 0; while (i < refSet1.Size()) { flag = dominance.Compare(solution, refSet1.Get(i)); if (flag == -1) { //This is: solution dominates refSet1.Remove(i); } else if (flag == 1) { dominated = true; i++; } else { flag = equal.Compare(solution, refSet1.Get(i)); if (flag == 0) { return(true); } i++; } } if (!dominated) { solution.UnMarked(); if (refSet1.Size() < refSet1Size) { //refSet1 isn't full refSet1.Add(solution); } else { archive.Add(solution); } } else { return(false); } return(true); }
/// <summary> /// /// </summary> /// <param name="cid">the id of current subproblem</param> /// <param name="type">1 - whole population probability; otherwise - whole neighborhood probability</param> /*public int ACOrSelection4(int cid, int type) * { * int ss; * ss = neighborhood[cid].Length; * double r; * int b = neighborhood[cid][0]; * Solution[] parents = new Solution[ss]; * double[] fitness = new double[ss]; * Solution[] parent = new Solution[populationSize]; * double[] fit = new double[populationSize]; * double sum = 0; * double[] pro = new double[ss]; * double[] p = new double[populationSize]; * double a1 = 0; * double a2 = 0; * * if (type == 1) * { * for (int i = 0; i < ss; i++) * { * parents[i] = population.Get(neighborhood[cid][i]); * fitness[i] = 1 / FitnessFunction(parents[i], lambda[cid]); * sum = sum + fitness[i]; * } * for (int j = 0; j < ss; j++) * { * pro[j] = fitness[j] / sum; * } * r = JMetalRandom.NextDouble(); * for (int k = 0; k < pro.Length; k++) * { * a2 = a2 + pro[k]; * if (r < a2 && r >= a1) * { * b = neighborhood[cid][k]; * break; * } * a1 = a1 + pro[k]; * } * } * else * { * for (int i = 0; i < populationSize; i++) * { * parent[i] = population.Get(i); * fit[i] = 1 / FitnessFunction(parent[i], lambda[cid]); * sum = sum + fit[i]; * } * for (int j = 0; j < populationSize; j++) * { * p[j] = fit[j] / sum; * } * r = JMetalRandom.NextDouble(); * for (int k = 0; k < p.Length; k++) * { * a2 = a2 + p[k]; * if (r < a2 && r >= a1) * { * b = k; * break; * } * a1 = a1 + p[k]; * } * } * * return b; * }*/ /// <summary> /// /// </summary> /// <param name="indiv">child solution</param> /// <param name="id">the id of current subproblem</param> /// <param name="type">update solutions in - neighborhood (1) or whole population (otherwise)</param> private void UpdateProblem(Solution indiv, int id, int type) { int size; int time; time = 0; if (type == 1) { size = neighborhood[id].Length; } else { size = population.Size(); } int[] perm = new int[size]; Utils.RandomPermutation(perm, size); for (int i = 0; i < size; i++) { int k; if (type == 1) { k = neighborhood[id][perm[i]]; } else { k = perm[i]; // calculate the values of objective function regarding the current subproblem } double f1, f2; f1 = FitnessFunction(population.Get(k), lambda[k]); f2 = FitnessFunction(indiv, lambda[k]); if (f2 < f1) { population.Replace(k, new Solution(indiv)); time++; } // the maximal number of solutions updated is not allowed to exceed 'limit' if (time >= nr) { return; } } }
/// <summary> /// Assigns crowding distances to all solutions in a <code>SolutionSet</code>. /// </summary> /// <param name="solutionSet">The <code>SolutionSet</code>.</param> /// <param name="nObjs">Number of objectives.</param> public void CrowdingDistanceAssignment(SolutionSet solutionSet, int nObjs) { int size = solutionSet.Size(); if (size == 0) { return; } if (size == 1) { solutionSet.Get(0).CrowdingDistance = double.PositiveInfinity; return; } if (size == 2) { solutionSet.Get(0).CrowdingDistance = double.PositiveInfinity; solutionSet.Get(1).CrowdingDistance = double.PositiveInfinity; return; } //Use a new SolutionSet to evite alter original solutionSet SolutionSet front = new SolutionSet(size); for (int i = 0; i < size; i++) { front.Add(solutionSet.Get(i)); } for (int i = 0; i < size; i++) { front.Get(i).CrowdingDistance = 0.0; } double objetiveMaxn; double objetiveMinn; double distance; for (int i = 0; i < nObjs; i++) { // Sort the population by Obj n front.Sort(new ObjectiveComparator(i)); objetiveMinn = front.Get(0).Objective[i]; objetiveMaxn = front.Get(front.Size() - 1).Objective[i]; //Set de crowding distance front.Get(0).CrowdingDistance = double.PositiveInfinity; front.Get(size - 1).CrowdingDistance = double.PositiveInfinity; for (int j = 1; j < size - 1; j++) { distance = front.Get(j + 1).Objective[i] - front.Get(j - 1).Objective[i]; distance = distance / (objetiveMaxn - objetiveMinn); distance += front.Get(j).CrowdingDistance; front.Get(j).CrowdingDistance = distance; } } }
/// <summary> /// Constructor. /// Creates a new instance of Spea2Fitness for a given <code>SolutionSet</code>. /// </summary> /// <param name="solutionSet">The <code>SolutionSet</code></param> public Spea2Fitness(SolutionSet solutionSet) { this.distanceMatrix = distance.DistanceMatrix(solutionSet); this.solutionSet = solutionSet; for (int i = 0; i < solutionSet.Size(); i++) { solutionSet.Get(i).Location = i; } }
/// <summary> /// Performs the operation /// </summary> /// <param name="obj">Object representing a SolutionSet.</param> /// <returns>An object representing an array with the selected parents</returns> public override object Execute(object obj) { SolutionSet population = (SolutionSet)obj; int pos1, pos2; pos1 = JMetalRandom.Next(0, population.Size() - 1); pos2 = JMetalRandom.Next(0, population.Size() - 1); while ((pos1 == pos2) && (population.Size() > 1)) { pos2 = JMetalRandom.Next(0, population.Size() - 1); } Solution[] parents = new Solution[2]; parents[0] = population.Get(pos1); parents[1] = population.Get(pos2); return(parents); }
/// <summary> /// Performs the operation /// </summary> /// <param name="obj">Object representing a SolutionSet</param> /// <returns>The selected solution</returns> public override object Execute(object obj) { SolutionSet population = (SolutionSet)obj; if (index == 0) //Create the permutation { a = (new PermutationUtility()).IntPermutation(population.Size()); } Solution solution1, solution2; solution1 = population.Get(a[index]); solution2 = population.Get(a[index + 1]); index = (index + 2) % population.Size(); int flag = dominance.Compare(solution1, solution2); if (flag == -1) { return(solution1); } else if (flag == 1) { return(solution2); } else if (solution1.CrowdingDistance > solution2.CrowdingDistance) { return(solution1); } else if (solution2.CrowdingDistance > solution1.CrowdingDistance) { return(solution2); } else if (JMetalRandom.NextDouble() < 0.5) { return(solution1); } else { return(solution2); } }
/// <summary> /// Performs the operation /// </summary> /// <param name="obj">Object representing a SolutionSet.</param> /// <returns>the best solution found</returns> public override object Execute(object obj) { SolutionSet solutionSet = (SolutionSet)obj; if (solutionSet.Size() == 0) { return(null); } int bestSolution; bestSolution = 0; for (int i = 1; i < solutionSet.Size(); i++) { if (comparator.Compare(solutionSet.Get(i), solutionSet.Get(bestSolution)) < 0) { bestSolution = i; } } return(bestSolution); }
/// <summary> /// Performs the operation /// </summary> /// <param name="obj">Object representing a SolutionSet</param> /// <returns>The selected solution</returns> public override object Execute(object obj) { SolutionSet solutionSet = (SolutionSet)obj; Solution solution1, solution2; solution1 = solutionSet.Get(JMetalRandom.Next(0, solutionSet.Size() - 1)); solution2 = solutionSet.Get(JMetalRandom.Next(0, solutionSet.Size() - 1)); if (solutionSet.Size() >= 2) { while (solution1 == solution2) { solution2 = solutionSet.Get(JMetalRandom.Next(0, solutionSet.Size() - 1)); } } int flag = comparator.Compare(solution1, solution2); if (flag == -1) { return(solution1); } else if (flag == 1) { return(solution2); } else if (JMetalRandom.NextDouble() < 0.5) { return(solution1); } else { return(solution2); } }
/// <summary> /// Apply a mutation operator to some particles in the swarm /// </summary> /// <param name="actualIteration"></param> /// <param name="totalIterations"></param> private void MopsoMutation(int actualIteration, int totalIterations) { for (int i = 0; i < particles.Size(); i++) { if ((i % 6) == 0) { polynomialMutation.Execute(particles.Get(i)); } } }
/// <summary> /// Returns the minimum distance from a <code>Solution</code> to a /// <code>SolutionSet according to the encodings.variable values</code>. /// </summary> /// <param name="solution">The <code>Solution</code></param> /// <param name="solutionSet">The <code>SolutionSet</code>.</param> /// <returns>The minimum distance between solution and the set.</returns> public double DistanceToSolutionSetInSolutionSpace(Solution solution, SolutionSet solutionSet) { //At start point the distance is the max double distance = double.MaxValue; // found the min distance respect to population for (int i = 0; i < solutionSet.Size(); i++) { double aux = this.DistanceBetweenSolutions(solution, solutionSet.Get(i)); if (aux < distance) { distance = aux; } } //->Return the best distance return(distance); }
/// <summary> /// Updates the grid adding solutions contained in a specific /// <code>SolutionSet</code>. /// <b>REQUIRE</b> The grid limits must have been previously calculated. /// </summary> /// <param name="solutionSet">The <code>SolutionSet</code> considered.</param> private void AddSolutionSet(SolutionSet solutionSet) { //Calculate the location of all individuals and update the grid MostPopulated = 0; int location; for (int ind = 0; ind < solutionSet.Size(); ind++) { location = Location(solutionSet.Get(ind)); hypercubes[location]++; if (hypercubes[location] > hypercubes[MostPopulated]) { MostPopulated = location; } } //The grid has been updated, so also update ocuppied's hypercubes CalculateOccupied(); }
public Solution GetBest(double w1, double w2, double w3) { var size = _solutions.Size(); _solution = -1; var min = double.MaxValue; double wsum = -1; for (var i = 0; i < size; i++) { wsum = w1 * _f1Scaled[i] + w2 * _f2Scaled[i] + w3 * _f3Scaled[i]; if (!(wsum < min)) { continue; } min = wsum; _solution = i; } //Console.WriteLine("Best solution: " + _solution + " wsum= " + wsum); return(_solutions.Get(_solution)); }
/// <summary> /// Updates the reference point /// </summary> /// <param name="solutionSet"></param> private void UpdateReferencePoint(SolutionSet solutionSet) { double[] maxObjectives = new double[numberOfObjectives]; for (int i = 0; i < numberOfObjectives; i++) { maxObjectives[i] = 0; } for (int i = 0; i < solutionSet.Size(); i++) { for (int j = 0; j < numberOfObjectives; j++) { if (maxObjectives[j] < solutionSet.Get(i).Objective[j]) { maxObjectives[j] = solutionSet.Get(i).Objective[j]; } } } for (int i = 0; i < referencePoint.NumberOfObjectives; i++) { referencePoint.Objective[i] = maxObjectives[i] + offset; } }
/// <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); }