1 /// \file IOHprofiler_problem.h
2 /// \brief Header file for the template class IOHprofiler_problem.
3 ///
4 /// A detailed file description.
5 ///
6 /// \author Furong Ye
7 #ifndef _IOHPROFILER_PROBLEM_H
8 #define _IOHPROFILER_PROBLEM_H
9 
10 #include "IOHprofiler_common.h"
11 #include "IOHprofiler_transformation.h"
12 
13 /// < transformation methods.
14 static IOHprofiler_transformation transformation;
15 
16 /// \brief A base class for defining problems.
17 ///
18 /// Basic structure for IOHExperimentor, which is used for generating benchmark problems.
19 /// To define a new problem, the 'internal_evaluate' method must be defined. The problem
20 /// sets as maximization by default. If the 'best_variables' are given, the optimal of
21 /// the problem will be calculated with the 'best_variables'; or you can set the optimal
22 /// by defining the 'customized_optimal' function; otherwise, the optimal is set as
23 /// min()(max()) for maximization(minimization). If additional calculation is needed by
24 /// 'internal_evaluate', you can configure it in 'prepare_problem()'.
25 template <class InputType> class IOHprofiler_problem
26 {
27 public:
28   IOHprofiler_problem(int instance_id = DEFAULT_INSTANCE, int dimension = DEFAULT_DIMENSION) :
problem_id(DEFAULT_PROBLEM_ID)29     problem_id(DEFAULT_PROBLEM_ID),
30     instance_id(instance_id),
31     maximization_minimization_flag(IOH_optimization_type::Maximization),
32     number_of_variables(DEFAULT_DIMENSION),
33     number_of_objectives(1),
34     lowerbound(std::vector<InputType> (number_of_variables) ),
35     upperbound(std::vector<InputType> (number_of_variables) ),
36     optimal(std::vector<double>(number_of_objectives) ),
37     optimalFound(false),
38     evaluations(0),
39     best_so_far_raw_objectives(std::vector<double>(number_of_objectives) ),
40     best_so_far_raw_evaluations(0),
41     best_so_far_transformed_objectives(std::vector<double>(number_of_objectives) ) {}
42 
~IOHprofiler_problem()43   virtual ~IOHprofiler_problem() {}
44 
45   IOHprofiler_problem(const IOHprofiler_problem&) = delete;
46   IOHprofiler_problem &operator=(const IOHprofiler_problem&) = delete;
47 
48   /// \todo to support multi-objective optimization
49   /// \fn virtual std::vector<double> internal_evaluate_multi(std::vector<InputType> x)
50   /// \brief A virtual internal evaluate function.
51   ///
52   /// The internal_evaluate function is to be used in evaluate function.
53   /// This function must be decalred in derived function of new problems.
54   // virtual std::vector<double> internal_evaluate_multi (const std::vector<InputType> &x) {
55   //   std::vector<double> result;
56   //   std::cout << "No multi evaluate function defined" << std::endl;
57   //   return result;
58   // };
59 
60   /// \fn double internal_evaluate(std::vector<InputType> x)
61   /// \brief A virtual internal evaluate function.
62   ///
63   /// The internal_evaluate function is to be used in evaluate function.
64   /// This function must be decalred in derived function of new problems.
internal_evaluate(const std::vector<InputType> & x)65   virtual double internal_evaluate(const std::vector<InputType> &x) {
66     double result = std::numeric_limits<double>::lowest();
67     IOH_warning("No evaluate function defined");
68     return result;
69   }
70 
prepare_problem()71   virtual void prepare_problem() {
72   }
73 
74   /// \todo to support multi-objective optimization
75   /// \fn std::vector<double> evevaluate_multialuate(std::vector<InputType> x)
76   /// \brife A common function for evaluating fitness of problems.
77   ///
78   /// Raw evaluate process, tranformation operations, and logging process are excuted
79   /// in this function.
80   /// \param x A InputType vector of variables.
81   /// \return A double vector of objectives.
82   // std::vector<double> evaluate_multi(std::vector<InputType> x) {
83   //   ++this->evaluations;
84 
85   //   transformation.variables_transformation(x,this->problem_id,this->instance_id,this->problem_type);
86   //   this->raw_objectives = internal_evaluate_multi(x);
87 
88   //   this->transformed_objectives = this->raw_objectives;
89   //   transformation.objectives_transformation(x,this->transformed_objectives,this->problem_id,this->instance_id,this->problem_type);
90   //   if (compareObjectives(this->transformed_objectives,this->best_so_far_transformed_objectives,this->maximization_minimization_flag)) {
91   //     this->best_so_far_transformed_objectives = this->transformed_objectives;
92   //     this->best_so_far_transformed_evaluations = this->evaluations;
93   //     this->best_so_far_raw_objectives = this->raw_objectives;
94   //     this->best_so_far_raw_evaluations = this->evaluations;
95 
96   //   }
97 
98   //   if (compareVector(this->transformed_objectives,this->optimal)) {
99   //     this->optimalFound = true;
100   //   }
101 
102   //   return this->transformed_objectives;
103   // }
104 
105   /// \fn double evaluate(std::vector<InputType> x)
106   /// \brife A common function for evaluating fitness of problems.
107   ///
108   /// Raw evaluate process, tranformation operations, and logging process are excuted
109   /// in this function.
110   /// \param x A InputType vector of variables.
111   /// \return A double vector of objectives.
112   double evaluate(std::vector<InputType> x);
113 
114   /// \fn virtual void customized_optimal()
115   ///
116   /// A virtual function to customize optimal of the problem.
customize_optimal()117   virtual void customize_optimal(){
118 
119   }
120 
121   /// \fn void calc_optimal()
122   ///
123   /// A function to calculate optimal of the problem.
124   /// It will be revoked after setting dimension (number_of_variables) or instance_id.
125   void calc_optimal();
126 
127   /// \todo  To support constrained optimization.
128   // virtual std::vector<double> constraints() {
129   //   std::vector<double> con;
130   //   printf("No constraints function defined\n");
131   //   return con;
132   // };
133 
134   /// \fn void reset_problem()
135   ///
136   /// \brief Reset problem as the default condition before doing evaluating.
137   void reset_problem();
138 
139   /// \fn std::vector<std::variant<int,double,std::string>> loggerInfo()
140   ///
141   /// Return a vector logger_info may be used by loggers.
142   /// logger_info[0] evaluations
143   /// logger_info[1] precision
144   /// logger_info[2] best_so_far_precision
145   /// logger_info[3] transformed_objective
146   /// logger_info[4] best_so_far_transformed_objectives
147   std::vector<double> loggerCOCOInfo() const;
148 
149   /// \fn std::vector<std::variant<int,double,std::string>> loggerInfo()
150   ///
151   /// Return a vector logger_info may be used by loggers.
152   /// logger_info[0] evaluations
153   /// logger_info[1] raw_objectives
154   /// logger_info[2] best_so_far_raw_objectives
155   /// logger_info[3] transformed_objective
156   /// logger_info[4] best_so_far_transformed_objectives
157   std::vector<double> loggerInfo() const;
158 
159   /// \fn IOHprofiler_hit_optimal()
160   ///
161   /// \brief Detect if the optimal have been found.
162   bool IOHprofiler_hit_optimal() const;
163 
164   int IOHprofiler_get_problem_id() const;
165 
166   void IOHprofiler_set_problem_id(int problem_id);
167 
168   int IOHprofiler_get_instance_id() const;
169 
170   /// \fn IOHprofiler_set_instance_id(int instance_id)
171   ///
172   /// To set instance_id of the problem. Since the optimal will be updated
173   /// as instanced_id updated, calc_optimal() is revoked here.
174   /// \param instance_id
175   void IOHprofiler_set_instance_id(int instance_id);
176 
177   std::string IOHprofiler_get_problem_name() const;
178 
179   void IOHprofiler_set_problem_name(std::string problem_name);
180 
181   std::string IOHprofiler_get_problem_type() const;
182 
183   void IOHprofiler_set_problem_type(std::string problem_type);
184 
185   std::vector<InputType> IOHprofiler_get_lowerbound() const;
186 
187   void IOHprofiler_set_lowerbound(int lowerbound);
188 
189   void IOHprofiler_set_lowerbound(const std::vector<InputType> &lowerbound);
190 
191   std::vector<InputType> IOHprofiler_get_upperbound() const;
192 
193   void IOHprofiler_set_upperbound(int upperbound);
194 
195   void IOHprofiler_set_upperbound(const std::vector<InputType> &upperbound);
196 
197   int IOHprofiler_get_number_of_variables() const;
198 
199   /// \fn IOHprofiler_set_number_of_variables(int number_of_variables)
200   ///
201   /// To set number_of_variables of the problem. When the number_of_variables is updated,
202   /// best_variables, lowerbound, upperbound, and optimal need to be updated as well.
203   ///
204   /// \param number_of_variables
205   void IOHprofiler_set_number_of_variables(const int number_of_variables);
206 
207   /// \fn IOHprofiler_set_number_of_variables(int number_of_variables)
208   ///
209   /// To set number_of_variables of the problem. When the number_of_variables is updated,
210   /// best_variables, lowerbound, upperbound, and optimal need to be updated as well. In case
211   /// the best value for each bit is not staic, another input 'best_variables' is supplied.
212   ///
213   /// \param number_of_variables, best_variables
214   void IOHprofiler_set_number_of_variables(const int number_of_variables, const std::vector<InputType> &best_variables);
215 
216   int IOHprofiler_get_number_of_objectives() const;
217 
218   void IOHprofiler_set_number_of_objectives(const int number_of_objectives);
219 
220   std::vector<double> IOHprofiler_get_raw_objectives() const;
221 
222   std::vector<double> IOHprofiler_get_transformed_objectives() const;
223 
224   int IOHprofiler_get_transformed_number_of_variables() const;
225 
226   std::vector<InputType> IOHprofiler_get_transformed_variables() const;
227 
228   std::vector<InputType> IOHprofiler_get_best_variables() const;
229 
230   void IOHprofiler_set_best_variables(const InputType best_variables);
231 
232   void IOHprofiler_set_best_variables(const std::vector<InputType> &best_variables);
233 
234   std::vector<double> IOHprofiler_get_optimal() const;
235 
236   void IOHprofiler_set_optimal(const double optimal);
237 
238   void IOHprofiler_set_optimal(const std::vector<double> &optimal);
239 
240   void IOHprofiler_evaluate_optimal(std::vector<InputType> best_variables);
241 
242   void IOHprofiler_evaluate_optimal();
243 
244   int IOHprofiler_get_evaluations() const;
245 
246   std::vector<double> IOHprofiler_get_best_so_far_raw_objectives() const;
247 
248   int IOHprofiler_get_best_so_far_raw_evaluations() const;
249 
250   std::vector<double> IOHprofiler_get_best_so_far_transformed_objectives() const;
251 
252   int IOHprofiler_get_best_so_far_transformed_evaluations() const;
253 
254   IOH_optimization_type IOHprofiler_get_optimization_type() const;
255 
256   void IOHprofiler_set_as_maximization();
257 
258   void IOHprofiler_set_as_minimization();
259 
260 private:
261   int problem_id; /// < problem id, assigned as being added into a suite.
262   int instance_id; /// < evaluate function is validated with instance and dimension. set default to avoid invalid class.
263 
264   std::string problem_name;
265   std::string problem_type;   /// todo. make it as enum.
266 
267   IOH_optimization_type maximization_minimization_flag;
268 
269   std::size_t number_of_variables; /// < evaluate function is validated with instance and dimension. set default to avoid invalid class.
270   std::size_t number_of_objectives;
271 
272   std::vector<InputType> lowerbound;
273   std::vector<InputType> upperbound;
274 
275   std::vector<InputType> best_variables; /// todo. comments, rename?
276   std::vector<InputType> best_transformed_variables;
277   std::vector<double> optimal; /// todo. How to evluate distance to optima. In global optima case, which optimum to be recorded.
278   bool optimalFound;
279 
280   std::vector<double> raw_objectives; /// < to record objectives before transformation.
281   std::vector<double> transformed_objectives; /// < to record objectives after transformation.
282   int transformed_number_of_variables; /// < intermediate variables in evaluate.
283   std::vector<InputType> transformed_variables; /// < intermediate variables in evaluate.
284 
285   /// todo. constrainted optimization.
286   /// std::size_t number_of_constraints;
287 
288   std::size_t evaluations; /// < to record optimization process.
289   std::vector<double> best_so_far_raw_objectives; /// < to record optimization process.
290   int best_so_far_raw_evaluations; /// < to record optimization process.
291   std::vector<double> best_so_far_transformed_objectives; /// < to record optimization process.
292   int best_so_far_transformed_evaluations; /// < to record optimization process.
293 };
294 
295 #include "IOHprofiler_problem.hpp"
296 
297 #endif // _IOHPROFILER_PROBLEM_H
298