/** * Computes the feasibility ratio * Return the ratio of feasible solutions */ public double MeanOveralViolation(SolutionSet solutionSet) { double aux = 0.0; for (int i = 0; i < solutionSet.Size(); i++) { aux += Math.Abs(solutionSet[i].NumberOfViolatedConstraints* solutionSet[i].OverallConstraintViolation); } return aux/solutionSet.Size(); }
/** * Computes the feasibility ratio * Return the ratio of feasible solutions */ public double FeasibilityRatio(SolutionSet solutionSet) { double aux = 0.0; for (int i = 0; i < solutionSet.Size(); i++) { if (solutionSet[i].OverallConstraintViolation < 0) { aux = aux + 1.0; } } return aux/solutionSet.Size(); }
/** Assigns crowding distances to all solutions in a <code>SolutionSet</code>. * @param solutionSet The <code>SolutionSet</code>. * @param nObjs Number of objectives. */ public static void CrowdingDistanceAssignment(SolutionSet solutionSet, int nObjs) { int size = solutionSet.Size(); if (size == 0) { return; } if (size == 1) { solutionSet[0].CrowdingDistance = (double.PositiveInfinity); return; } // if if (size == 2) { solutionSet[0].CrowdingDistance = (double.PositiveInfinity); solutionSet[1].CrowdingDistance = (double.PositiveInfinity); return; } // if //Use a new SolutionSet to evite alter original solutionSet SolutionSet front = new SolutionSet(size); for (int i = 0; i < size; i++) { front.Add(solutionSet[i]); } for (int i = 0; i < size; i++) { front[i].CrowdingDistance = (0.0); } for (int i = 0; i < nObjs; i++) { // Sort the population by Obj n front.Sort(new ObjectiveComparator(i)); double objetiveMinn = front[0].Objective[i]; double objetiveMaxn = front[front.Size() - 1].Objective[i]; //Set de crowding distance front[0].CrowdingDistance = (double.PositiveInfinity); front[size - 1].CrowdingDistance = (double.PositiveInfinity); for (int j = 1; j < size - 1; j++) { double distance = front[j + 1].Objective[i] - front[j - 1].Objective[i]; distance = distance/(objetiveMaxn - objetiveMinn); distance += front[j].CrowdingDistance; front[j].CrowdingDistance = (distance); } // for } // for }
public ThetaNonDominatedSort(SolutionSet population, List<Cluster> clusters, double theta) { Dominance = new ThetaComparator(theta); _solutionSet = population; _ranking = new List<SolutionSet>(); // dominateMe[i] contains the number of solutions dominating i int[] dominateMe = new int[_solutionSet.Size()]; // iDominate[k] contains the list of solutions dominated by k List<int>[] iDominate = new List<int>[_solutionSet.Size()]; // front[i] contains the list of individuals belonging to the front i List<int>[] front = new List<int>[_solutionSet.Size() + 1]; // flagDominate is an auxiliar encodings.variable int flagDominate; for (int p = 0; p < (clusters.Count - 1); p++) { // Initialize the fronts for (int k = 0; k < front.Length; k++) { front[k] = new List<int>(); } for (int q = 0; q < clusters[p].Count; q++) { // Initialize the list of individuals that i dominate and the number // of individuals that dominate me iDominate[q] = new List<int>(); dominateMe[q] = 0; } for (int q = 0; q < (clusters[p].Count - 1); q++) { for (int r = q + 1; r < (clusters[p].Count - 1); r++) { flagDominate = Dominance.Compare(clusters[p][q].Item2, clusters[p][r].Item2); //flagDominate = Constraint.Compare(clusters[p][q].Item1, clusters[p][r].Item1); if (flagDominate == 0) { flagDominate = Dominance.Compare(clusters[p][q].Item2, clusters[p][r].Item2); } if (flagDominate == -1) { iDominate[q].Add(r); dominateMe[r]++; } else if (flagDominate == 1) { iDominate[r].Add(q); dominateMe[q]++; } } } //Fill front if (_ranking.Count == 0) { _ranking.Add(new SolutionSet(population.Size())); } for (int q = 0; q < clusters[p].Count; q++) { if (dominateMe[q] == 0) { front[0].Add(q); _ranking[0].Add(clusters[p][q].Item1); clusters[p][q].Item1.Rank = 0; } } //Obtain the rest of fronts int i = 0; IEnumerator<int> it1; // Iterators while (front[i].Count != 0) { i++; if (i >= _ranking.Count) { _ranking.Add(new SolutionSet(population.Size())); } it1 = front[i - 1].GetEnumerator(); while (it1.MoveNext()) { IEnumerator<int> it2 = iDominate[it1.Current].GetEnumerator(); // Iterators while (it2.MoveNext()) { int index = it2.Current; dominateMe[index]--; if (dominateMe[index] == 0) { front[i].Add(index); _ranking[i].Add(clusters[p][index].Item1); clusters[p][index].Item1.Rank = i; } } } } } }
public override SolutionSet Execute() { int populationSize; int maxEvaluations; QualityIndicator indicators; Operator mutationOperator; Operator crossoverOperator; Operator selectionOperator; object parameter; if (InputParameters.TryGetValue("populationSize", out parameter)) { populationSize = (int) parameter; } else { throw new Exception("populationSize does not exist"); } if (InputParameters.TryGetValue("maxEvaluations", out parameter)) { maxEvaluations = (int) parameter; } else { throw new Exception("maxEvaluations does not exist"); } if (InputParameters.TryGetValue("indicators", out parameter)) { indicators = (QualityIndicator) parameter; } else { throw new Exception("maxEvaluations does not exist"); } if (InputParameters.TryGetValue("theta", out parameter)) { Theta = (int) parameter; } else { throw new Exception("Theta does not exist"); } if (InputParameters.TryGetValue("H", out parameter)) { K = MetalMath.BinomialCoeff(Problema.NumberOfObjectives - 1, ((int) parameter) + Problema.NumberOfObjectives - 1); } else { throw new Exception("H does not exist"); } // Initializing variables var population = new SolutionSet(populationSize); var evaluations = 0; int requiredEvaluations = 0; Operator unknownIOperator; //Read the operators if (UsedOperators.TryGetValue("mutation", out unknownIOperator)) { mutationOperator = unknownIOperator; } else { throw new Exception("mutation does not exist"); } if (UsedOperators.TryGetValue("crossover", out unknownIOperator)) { crossoverOperator = unknownIOperator; } else { throw new Exception("crossover does not exist"); } if (UsedOperators.TryGetValue("selection", out unknownIOperator)) { selectionOperator = unknownIOperator; } else { throw new Exception("selection does not exist"); } K = populationSize; ReferencePoints = new Solution[K]; //Create references points GenerateReferencePoint(); // Create the initial solutionSet for (int i = 0; i < populationSize; i++) { var newSolution = new Solution(Problema); Problema.Evaluate(newSolution); Problema.EvaluateConstraints(newSolution); evaluations++; population.Add(newSolution); } IdealPoint = new Solution(Problema); for (var i = 0; i < Problema.NumberOfObjectives; i++) { IdealPoint.Objective[i] = double.PositiveInfinity; } ComputeIdealPoint(population); ThetaNonDominatedSort ranking = null; // Generations SolutionSet union = null; while (evaluations < maxEvaluations) { // Create the offSpring solutionSet var offspringPopulation = new SolutionSet(populationSize); Solution[] parents = new Solution[2]; for (int i = 0; i < (populationSize/2); i++) { if (evaluations < maxEvaluations) { //obtain parents parents[0] = (Solution) selectionOperator.Execute(population); parents[1] = (Solution) selectionOperator.Execute(population); Solution[] offSpring = (Solution[]) crossoverOperator.Execute(parents); mutationOperator.Execute(offSpring[0]); mutationOperator.Execute(offSpring[1]); Problema.Evaluate(offSpring[0]); Problema.EvaluateConstraints(offSpring[0]); Problema.Evaluate(offSpring[1]); Problema.EvaluateConstraints(offSpring[1]); offspringPopulation.Add(offSpring[0]); offspringPopulation.Add(offSpring[1]); evaluations += 2; } } //Update ideal point // Create the solutionSet union of solutionSet and offSpring union = population.Union(offspringPopulation); ComputeIdealPoint(offspringPopulation); //Normalize NormalizePopulation(union); //Clustering and non dominated sort ranking = new ThetaNonDominatedSort(union, Clustering(union), Theta); //Generate next pop population = new SolutionSet(populationSize); int front = 0; while (population.Size() + ranking.GetSubfront(front).Size() <= populationSize) { var frontResult = ranking.GetSubfront(front); foreach (var r in frontResult.SolutionList) { population.Add(r); } front++; } //Generate new pop var localList = ranking.GetSubfront(front).SolutionList.OrderBy(item => PseudoRandom.Instance().Next()).ToList(); int localSizePt1 = population.Size(); for (int i = 0; i < populationSize - localSizePt1; i++) { population.Add(localList[i]); } if ((indicators != null) && (requiredEvaluations == 0)) { /* double hv = indicators.GetHypervolume(population); if (hv >= (0.98 * indicators.GetTrueParetoFrontHypervolume())) { requiredEvaluations = evaluations; }*/ double gd = indicators.GetGd(ranking.GetSubfront(0)); Console.WriteLine(gd); } } OutputParameters["evaluations"] = requiredEvaluations; ranking.GetSubfront(0).PrintFeasibleFUN("FUN_THETA_NSGAIII"); Console.WriteLine("before quitting"); Console.WriteLine(indicators.GetGd(ranking.GetSubfront(0))); Console.WriteLine("before quitting"); return ranking.GetSubfront(0); }
private void ComputeIdealPoint(SolutionSet pop) { if (pop.Size() <= 0) { throw new Exception("Empty pop"); } pop.SolutionList.ForEach(sol => { for (var i = 0; i < sol.NumberOfObjectives; i++) { if (sol.Objective[i] < IdealPoint.Objective[i]) { IdealPoint.Objective[i] = sol.Objective[i]; } } }); }
private List<Cluster> Clustering(SolutionSet normalizedPop) { List<Cluster> clusters = new List<Cluster>(K); for (var c = 0; c < K; c++) { clusters.Add(new Cluster(ReferencePoints[c], normalizedPop.Size())); } for (var x = 0; x < normalizedPop.Size(); x++) { var k = 0; var min = Distance(normalizedPop.SolutionList[x], ReferencePoints[k]); for (var j = 1; j < K; j++) { var d2 = Distance(normalizedPop.SolutionList[x], ReferencePoints[j]); if (d2.Item2 < min.Item2) { min = d2; k = j; } } clusters[k].Add(normalizedPop.SolutionList[x], min); } return clusters; }
/** Returns the minimum distance from a <code>Solution</code> to a * <code>SolutionSet according to the encodings.variable values</code>. * @param solution The <code>Solution</code>. * @param solutionSet The <code>SolutionSet</code>. * @return The minimum distance between solution and the set. * @throws JMException */ public static 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 = DistanceBetweenSolutions(solution, solutionSet[i]); if (aux < distance) { distance = aux; } } // for //->Return the best distance return distance; }
/** * Return the index of the nearest solution in the solution set to a given solution * @param solution * @param solutionSet * @return The index of the nearest solution; -1 if the solutionSet is empty */ public static int IndexToNearestSolutionInSolutionSpace(Solution solution, SolutionSet solutionSet) { int index = -1; double minimumDistance = double.MaxValue; for (int i = 0; i < solutionSet.Size(); i++) { double distance = DistanceBetweenSolutions(solution, solutionSet[i]); if (distance < minimumDistance) { minimumDistance = distance; index = i; } } return index; }
/** * Returns a matrix with distances between solutions in a * <code>SolutionSet</code>. * @param solutionSet The <code>SolutionSet</code>. * @return a matrix with distances. */ public static double[][] DistanceMatrix(SolutionSet solutionSet) { //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; Solution solutionI = solutionSet[i]; for (int j = i + 1; j < solutionSet.Size(); j++) { Solution solutionJ = solutionSet[j]; distance[i][j] = DistanceBetweenObjectives(solutionI, solutionJ); distance[j][i] = distance[i][j]; } // for } // for //->Return the matrix of distances return distance; }
public Ranking(SolutionSet solutionSet) { _solutionSet = solutionSet; // dominateMe[i] contains the number of solutions dominating i int[] dominateMe = new int[_solutionSet.Size()]; // iDominate[k] contains the list of solutions dominated by k List<int>[] iDominate = new List<int>[_solutionSet.Size()]; // front[i] contains the list of individuals belonging to the front i List<int>[] front = new List<int>[_solutionSet.Size() + 1]; // flagDominate is an auxiliar encodings.variable int flagDominate; // Initialize the fronts for (int k = 0; k < front.Length; k++) { front[k] = new List<int>(); } //-> Fast non dominated sorting algorithm // Contribution of Guillaume Jacquenot for (int p = 0; p < _solutionSet.Size(); p++) { // Initialize the list of individuals that i dominate and the number // of individuals that dominate me iDominate[p] = new List<int>(); dominateMe[p] = 0; } for (int p = 0; p < (_solutionSet.Size() - 1); p++) { // For all q individuals , calculate if p dominates q or vice versa for (int q = p + 1; q < _solutionSet.Size(); q++) { flagDominate = Constraint.Compare(solutionSet[p], solutionSet[q]); if (flagDominate == 0) { flagDominate = Dominance.Compare(solutionSet[p], solutionSet[q]); } if (flagDominate == -1) { iDominate[p].Add(q); dominateMe[q]++; } else if (flagDominate == 1) { iDominate[q].Add(p); dominateMe[p]++; } } // If nobody dominates p, p belongs to the first front } for (int p = 0; p < _solutionSet.Size(); p++) { if (dominateMe[p] == 0) { front[0].Add(p); solutionSet[p].Rank = 0; } } //Obtain the rest of fronts int i = 0; IEnumerator<int> it1; // Iterators while (front[i].Count != 0) { i++; it1 = front[i - 1].GetEnumerator(); while (it1.MoveNext()) { IEnumerator<int> it2 = iDominate[it1.Current].GetEnumerator(); // Iterators while (it2.MoveNext()) { int index = it2.Current; dominateMe[index]--; if (dominateMe[index] == 0) { front[i].Add(index); _solutionSet[index].Rank = i; } } } } //<- _ranking = new SolutionSet[i]; //0,1,2,....,i-1 are front, then i fronts for (int j = 0; j < i; j++) { _ranking[j] = new SolutionSet(front[j].Count); it1 = front[j].GetEnumerator(); while (it1.MoveNext()) { _ranking[j].Add(solutionSet[it1.Current]); } } }
/** * Updates the grid limits considering the solutions contained in a * <code>SolutionSet</code>. * @param solutionSet The <code>SolutionSet</code> considered. */ 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[ind]; for (int obj = 0; obj < _objectives; obj++) { double tmpIndividualObjective = tmpIndividual.Objective[obj]; if (tmpIndividualObjective < _lowerLimits[obj]) { _lowerLimits[obj] = tmpIndividualObjective; } if (tmpIndividualObjective > _upperLimits[obj]) { _upperLimits[obj] = tmpIndividualObjective; } } } }
/** * Updates the grid adding solutions contained in a specific * <code>SolutionSet</code>. * <b>REQUIRE</b> The grid limits must have been previously calculated. * @param solutionSet The <code>SolutionSet</code> considered. */ private void AddSolutionSet(SolutionSet solutionSet) { //Calculate the location of all individuals and update the grid MostPopulated = 0; for (int ind = 0; ind < solutionSet.Size(); ind++) { int location = Location(solutionSet[ind]); Hypercubes[location]++; if (Hypercubes[location] > Hypercubes[MostPopulated]) { MostPopulated = location; } } //The grid has been updated, so also update ocuppied's hypercubes CalculateOccupied(); }
/// <summary> /// Joins two solution sets: the current one and the one passed as argument /// </summary> /// <param name="solutionSet"> /// A <see cref="SolutionSet" /> /// </param> /// <returns> /// A new solution set /// A <see cref="SolutionSet" /> /// </returns> public SolutionSet Union(SolutionSet solutionSet) { if (solutionSet == null) { throw new ArgumentNullException("solutionSet"); } //Check the correct size int newSize = Size() + solutionSet.Size(); if (newSize < Capacity) { newSize = Capacity; } //Create a new population var union = new SolutionSet(newSize); foreach (Solution solution in SolutionList) { union.Add(solution); } for (int i = Size(); i < (Size() + solutionSet.Size()); i++) { union.Add(solutionSet.SolutionList[i - Size()]); } return union; }