GHOST
Loading...
Searching...
No Matches
objective.hpp
Go to the documentation of this file.
1/*
2 * GHOST (General meta-Heuristic Optimization Solving Tool) is a C++ framework
3 * designed to help developers to model and implement optimization problem
4 * solving. It contains a meta-heuristic solver aiming to solve any kind of
5 * combinatorial and optimization real-time problems represented by a CSP/COP/EF-CSP/EF-COP.
6 *
7 * First developed to solve game-related optimization problems, GHOST can be used for
8 * any kind of applications where solving combinatorial and optimization problems. In
9 * particular, it had been designed to be able to solve not-too-complex problem instances
10 * within some milliseconds, making it very suitable for highly reactive or embedded systems.
11 * Please visit https://github.com/richoux/GHOST for further information.
12 *
13 * Copyright (C) 2014-2025 Florian Richoux
14 *
15 * This file is part of GHOST.
16 * GHOST is free software: you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as published
18 * by the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
20
21 * GHOST is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25
26 * You should have received a copy of the GNU General Public License
27 * along with GHOST. If not, see http://www.gnu.org/licenses/.
28 */
29
30
31#pragma once
32
33#include <algorithm>
34#include <limits>
35#include <vector>
36#include <map>
37#include <cmath> // for isnan
38#include <exception>
39
40#include "variable.hpp"
41#include "thirdparty/randutils.hpp"
42
43namespace ghost
44{
45 namespace algorithms
46 {
47 class AdaptiveSearchValueHeuristic;
48 class AntidoteSearchValueHeuristic;
49 }
50
62 {
63 template<typename ModelBuilderType> friend class Solver;
64 friend class SearchUnit;
65 friend class ModelBuilder;
66
67 friend class NullObjective;
68 friend class Minimize;
69 friend class Maximize;
70
71 friend class algorithms::AdaptiveSearchValueHeuristic;
72 friend class algorithms::AntidoteSearchValueHeuristic;
73
74 std::vector<Variable*> _variables; // Vector of raw pointers to variables needed to compute the objective function.
75 std::vector<int> _variables_index; // To know where are the constraint's variables in the global variable vector.
76 std::map<int,int> _variables_position; // To know where are global variables in the constraint's variables vector.
77 bool _is_optimization;
78 bool _is_maximization;
79 std::string _name; // Name of the objective object.
80
81 struct nanException : std::exception
82 {
83 std::vector<Variable*> variables;
84 std::string message;
85
86 nanException( const std::vector<Variable*>& variables ) : variables(variables)
87 {
88 message = "Objective required_cost returned a NaN value on variables (";
89 for( int i = 0; i < static_cast<int>( variables.size() ) - 1; ++i )
90 message += std::to_string( variables[i]->get_value() ) + ", ";
91 message += std::to_string( variables[ static_cast<int>( variables.size() ) - 1 ]->get_value() ) + ")\n";
92 }
93 const char* what() const noexcept { return message.c_str(); }
94 };
95
96 struct variableOutOfTheScope : std::exception
97 {
98 std::string message;
99
100 variableOutOfTheScope( int var_id, std::string name )
101 {
102 message = "Variable ID " + std::to_string( var_id ) + " is not in the scope of the Objective function " + name + ".\n";
103 }
104 const char* what() const noexcept { return message.c_str(); }
105 };
106
107 Objective( const std::vector<int>& variables_index, bool is_maximization, const std::string& name );
108 Objective( const std::vector<Variable>& variables, bool is_maximization, const std::string& name );
109
110 inline void update( int index, int new_value ) { conditional_update_data_structures( _variables, _variables_position[ index ], new_value ); }
111
112 // Call required_cost() on Objective::_variables after making sure the cost does not give a nan, rise an exception otherwise.
113 double cost() const;
114
115 // Call expert_heuristic_value on Objective::_variables.
116 inline int heuristic_value( int variable_index, const std::vector<int>& possible_values, randutils::mt19937_rng& rng ) const
117 { return expert_heuristic_value( _variables, _variables_position.at( variable_index ), possible_values, rng ); }
118
119 // Call expert_heuristic_value_permutation on Objective::_variables.
120 inline int heuristic_value_permutation( int variable_index, const std::vector<int>& bad_variables, randutils::mt19937_rng& rng ) const
121 { return expert_heuristic_value_permutation( _variables, _variables_position.at( variable_index ), bad_variables, rng ); }
122
123 // Call expert_postprocess on Objective::_variables.
124 inline double postprocess( double best_cost ) const
125 { return expert_postprocess( _variables, best_cost ); }
126
127 protected:
145 virtual double required_cost( const std::vector<Variable*>& variables ) const = 0;
146
162 virtual void conditional_update_data_structures( const std::vector<Variable*>& variables, int index, int new_value );
163
189 virtual int expert_heuristic_value( const std::vector<Variable*>& variables,
190 int variable_index,
191 const std::vector<int>& possible_values,
192 randutils::mt19937_rng& rng ) const;
193
214 virtual int expert_heuristic_value_permutation( const std::vector<Variable*>& variables,
215 int variable_index,
216 const std::vector<int>& bad_variables,
217 randutils::mt19937_rng& rng ) const;
218
244 virtual double expert_postprocess( const std::vector<Variable*>& variables,
245 double best_cost ) const;
246
247
248 // No documentation on purpose.
249 inline void is_not_optimization() { _is_optimization = false; }
250
251 public:
253 Objective( const Objective& other ) = default;
255 Objective( Objective&& other ) = default;
256
258 Objective& operator=( const Objective& other ) = delete;
260 Objective& operator=( Objective&& other ) = delete;
261
263 virtual ~Objective() = default;
264
266 inline std::string get_name() const { return _name; }
267
269 inline bool is_optimization() const { return _is_optimization; }
270
275 inline bool is_maximization() const { return _is_maximization; }
276
278 friend std::ostream& operator<<( std::ostream& os, const Objective& o )
279 {
280 return os << "Objective name: " << o._name
281 << "\n********";
282 }
283 };
284
285 /*******************/
287 /*******************/
288 // NullObjective is used when no objective functions have been given to the solver (ie, for pure satisfaction runs).
289 class NullObjective : public Objective
290 {
291 public:
292 NullObjective() : Objective( std::vector<int>{0}, false, "nullObjective" )
293 {
294 this->is_not_optimization();
295 }
296
297 private:
298 double required_cost( const std::vector<Variable*>& variables ) const override { return 0.0; }
299 };
300
301 /**************/
303 /**************/
313 class Minimize : public Objective
314 {
315 public:
323 Minimize( const std::vector<int>& variables_index )
324 : Objective( variables_index, false, std::string( "Minimize" ) )
325 { }
326
333 Minimize( const std::vector<Variable>& variables )
334 : Objective( variables, false, std::string( "Minimize" ) )
335 { }
336
344 Minimize( const std::vector<int>& variables_index, const std::string& name )
345 : Objective( variables_index, false, name )
346 { }
347
354 Minimize( const std::vector<Variable>& variables, const std::string& name )
355 : Objective( variables, false, name )
356 { }
357
365 Minimize( const std::vector<int>& variables_index, const char* name )
366 : Objective( variables_index, false, std::string( name ) )
367 { }
368
375 Minimize( const std::vector<Variable>& variables, const char* name )
376 : Objective( variables, false, std::string( name ) )
377 { }
378 };
379
380 /**************/
382 /**************/
392 class Maximize : public Objective
393 {
394 public:
402 Maximize( const std::vector<int>& variables_index )
403 : Objective( variables_index, true, std::string( "Maximize" ) )
404 { }
405
412 Maximize( const std::vector<Variable>& variables )
413 : Objective( variables, true, std::string( "Maximize" ) )
414 { }
415
423 Maximize( const std::vector<int>& variables_index, const std::string& name )
424 : Objective( variables_index, true, name )
425 { }
426
433 Maximize( const std::vector<Variable>& variables, const std::string& name )
434 : Objective( variables, true, name )
435 { }
436
444 Maximize( const std::vector<int>& variables_index, const char* name )
445 : Objective( variables_index, true, std::string( name ) )
446 { }
447
454 Maximize( const std::vector<Variable>& variables, const char* name )
455 : Objective( variables, true, std::string( name ) )
456 { }
457 };
458}
Definition objective.hpp:393
Maximize(const std::vector< Variable > &variables, const std::string &name)
Definition objective.hpp:433
Maximize(const std::vector< int > &variables_index, const char *name)
Definition objective.hpp:444
Maximize(const std::vector< int > &variables_index, const std::string &name)
Definition objective.hpp:423
Maximize(const std::vector< Variable > &variables)
Definition objective.hpp:412
Maximize(const std::vector< int > &variables_index)
Definition objective.hpp:402
Maximize(const std::vector< Variable > &variables, const char *name)
Definition objective.hpp:454
Definition objective.hpp:314
Minimize(const std::vector< Variable > &variables, const char *name)
Definition objective.hpp:375
Minimize(const std::vector< int > &variables_index, const char *name)
Definition objective.hpp:365
Minimize(const std::vector< int > &variables_index, const std::string &name)
Definition objective.hpp:344
Minimize(const std::vector< Variable > &variables, const std::string &name)
Definition objective.hpp:354
Minimize(const std::vector< Variable > &variables)
Definition objective.hpp:333
Minimize(const std::vector< int > &variables_index)
Definition objective.hpp:323
Definition model_builder.hpp:63
Definition objective.hpp:62
Objective & operator=(Objective &&other)=delete
Move assignment operator disabled.
friend class SearchUnit
Definition objective.hpp:64
virtual void conditional_update_data_structures(const std::vector< Variable * > &variables, int index, int new_value)
virtual int expert_heuristic_value_permutation(const std::vector< Variable * > &variables, int variable_index, const std::vector< int > &bad_variables, randutils::mt19937_rng &rng) const
std::string get_name() const
Inline accessor to get the name of the objective object.
Definition objective.hpp:266
virtual double expert_postprocess(const std::vector< Variable * > &variables, double best_cost) const
Objective(const Objective &other)=default
Default copy contructor.
virtual double required_cost(const std::vector< Variable * > &variables) const =0
virtual int expert_heuristic_value(const std::vector< Variable * > &variables, int variable_index, const std::vector< int > &possible_values, randutils::mt19937_rng &rng) const
virtual ~Objective()=default
Default virtual destructor.
Objective & operator=(const Objective &other)=delete
Copy assignment operator disabled.
void is_not_optimization()
Definition objective.hpp:249
friend std::ostream & operator<<(std::ostream &os, const Objective &o)
To have a nicer stream of Objective.
Definition objective.hpp:278
bool is_optimization() const
Inline method returning if a user-defined objective function has been declared.
Definition objective.hpp:269
Objective(Objective &&other)=default
Default move contructor.
bool is_maximization() const
Definition objective.hpp:275
Definition solver.hpp:119
Definition auxiliary_data.hpp:38