/// <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> /// Tries to update the reference set 2 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 RefSet2Test(Solution solution) { double aux; if (refSet2.Size() < refSet2Size) { solution.DistanceToSolutionSet = distance.DistanceToSolutionSetInSolutionSpace(solution, refSet1); aux = distance.DistanceToSolutionSetInSolutionSpace(solution, refSet2); if (aux < solution.DistanceToSolutionSet) { solution.DistanceToSolutionSet = aux; } refSet2.Add(solution); return(true); } solution.DistanceToSolutionSet = distance.DistanceToSolutionSetInSolutionSpace(solution, refSet1); aux = distance.DistanceToSolutionSetInSolutionSpace(solution, refSet2); if (aux < solution.DistanceToSolutionSet) { solution.DistanceToSolutionSet = aux; } double peor = 0.0; int index = 0; for (int i = 0; i < refSet2.Size(); i++) { aux = refSet2.Get(i).DistanceToSolutionSet; if (aux > peor) { peor = aux; index = i; } } if (solution.DistanceToSolutionSet < peor) { refSet2.Remove(index); //Update distances in REFSET2 for (int j = 0; j < refSet2.Size(); j++) { aux = distance.DistanceBetweenSolutions(refSet2.Get(j), solution); if (aux < refSet2.Get(j).DistanceToSolutionSet) { refSet2.Get(j).DistanceToSolutionSet = aux; } } solution.UnMarked(); refSet2.Add(solution); return(true); } return(false); }
/// <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> /// Implements the referenceSetUpdate method. /// </summary> /// <param name="build">build if true, indicates that the reference has to be build for the /// first time; if false, indicates that the reference set has to be /// updated with new solutions</param> public void ReferenceSetUpdate(bool build) { if (build) { // Build a new reference set // STEP 1. Select the p best individuals of P, where p is refSet1Size. // Selection Criterium: Spea2Fitness Solution individual; (new Spea2Fitness(solutionSet)).FitnessAssign(); solutionSet.Sort(fitness); // STEP 2. Build the RefSet1 with these p individuals for (int i = 0; i < refSet1Size; i++) { individual = solutionSet.Get(0); solutionSet.Remove(0); individual.UnMarked(); refSet1.Add(individual); } // STEP 3. Compute Euclidean distances in SolutionSet to obtain q // individuals, where q is refSet2Size_ for (int i = 0; i < solutionSet.Size(); i++) { individual = solutionSet.Get(i); individual.DistanceToSolutionSet = distance.DistanceToSolutionSetInSolutionSpace(individual, refSet1); } int size = refSet2Size; if (solutionSet.Size() < refSet2Size) { size = solutionSet.Size(); } // STEP 4. Build the RefSet2 with these q individuals for (int i = 0; i < size; i++) { // Find the maximumMinimunDistanceToPopulation double maxMinimum = 0.0; int index = 0; for (int j = 0; j < solutionSet.Size(); j++) { if (solutionSet.Get(j).DistanceToSolutionSet > maxMinimum) { maxMinimum = solutionSet.Get(j).DistanceToSolutionSet; index = j; } } individual = solutionSet.Get(index); solutionSet.Remove(index); // Update distances to REFSET in population for (int j = 0; j < solutionSet.Size(); j++) { double aux = distance.DistanceBetweenSolutions(solutionSet.Get(j), individual); if (aux < individual.DistanceToSolutionSet) { solutionSet.Get(j).DistanceToSolutionSet = aux; } } // Insert the individual into REFSET2 refSet2.Add(individual); // Update distances in REFSET2 for (int j = 0; j < refSet2.Size(); j++) { for (int k = 0; k < refSet2.Size(); k++) { if (i != j) { double aux = distance.DistanceBetweenSolutions(refSet2.Get(j), refSet2.Get(k)); if (aux < refSet2.Get(j).DistanceToSolutionSet) { refSet2.Get(j).DistanceToSolutionSet = aux; } } } } } } else { // Update the reference set from the subset generation result Solution individual; for (int i = 0; i < subSet.Size(); i++) { individual = (Solution)improvementOperator.Execute(subSet.Get(i)); evaluations += improvementOperator.GetEvaluations(); if (RefSet1Test(individual)) { //Update distance of RefSet2 for (int indSet2 = 0; indSet2 < refSet2.Size(); indSet2++) { double aux = distance.DistanceBetweenSolutions(individual, refSet2.Get(indSet2)); if (aux < refSet2.Get(indSet2).DistanceToSolutionSet) { refSet2.Get(indSet2).DistanceToSolutionSet = aux; } } } else { RefSet2Test(individual); } } subSet.Clear(); } }
/** * Runs of the GDE3 algorithm. * @return a <code>SolutionSet</code> that is a set of non dominated solutions * as a result of the algorithm execution * @throws JMException */ public override SolutionSet Execute() { int populationSize = -1; int maxIterations = -1; int evaluations; int iterations; SolutionSet population; SolutionSet offspringPopulation; Distance distance; IComparer <Solution> dominance; Operator selectionOperator; Operator crossoverOperator; distance = new Distance(); dominance = new DominanceComparator(); Solution[] parent; //Read the parameters JMetalCSharp.Utils.Utils.GetIntValueFromParameter(this.InputParameters, "populationSize", ref populationSize); JMetalCSharp.Utils.Utils.GetIntValueFromParameter(this.InputParameters, "maxIterations", ref maxIterations); selectionOperator = this.Operators["selection"]; crossoverOperator = this.Operators["crossover"]; //Initialize the variables population = new SolutionSet(populationSize); evaluations = 0; iterations = 0; // Create the initial solutionSet Solution newSolution; for (int i = 0; i < populationSize; i++) { newSolution = new Solution(this.Problem); this.Problem.Evaluate(newSolution); this.Problem.EvaluateConstraints(newSolution); evaluations++; population.Add(newSolution); } // Generations ... while (iterations < maxIterations) { // Create the offSpring solutionSet offspringPopulation = new SolutionSet(populationSize * 2); for (int i = 0; i < populationSize; i++) { // Obtain parents. Two parameters are required: the population and the // index of the current individual parent = (Solution[])selectionOperator.Execute(new object[] { population, i }); Solution child; // Crossover. Two parameters are required: the current individual and the // array of parents child = (Solution)crossoverOperator.Execute(new object[] { population.Get(i), parent }); this.Problem.Evaluate(child); this.Problem.EvaluateConstraints(child); evaluations++; // Dominance test int result; result = dominance.Compare(population.Get(i), child); if (result == -1) { // Solution i dominates child offspringPopulation.Add(population.Get(i)); } else if (result == 1) { // child dominates offspringPopulation.Add(child); } else { // the two solutions are non-dominated offspringPopulation.Add(child); offspringPopulation.Add(population.Get(i)); } } // Ranking the offspring population Ranking ranking = new Ranking(offspringPopulation); 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())) { //Assign crowding distance to individuals distance.CrowdingDistanceAssignment(front, this.Problem.NumberOfObjectives); //Add the individuals of this front for (int k = 0; k < front.Size(); k++) { population.Add(front.Get(k)); } // for //Decrement remain 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 contains individuals to insert while (front.Size() > remain) { distance.CrowdingDistanceAssignment(front, this.Problem.NumberOfObjectives); front.Remove(front.IndexWorst(new CrowdingComparator())); } for (int k = 0; k < front.Size(); k++) { population.Add(front.Get(k)); } remain = 0; } iterations++; } // Return the first non-dominated front Ranking rnk = new Ranking(population); this.Result = rnk.GetSubfront(0); return(this.Result); }
/// <summary> /// Gets 'size' elements from a population of more than 'size' elements /// using for this de enviromentalSelection truncation /// </summary> /// <param name="size">The number of elements to get.</param> /// <returns></returns> public SolutionSet EnvironmentalSelection(int size) { if (solutionSet.Size() < size) { size = solutionSet.Size(); } // Create a new auxiliar population for no alter the original population SolutionSet aux = new SolutionSet(solutionSet.Size()); int i = 0; while (i < solutionSet.Size()) { if (solutionSet.Get(i).Fitness < 1.0) { aux.Add(solutionSet.Get(i)); solutionSet.Remove(i); } else { i++; } } if (aux.Size() < size) { IComparer <Solution> comparator = new FitnessComparator(); solutionSet.Sort(comparator); int remain = size - aux.Size(); for (i = 0; i < remain; i++) { aux.Add(solutionSet.Get(i)); } return(aux); } else if (aux.Size() == size) { return(aux); } double[][] distanceMatrix = distance.DistanceMatrix(aux); List <List <DistanceNode> > distanceList = new List <List <DistanceNode> >(); for (int pos = 0; pos < aux.Size(); pos++) { aux.Get(pos).Location = pos; List <DistanceNode> distanceNodeList = new List <DistanceNode>(); for (int refe = 0; refe < aux.Size(); refe++) { if (pos != refe) { distanceNodeList.Add(new DistanceNode(distanceMatrix[pos][refe], refe)); } } distanceList.Add(distanceNodeList); } foreach (List <DistanceNode> aDistanceList in distanceList) { aDistanceList.Sort(distanceNodeComparator); } while (aux.Size() > size) { double minDistance = double.MaxValue; int toRemove = 0; i = 0; foreach (List <DistanceNode> dn in distanceList) { if (dn[0].Distance < minDistance) { toRemove = i; minDistance = dn[0].Distance; //i and toRemove have the same distance to the first solution } else if (dn[0].Distance == minDistance) { int k = 0; while ((dn[k].Distance == distanceList[toRemove][k].Distance) && k < (distanceList[i].Count - 1)) { k++; } if (dn[k].Distance < distanceList[toRemove][k].Distance) { toRemove = i; } } i++; } int tmp = aux.Get(toRemove).Location; aux.Remove(toRemove); distanceList.RemoveAt(toRemove); foreach (List <DistanceNode> aDistanceList in distanceList) { List <DistanceNode> interIterator = aDistanceList.ToList(); foreach (var element in interIterator) { if (element.Reference == tmp) { aDistanceList.Remove(element); } } } } return(aux); }