dignea  1.0.0
Diverse Instance Generator with Novelty Search and Evolutionary Algorithms
Comparator.h
Go to the documentation of this file.
1 
12 #ifndef __COMPARATOR_H__
13 #define __COMPARATOR_H__
14 
15 #include <dignea/core/Problem.h>
16 #include <dignea/core/Solution.h>
17 #include <dignea/utilities/exceptions/OutOfRange.h>
18 
19 #include <numeric>
20 #include <type_traits>
21 
22 static const int FIRST_BEST = -1;
23 static const int SECOND_BEST = 1;
24 static const int TIE = 0;
25 
26 static const int FIRST_DOMINATES = -1;
27 static const int SECOND_DOMINATES = 1;
28 static const int NON_DOMINANCES_EQUALS = 2;
29 static const int NON_DOMINANCES_NOT_EQUALS = 3;
30 
38 template <typename S>
39 int cmpByFitness(const S &ind1, const S &ind2) {
40  double fitness1 = ind1.getFitness();
41  double fitness2 = ind2.getFitness();
42  if (fitness1 > fitness2) {
43  return FIRST_BEST;
44  }
45  if (fitness1 < fitness2) {
46  return SECOND_BEST;
47  }
48  return TIE;
49 }
50 
62 template <typename S>
63 int cmpByObj(const S &ind1, const S &ind2, const int &nObj,
64  const Problem<S> *problem) {
65  if (ind1.getNumberOfObjs() < nObj || ind2.getNumberOfObjs() < nObj) {
66  std::string where =
67  "Comparator::cmpByObj() with obj = " + to_string(nObj);
68  throw(OutOfRange(where));
69  }
70  double obj1 = ind1.getObjAt(nObj);
71  double obj2 = ind2.getObjAt(nObj);
72  // Diferenciamos los casos de minimizacion y maximizacion de objetivos
73  if (problem->getOptimizationDirection(nObj) == Minimize) {
74  if (obj1 < obj2) {
75  return FIRST_BEST;
76  }
77  if (obj1 > obj2) {
78  return SECOND_BEST;
79  }
80  } else {
81  if (obj1 > obj2) {
82  return FIRST_BEST;
83  }
84  if (obj1 < obj2) {
85  return SECOND_BEST;
86  }
87  }
88  return TIE;
89 }
90 
104 template <typename S>
105 int improves(const S &ind1, const S &ind2) {
106  if (ind1.getNumberOfCons() != ind2.getNumberOfCons()) {
107  std::string where = "Comparator::improves() different constraints";
108  throw(OutOfRange(where));
109  }
110  vector ind1Const = ind1.getConstraints();
111  vector ind2Const = ind2.getConstraints();
112  float ind1Penalty =
113  std::accumulate(ind1Const.begin(), ind1Const.end(), 0.0f);
114  float ind2Penalty =
115  std::accumulate(ind2Const.begin(), ind2Const.end(), 0.0f);
116 
117  if (ind1Penalty < ind2Penalty) {
118  return FIRST_BEST;
119  } else if (ind2Penalty < ind1Penalty) {
120  return SECOND_BEST;
121  } else {
122  // Comprobamos el fitness
123  return cmpByFitness(ind1, ind2);
124  }
125 }
126 
139 template <typename S>
140 int dominanceTest(const S &ind1, const S &ind2, const Problem<S> *problem) {
141  if (ind1.getNumberOfObjs() < 2 || ind2.getNumberOfObjs() < 2) {
142  std::string where =
143  "Comparator::dominanceTest() with less than two objectices";
144  throw(std::runtime_error(where));
145  }
146  if (ind1.getNumberOfObjs() != ind2.getNumberOfObjs()) {
147  std::string where =
148  "Comparator::dominanceTest() with different number of objectives "
149  "each individual";
150  throw(std::runtime_error(where));
151  }
152  int flag;
153  auto dominate1{0};
154  auto dominate2{0};
155  for (int i = 0; i < ind1.getNumberOfObjs(); i++) {
156  if (problem->getOptimizationDirection(i) == Maximize) {
157  if (ind1.getObjAt(i) > ind2.getObjAt(i))
158  flag = -1;
159  else if (ind1.getObjAt(i) < ind2.getObjAt(i))
160  flag = 1;
161  else
162  flag = 0;
163  } else { // Objetivo a minimizar
164  if (ind1.getObjAt(i) < ind2.getObjAt(i))
165  flag = -1;
166  else if (ind1.getObjAt(i) > ind2.getObjAt(i))
167  flag = 1;
168  else
169  flag = 0;
170  }
171 
172  if (flag == -1) dominate1 = 1;
173  if (flag == 1) dominate2 = 1;
174  }
175 
176  if ((dominate1 == 0) && (dominate2 == 0)) { // iguales
177  return NON_DOMINANCES_EQUALS; // Non dominated solutions
178  }
179  if ((dominate1 == 1) && (dominate2 == 1)) { // no iguales
180  return NON_DOMINANCES_NOT_EQUALS;
181  }
182  if (dominate1 == 1) {
183  return FIRST_DOMINATES; // solution1 dominates
184  }
185  return SECOND_DOMINATES; // solution2 dominates
186 }
187 
197 template <typename T>
198 bool areEqual(const vector<T> &v1, const vector<T> &v2) {
199  const T tolerance = 0.01;
200  if (v1.size() != v2.size()) {
201  return false; // Vectors have different sizes, they cannot be equal
202  }
203 
204  for (std::size_t i = 0; i < v1.size(); ++i) {
205  if (std::abs(v1[i] - v2[i]) > tolerance) {
206  return false; // Difference between elements exceeds tolerance,
207  // vectors are not equal
208  }
209  }
210  return true; // All corresponding elements are within tolerance, vectors
211  // are considered equal
212 }
213 
223 template <typename T>
224 bool areEqual(const T &a, const T &b) {
225  const T tolerance = 0.0001f;
226 
227  return (std::abs(a - b) < tolerance * std::max(std::abs(a), std::abs(b)));
228 }
229 
230 #endif //__COMPARATOR_H__
int cmpByFitness(const S &ind1, const S &ind2)
Compares two individuals by their fitness.
Definition: Comparator.h:39
int improves(const S &ind1, const S &ind2)
Checks whether a solution is improved by a new one. A solution (with constraints) is said to improve ...
Definition: Comparator.h:105
bool areEqual(const vector< T > &v1, const vector< T > &v2)
Compare whether two vectors are equal within a tolerance.
Definition: Comparator.h:198
int dominanceTest(const S &ind1, const S &ind2, const Problem< S > *problem)
Test whether an individual dominates another. A individual dominates another if all their objectives ...
Definition: Comparator.h:140
int cmpByObj(const S &ind1, const S &ind2, const int &nObj, const Problem< S > *problem)
Compares two individuals by the objective nObj. The problem to solve must be given to check whether t...
Definition: Comparator.h:63
Class to represent a Problem in the tool. It includes the basic information for a problem a few metho...
Definition: Problem.h:29
virtual int getOptimizationDirection(const int i) const =0
Returns the optimization direction for each objective in the problem. It returns Minimize or Maximize...