├── doc ├── images │ ├── architecture.png │ ├── graph_color.png │ ├── graph_cover.png │ └── graph_template.png └── mainpage.md ├── lib └── .gitignore ├── tests ├── bin │ └── .gitignore └── CMakeLists.txt ├── tutorial ├── video │ ├── bin │ │ └── .gitignore │ ├── src │ │ ├── knapsack_alldiff.hpp │ │ ├── knapsack_model_builder.hpp │ │ ├── knapsack_objective.hpp │ │ ├── knapsack_capacity.hpp │ │ ├── knapsack_objective.cpp │ │ ├── knapsack_alldiff.cpp │ │ ├── knapsack.cpp │ │ ├── knapsack_model_builder.cpp │ │ └── knapsack_capacity.cpp │ └── CMakeLists.txt └── wiki │ ├── bin │ └── .gitignore │ ├── src │ ├── model_builder_sat.hpp │ ├── model_builder_opti.hpp │ ├── constraint_capacity_ef.cpp │ ├── constraint_at_least_ef.cpp │ ├── constraint_capacity.cpp │ ├── constraint_at_least.cpp │ ├── objective_max_value.hpp │ ├── objective_max_value.cpp │ ├── model_builder_sat.cpp │ ├── constraint_capacity.hpp │ ├── constraint_at_least.hpp │ ├── model_builder_opti.cpp │ └── main.cpp │ └── CMakeLists.txt ├── .gitignore ├── license_text ├── include ├── macros.hpp ├── algorithms │ ├── uniform_variable_heuristic.hpp │ ├── all_free_variable_candidates_heuristic.hpp │ ├── antidote_search_variable_heuristic.hpp │ ├── adaptive_search_variable_candidates_heuristic.hpp │ ├── antidote_search_variable_candidates_heuristic.hpp │ ├── random_walk_value_heuristic.hpp │ ├── adaptive_search_value_heuristic.hpp │ ├── antidote_search_value_heuristic.hpp │ ├── null_error_projection_algorithm.hpp │ ├── adaptive_search_error_projection_algorithm.hpp │ ├── culprit_search_error_projection_algorithm.hpp │ ├── variable_candidates_heuristic.hpp │ ├── variable_heuristic.hpp │ ├── error_projection_algorithm.hpp │ └── value_heuristic.hpp ├── print.hpp ├── model.hpp ├── global_constraints │ ├── all_equal.hpp │ ├── all_different.hpp │ ├── fix_value.hpp │ ├── linear_equation.hpp │ ├── linear_equation_g.hpp │ ├── linear_equation_l.hpp │ ├── linear_equation_eq.hpp │ ├── linear_equation_neq.hpp │ ├── linear_equation_leq.hpp │ └── linear_equation_geq.hpp ├── options.hpp └── search_unit_data.hpp ├── src ├── algorithms │ ├── uniform_variable_heuristic.cpp │ ├── antidote_search_variable_heuristic.cpp │ ├── all_free_variable_candidates_heuristic.cpp │ ├── antidote_search_variable_candidates_heuristic.cpp │ ├── null_error_projection_algorithm.cpp │ ├── random_walk_value_heuristic.cpp │ ├── adaptive_search_variable_candidates_heuristic.cpp │ ├── adaptive_search_error_projection_algorithm.cpp │ ├── adaptive_search_value_heuristic.cpp │ └── antidote_search_value_heuristic.cpp ├── model.cpp ├── auxiliary_data.cpp ├── global_constraints │ ├── linear_equation_eq.cpp │ ├── linear_equation_geq.cpp │ ├── linear_equation_leq.cpp │ ├── linear_equation_g.cpp │ ├── linear_equation_l.cpp │ ├── linear_equation_neq.cpp │ ├── fix_value.cpp │ ├── linear_equation.cpp │ ├── all_equal.cpp │ └── all_different.cpp ├── print.cpp ├── objective.cpp ├── options.cpp ├── model_builder.cpp └── variable.cpp ├── README.md ├── .github └── workflows │ ├── linux.yml │ ├── windows.yml │ └── macos.yml └── ChangeLog.md /doc/images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richoux/GHOST/HEAD/doc/images/architecture.png -------------------------------------------------------------------------------- /doc/images/graph_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richoux/GHOST/HEAD/doc/images/graph_color.png -------------------------------------------------------------------------------- /doc/images/graph_cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richoux/GHOST/HEAD/doc/images/graph_cover.png -------------------------------------------------------------------------------- /lib/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /doc/images/graph_template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/richoux/GHOST/HEAD/doc/images/graph_template.png -------------------------------------------------------------------------------- /tests/bin/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /tutorial/video/bin/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /tutorial/wiki/bin/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /tutorial/wiki/src/model_builder_sat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class TutorialBuilder : public ghost::ModelBuilder 8 | { 9 | public: 10 | TutorialBuilder(); 11 | 12 | void declare_variables() override; 13 | void declare_constraints() override; 14 | }; 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Tiled source files 2 | ./include/*~ 3 | ./src/*~ 4 | test/src/*~ 5 | 6 | # Doxygen files 7 | doc/html 8 | doc/latex 9 | doc/.zcache 10 | 11 | # CMake builds 12 | build32 13 | build64 14 | build/* 15 | 16 | # CMake test builds 17 | tests/build* 18 | 19 | # tutorial obj and bin 20 | tutorial/wiki/build/* 21 | tutorial/video/build/* 22 | -------------------------------------------------------------------------------- /tutorial/video/src/knapsack_alldiff.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class KSAllDiff : public ghost::Constraint 7 | { 8 | 9 | public: 10 | KSAllDiff( const std::vector& variables ); 11 | 12 | double required_error( const std::vector& variables ) const override; 13 | }; 14 | -------------------------------------------------------------------------------- /tutorial/video/src/knapsack_model_builder.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class KSBuilder : public ghost::ModelBuilder 8 | { 9 | public: 10 | KSBuilder(); 11 | 12 | void declare_variables() override; 13 | void declare_constraints() override; 14 | void declare_objective() override; 15 | }; 16 | -------------------------------------------------------------------------------- /tutorial/wiki/src/model_builder_opti.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class TutorialBuilder : public ghost::ModelBuilder 8 | { 9 | public: 10 | TutorialBuilder(); 11 | 12 | void declare_variables() override; 13 | void declare_constraints() override; 14 | void declare_objective() override; 15 | }; 16 | -------------------------------------------------------------------------------- /tutorial/wiki/src/constraint_capacity_ef.cpp: -------------------------------------------------------------------------------- 1 | #include "constraint_capacity.hpp" 2 | 3 | double Capacity::required_error( const std::vector& variables ) const 4 | { 5 | double total_size = 0.0; 6 | 7 | for( size_t i = 0 ; i < variables.size() ; ++i ) 8 | total_size += ( variables[i]->get_value() * _object_size[i] ); 9 | 10 | return std::max( 0., total_size - _capacity ); 11 | } 12 | -------------------------------------------------------------------------------- /tutorial/wiki/src/constraint_at_least_ef.cpp: -------------------------------------------------------------------------------- 1 | #include "constraint_at_least.hpp" 2 | 3 | double AtLeast::required_error( const std::vector& variables ) const 4 | { 5 | double total_value = 0.0; 6 | 7 | for( size_t i = 0 ; i < variables.size() ; ++i ) 8 | total_value += ( variables[i]->get_value() * _object_value[i] ); 9 | 10 | return std::max( 0., _target_value - total_value ); 11 | } 12 | -------------------------------------------------------------------------------- /tutorial/wiki/src/constraint_capacity.cpp: -------------------------------------------------------------------------------- 1 | #include "constraint_capacity.hpp" 2 | 3 | double Capacity::required_error( const std::vector& variables ) const 4 | { 5 | double total_size = 0.0; 6 | 7 | for( size_t i = 0 ; i < variables.size() ; ++i ) 8 | total_size += ( variables[i]->get_value() * _object_size[i] ); 9 | 10 | if( total_size <= _capacity ) 11 | return 0.0; 12 | else 13 | return 1.0; 14 | } 15 | -------------------------------------------------------------------------------- /tutorial/wiki/src/constraint_at_least.cpp: -------------------------------------------------------------------------------- 1 | #include "constraint_at_least.hpp" 2 | 3 | double AtLeast::required_error( const std::vector& variables ) const 4 | { 5 | double total_value = 0.0; 6 | 7 | for( size_t i = 0 ; i < variables.size() ; ++i ) 8 | total_value += ( variables[i]->get_value() * _object_value[i] ); 9 | 10 | if( total_value >= _target_value ) 11 | return 0.0; 12 | else 13 | return 1.0; 14 | } 15 | -------------------------------------------------------------------------------- /tutorial/video/src/knapsack_objective.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class KSObjective : public ghost::Maximize 8 | { 9 | std::vector _values; 10 | 11 | public: 12 | KSObjective( const std::vector& variables, const std::vector&& values ); 13 | 14 | double required_cost( const std::vector& variables ) const override; 15 | }; 16 | -------------------------------------------------------------------------------- /tutorial/video/src/knapsack_capacity.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class KSCapacity : public ghost::Constraint 8 | { 9 | int _capacity; 10 | std::vector _weights; 11 | 12 | public: 13 | KSCapacity( const std::vector& variables, int capacity, const std::vector&& weights ); 14 | 15 | double required_error( const std::vector& variables ) const override; 16 | }; 17 | -------------------------------------------------------------------------------- /tutorial/wiki/src/objective_max_value.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | class MaxValue : public ghost::Maximize 10 | { 11 | std::vector _object_value; 12 | 13 | double required_cost( const std::vector& ) const override; 14 | 15 | public: 16 | MaxValue( const std::vector&, const std::vector&& object_value ); 17 | }; 18 | -------------------------------------------------------------------------------- /tutorial/video/src/knapsack_objective.cpp: -------------------------------------------------------------------------------- 1 | #include "knapsack_objective.hpp" 2 | 3 | KSObjective::KSObjective( const std::vector& variables, const std::vector&& values ) 4 | : Maximize( variables, "Max profit" ), 5 | _values( std::move( values ) ) 6 | { } 7 | 8 | double KSObjective::required_cost( const std::vector& variables ) const 9 | { 10 | double total_value = 0.0; 11 | 12 | for( size_t i = 0 ; i < variables.size() ; ++i ) 13 | total_value += variables[i]->get_value() * _values[i]; 14 | 15 | return total_value; 16 | } 17 | -------------------------------------------------------------------------------- /tutorial/video/src/knapsack_alldiff.cpp: -------------------------------------------------------------------------------- 1 | #include "knapsack_alldiff.hpp" 2 | 3 | KSAllDiff::KSAllDiff( const std::vector& variables ) 4 | : Constraint( variables ) 5 | { } 6 | 7 | double KSAllDiff::required_error( const std::vector& variables ) const 8 | { 9 | // EFOP version 10 | 11 | double count = 0.0; 12 | 13 | for( size_t i = 0 ; i < variables.size() - 1 ; ++i ) 14 | for( size_t j = i + 1 ; j < variables.size() ; ++j ) 15 | if( variables[i]->get_value() == variables[j]->get_value() ) 16 | ++count; 17 | 18 | return count; 19 | } 20 | -------------------------------------------------------------------------------- /tutorial/video/src/knapsack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "knapsack_model_builder.hpp" 9 | 10 | using namespace std::literals::chrono_literals; 11 | 12 | int main( int argc, char** argv ) 13 | { 14 | KSBuilder builder; 15 | 16 | ghost::Solver solver( builder ); 17 | 18 | double cost; 19 | std::vector solution; 20 | 21 | ghost::Options options; 22 | options.parallel_runs = true; 23 | 24 | solver.fast_search( cost, solution, 100ms, options ); 25 | } 26 | -------------------------------------------------------------------------------- /tutorial/wiki/src/objective_max_value.cpp: -------------------------------------------------------------------------------- 1 | #include "objective_max_value.hpp" 2 | 3 | MaxValue::MaxValue( const std::vector& variables, 4 | const std::vector&& object_value ) 5 | : Maximize( variables, "Max value" ), 6 | _object_value( std::move( object_value ) ) 7 | { } 8 | 9 | double MaxValue::required_cost( const std::vector& variables ) const 10 | { 11 | double total_value = 0.0; 12 | 13 | for( size_t i = 0 ; i < variables.size() ; ++i ) 14 | total_value += ( variables[i]->get_value() * _object_value[i] ); 15 | 16 | return total_value; 17 | } 18 | -------------------------------------------------------------------------------- /tutorial/wiki/src/model_builder_sat.cpp: -------------------------------------------------------------------------------- 1 | #include "model_builder_sat.hpp" 2 | #include "constraint_capacity.hpp" 3 | #include "constraint_at_least.hpp" 4 | 5 | TutorialBuilder::TutorialBuilder() 6 | : ModelBuilder() 7 | { } 8 | 9 | void TutorialBuilder::declare_variables() 10 | { 11 | variables.emplace_back( 0, 51, std::string("bottle") ); 12 | variables.emplace_back( 0, 11, std::string("sandwich") ); 13 | } 14 | 15 | void TutorialBuilder::declare_constraints() 16 | { 17 | constraints.emplace_back( std::make_shared( variables, std::vector{1, 1.25}, 30 ) ); 18 | constraints.emplace_back( std::make_shared( variables, std::vector{500, 650}, 15000 ) ); 19 | } 20 | -------------------------------------------------------------------------------- /tutorial/wiki/src/constraint_capacity.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | class Capacity : public ghost::Constraint 11 | { 12 | std::vector _object_size; 13 | int _capacity; 14 | 15 | double required_error( const std::vector& variables ) const override; 16 | 17 | public: 18 | Capacity( const std::vector& variables, 19 | const std::vector&& object_size, 20 | int capacity ) 21 | : Constraint( variables ), 22 | _object_size( std::move( object_size ) ), 23 | _capacity( capacity ) 24 | { } 25 | }; 26 | -------------------------------------------------------------------------------- /tutorial/wiki/src/constraint_at_least.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | class AtLeast : public ghost::Constraint 11 | { 12 | std::vector _object_value; 13 | double _target_value; 14 | 15 | double required_error( const std::vector& variables ) const override; 16 | 17 | public: 18 | AtLeast( const std::vector& variables, 19 | const std::vector&& object_value, 20 | double target_value ) 21 | : Constraint( variables ), 22 | _object_value( std::move( object_value ) ), 23 | _target_value( target_value ) 24 | { } 25 | }; 26 | -------------------------------------------------------------------------------- /tutorial/wiki/src/model_builder_opti.cpp: -------------------------------------------------------------------------------- 1 | #include "model_builder_opti.hpp" 2 | #include "constraint_capacity.hpp" 3 | #include "objective_max_value.hpp" 4 | 5 | TutorialBuilder::TutorialBuilder() 6 | : ModelBuilder() 7 | { } 8 | 9 | void TutorialBuilder::declare_variables() 10 | { 11 | variables.emplace_back( 0, 51, std::string("bottle") ); 12 | variables.emplace_back( 0, 11, std::string("sandwich") ); 13 | } 14 | 15 | void TutorialBuilder::declare_constraints() 16 | { 17 | constraints.emplace_back( std::make_shared( variables, std::vector{1, 1.25}, 30 ) ); 18 | } 19 | 20 | void TutorialBuilder::declare_objective() 21 | { 22 | objective = std::make_shared( variables, std::vector{500, 650} ); 23 | } 24 | -------------------------------------------------------------------------------- /tutorial/video/src/knapsack_model_builder.cpp: -------------------------------------------------------------------------------- 1 | #include "knapsack_model_builder.hpp" 2 | #include "knapsack_capacity.hpp" 3 | #include "knapsack_alldiff.hpp" 4 | #include "knapsack_objective.hpp" 5 | 6 | KSBuilder::KSBuilder() 7 | : ModelBuilder() 8 | { } 9 | 10 | void KSBuilder::declare_variables() 11 | { 12 | create_n_variables( 5, 0, 16 ); 13 | } 14 | 15 | void KSBuilder::declare_constraints() 16 | { 17 | constraints.emplace_back( std::make_shared( variables, 15, std::vector{12,2,1,1,4} ) ); 18 | constraints.emplace_back( std::make_shared( variables ) ); 19 | } 20 | 21 | void KSBuilder::declare_objective() 22 | { 23 | objective = std::make_shared( variables, std::vector{4,2,2,1,10} ); 24 | } 25 | -------------------------------------------------------------------------------- /tutorial/video/src/knapsack_capacity.cpp: -------------------------------------------------------------------------------- 1 | #include "knapsack_capacity.hpp" 2 | 3 | KSCapacity::KSCapacity( const std::vector& variables, int capacity, const std::vector&& weights ) 4 | : Constraint( variables ), 5 | _capacity( capacity ), 6 | _weights( std::move( weights ) ) 7 | { } 8 | 9 | double KSCapacity::required_error( const std::vector& variables ) const 10 | { 11 | // Stuff in common 12 | 13 | double total_weight = 0.0; 14 | for( size_t i = 0 ; i < variables.size() ; ++i ) 15 | total_weight += variables[i]->get_value() * _weights[i]; 16 | 17 | /* 18 | // COP version here 19 | 20 | return total_weight <= _capacity ? 0.0 : 1.0; 21 | 22 | /*/ 23 | // EFOP version here 24 | 25 | return std::max( 0., total_weight - _capacity ); 26 | //*/ 27 | } 28 | -------------------------------------------------------------------------------- /tutorial/wiki/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #if defined OPTIMIZATION 10 | #include "model_builder_opti.hpp" 11 | #else 12 | #include "model_builder_sat.hpp" 13 | #endif 14 | 15 | using namespace std::literals::chrono_literals; 16 | 17 | int main() 18 | { 19 | // Declaring the model builder 20 | TutorialBuilder builder; 21 | 22 | // Defining the solver and calling it 23 | ghost::Solver solver( builder ); 24 | 25 | double cost; 26 | std::vector solution; 27 | 28 | // Run the solver with a 500 microseconds budget 29 | bool found = solver.fast_search( cost, solution, 500us ); 30 | 31 | // After 500 microseconds, the solver will write in cost and solution the best solution it has found. 32 | found ? std::cout << "Solution found\n" : std::cout << "Solution not found\n"; 33 | std::cout << "Cost: " << cost << "\nSolution:"; 34 | for( auto v : solution ) 35 | std::cout << " " << v; 36 | std::cout << "\n"; 37 | } 38 | -------------------------------------------------------------------------------- /license_text: -------------------------------------------------------------------------------- 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-2023 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 | -------------------------------------------------------------------------------- /include/macros.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #if defined GHOST_TRACE_PARALLEL 33 | #define GHOST_TRACE 34 | #include 35 | #include 36 | #define COUT _log_trace 37 | #else 38 | #define COUT std::cout 39 | #endif 40 | 41 | #if defined GHOST_RANDOM_WALK 42 | #define GHOST_TRACE 43 | #endif 44 | 45 | #if defined GHOST_HILL_CLIMBING 46 | #define GHOST_TRACE 47 | #endif 48 | 49 | #if defined GHOST_FITNESS_CLOUD 50 | #define GHOST_TRACE 51 | #endif 52 | -------------------------------------------------------------------------------- /src/algorithms/uniform_variable_heuristic.cpp: -------------------------------------------------------------------------------- 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 | #include "algorithms/uniform_variable_heuristic.hpp" 31 | 32 | using ghost::algorithms::UniformVariableHeuristic; 33 | 34 | UniformVariableHeuristic::UniformVariableHeuristic() 35 | : VariableHeuristic( "Uniform" ) 36 | { } 37 | 38 | int UniformVariableHeuristic::select_variable( const std::vector& candidates, const SearchUnitData& data, randutils::mt19937_rng& rng ) const 39 | { 40 | return static_cast( rng.pick( candidates ) ); 41 | } 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://github.com/richoux/GHOST/wiki/images/GHOST_banner.png) 2 | 3 | [![3.2.0](https://img.shields.io/badge/stable-3.2.0-brightgreen.svg)](https://github.com/richoux/GHOST/releases/tag/3.2.0) 4 | [![3.2.x](https://img.shields.io/badge/latest-3.2.x-f57f17.svg)](https://github.com/richoux/GHOST/tree/develop) 5 | [![Actions Status](https://github.com/richoux/GHOST/workflows/Linux/badge.svg)](https://github.com/richoux/GHOST/actions) 6 | [![Actions Status](https://github.com/richoux/GHOST/workflows/MacOS/badge.svg)](https://github.com/richoux/GHOST/actions) 7 | [![Actions Status](https://github.com/richoux/GHOST/workflows/Windows/badge.svg)](https://github.com/richoux/GHOST/actions) 8 | [![License](https://img.shields.io/badge/License-GNU_GPL_v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html) 9 | 10 | GHOST (General meta-Heuristic Optimization Solving Toolkit) is a C++ library designed to help developers to model and implement optimization problem solving. It contains a meta-heuristic solver aiming to solve any kind of combinatorial and optimization real-time problems represented by a Constraint Satisfaction Problem (CSP), a Constrained Optimization Problem (COP), a Error Function Constraint-based Satisfaction Problem (EF-CSP), or a Error Function-based Constrained Optimization Problem (EF-COP). 11 | 12 | ## License 13 | 14 | GHOST is under the term of the GNU GPL v3 license. Dual-licenses are possible (see the [dual-license wiki section](https://github.com/richoux/GHOST/wiki/1.-Introduction#possibilities-for-dual-license)). 15 | 16 | ## Code documentation 17 | 18 | Please visit [richoux.github.io/GHOST](https://richoux.github.io/GHOST) for the full Doxygen documentation. 19 | 20 | ## How to install 21 | 22 | Installation steps for GNU/Linux, OSX and Windows can be found here: [wiki How to install](https://github.com/richoux/GHOST/wiki/2.-How-to-install). 23 | 24 | ## User manual 25 | 26 | For a short tutorial on Constraint Programming and the 'How to use GHOST' section, please visit the [user manual](https://github.com/richoux/GHOST/wiki). 27 | -------------------------------------------------------------------------------- /include/algorithms/uniform_variable_heuristic.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "variable_heuristic.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace algorithms 39 | { 40 | class UniformVariableHeuristic : public VariableHeuristic 41 | { 42 | public: 43 | UniformVariableHeuristic(); 44 | 45 | int select_variable( const std::vector& candidates, const SearchUnitData& data, randutils::mt19937_rng& rng ) const override; 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /include/algorithms/all_free_variable_candidates_heuristic.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "variable_candidates_heuristic.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace algorithms 39 | { 40 | class AllFreeVariableCandidatesHeuristic : public VariableCandidatesHeuristic 41 | { 42 | public: 43 | AllFreeVariableCandidatesHeuristic(); 44 | 45 | std::vector compute_variable_candidates( const SearchUnitData& data ) const override; 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /include/algorithms/antidote_search_variable_heuristic.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "variable_heuristic.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace algorithms 39 | { 40 | class AntidoteSearchVariableHeuristic : public VariableHeuristic 41 | { 42 | public: 43 | AntidoteSearchVariableHeuristic(); 44 | 45 | int select_variable( const std::vector& candidates, const SearchUnitData& data, randutils::mt19937_rng& rng ) const override; 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /include/algorithms/adaptive_search_variable_candidates_heuristic.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "variable_candidates_heuristic.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace algorithms 39 | { 40 | class AdaptiveSearchVariableCandidatesHeuristic : public VariableCandidatesHeuristic 41 | { 42 | public: 43 | AdaptiveSearchVariableCandidatesHeuristic(); 44 | 45 | std::vector compute_variable_candidates( const SearchUnitData& data ) const override; 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /include/algorithms/antidote_search_variable_candidates_heuristic.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "variable_candidates_heuristic.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace algorithms 39 | { 40 | class AntidoteSearchVariableCandidatesHeuristic : public VariableCandidatesHeuristic 41 | { 42 | public: 43 | AntidoteSearchVariableCandidatesHeuristic(); 44 | 45 | std::vector compute_variable_candidates( const SearchUnitData& data ) const override; 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/model.cpp: -------------------------------------------------------------------------------- 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 | #include "model.hpp" 31 | 32 | using ghost::Model; 33 | 34 | Model::Model( std::vector&& moved_variables, 35 | const std::vector>& constraints, 36 | const std::shared_ptr& objective, 37 | const std::shared_ptr& auxiliary_data, 38 | bool permutation_problem ) 39 | : variables( std::move( moved_variables ) ), 40 | constraints( constraints ), 41 | objective( objective ), 42 | auxiliary_data( auxiliary_data ), 43 | permutation_problem( permutation_problem ) 44 | { } 45 | -------------------------------------------------------------------------------- /include/algorithms/random_walk_value_heuristic.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "value_heuristic.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace algorithms 39 | { 40 | class RandomWalkValueHeuristic : public ValueHeuristic 41 | { 42 | public: 43 | RandomWalkValueHeuristic(); 44 | 45 | int select_value( int variable_to_change, 46 | const SearchUnitData& data, 47 | const Model& model, 48 | const std::map>& delta_errors, 49 | double& min_conflict, 50 | randutils::mt19937_rng& rng ) const override; 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/algorithms/antidote_search_variable_heuristic.cpp: -------------------------------------------------------------------------------- 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 | #include "algorithms/antidote_search_variable_heuristic.hpp" 31 | #include "thirdparty/randutils.hpp" 32 | 33 | using ghost::algorithms::AntidoteSearchVariableHeuristic; 34 | 35 | AntidoteSearchVariableHeuristic::AntidoteSearchVariableHeuristic() 36 | : VariableHeuristic( "Antidote Search" ) 37 | { } 38 | 39 | int AntidoteSearchVariableHeuristic::select_variable( const std::vector& candidates, const SearchUnitData& data, randutils::mt19937_rng& rng ) const 40 | { 41 | // WARNING: must remove variables which are in any constraints 42 | return rng.variate( candidates.begin(), candidates.end() ); 43 | } 44 | -------------------------------------------------------------------------------- /include/algorithms/adaptive_search_value_heuristic.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "value_heuristic.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace algorithms 39 | { 40 | class AdaptiveSearchValueHeuristic : public ValueHeuristic 41 | { 42 | public: 43 | AdaptiveSearchValueHeuristic(); 44 | 45 | int select_value( int variable_to_change, 46 | const SearchUnitData& data, 47 | const Model& model, 48 | const std::map>& delta_errors, 49 | double& min_conflict, 50 | randutils::mt19937_rng& rng ) const override; 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /include/algorithms/antidote_search_value_heuristic.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "value_heuristic.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace algorithms 39 | { 40 | class AntidoteSearchValueHeuristic : public ValueHeuristic 41 | { 42 | public: 43 | AntidoteSearchValueHeuristic(); 44 | 45 | int select_value( int variable_to_change, 46 | const SearchUnitData& data, 47 | const Model& model, 48 | const std::map>& delta_errors, 49 | double& min_conflict, 50 | randutils::mt19937_rng& rng ) const override; 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/algorithms/all_free_variable_candidates_heuristic.cpp: -------------------------------------------------------------------------------- 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 | #include "algorithms/all_free_variable_candidates_heuristic.hpp" 31 | 32 | using ghost::algorithms::AllFreeVariableCandidatesHeuristic; 33 | 34 | AllFreeVariableCandidatesHeuristic::AllFreeVariableCandidatesHeuristic() 35 | : VariableCandidatesHeuristic( "All Free" ) 36 | { } 37 | 38 | std::vector AllFreeVariableCandidatesHeuristic::compute_variable_candidates( const SearchUnitData& data ) const 39 | { 40 | std::vector free_variables_list; 41 | for( int variable_id = 0 ; variable_id < data.number_variables ; ++variable_id ) 42 | if( data.tabu_list[ variable_id ] <= data.local_moves ) 43 | free_variables_list.push_back( variable_id ); 44 | 45 | return free_variables_list; 46 | } 47 | -------------------------------------------------------------------------------- /doc/mainpage.md: -------------------------------------------------------------------------------- 1 | Introduction 2 | ==== 3 | 4 | GHOST (General meta-Heuristic Optimization Solving Toolkit) is a C++17 5 | library to let a user declare his or her own combinatorial 6 | problems. It implements a meta-heuristic solver aiming to solve any 7 | kind of combinatorial and optimization RTS-related problems declared 8 | in Constraint Programming. 9 | 10 | GHOST allows the user to easily declare problems in different 11 | Constraint Programming formalisms such as Constraint Satisfaction 12 | Problems (CSP), Constrained Optimization Problems (COP), Error 13 | Function Satisfaction Problems (EFSP), and Error Function Optimization 14 | Problems (EFOP). 15 | 16 | This toolkit has first been designed to solved optimization problems 17 | within the game StarCraft: Brood war, but can be used to deal with any 18 | combinatorial problems. It is a generalization of the Wall-in project 19 | (see 20 | [github.com/richoux/Wall-in](https://github.com/richoux/Wall-in)). 21 | 22 | The source code is available at 23 | [github.com/richoux/GHOST](https://github.com/richoux/GHOST), and the 24 | documentation pages at 25 | [richoux.github.io/GHOST](http://richoux.github.io/GHOST). GHOST is 26 | under the terms of the GNU GPL v3 licence. 27 | 28 | Install instructions, a short Constraint Programming tutorial, GHOST 29 | tutorials, and more, are available on the [wiki of GHOST's GitHub 30 | page](https://github.com/richoux/GHOST/wiki/). 31 | 32 | Scientific papers about GHOST: 33 | ---- 34 | 35 | You can find PDFs of these papers on my [personnal web page](https://richoux.fr). 36 | 37 | - Florian Richoux, Jean-François Baffier and Alberto Uriarte, 38 | [GHOST: A Combinatorial Optimization Solver for RTS-related 39 | Problems](https://doi.org/10.1109/TCIAIG.2016.2573199), 40 | IEEE Transactions on Computational Intelligence and AI in Games, 41 | 2016. 42 | - Julien Fradin and Florian Richoux, [Robustness and Flexibility of GHOST](https://www.aaai.org/ocs/index.php/AIIDE/AIIDE15/paper/view/11558/11383), AIIDE 2015 RTS Workshop. 43 | - Florian Richoux, Alberto Uriarte and Santiago Ontañón, [Walling in 44 | Strategy Games via Constraint Optimization](https://www.aaai.org/ocs/index.php/AIIDE/AIIDE14/paper/view/8956), AIIDE 2014. 45 | -------------------------------------------------------------------------------- /src/algorithms/antidote_search_variable_candidates_heuristic.cpp: -------------------------------------------------------------------------------- 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 | #include "algorithms/antidote_search_variable_candidates_heuristic.hpp" 31 | #include "thirdparty/randutils.hpp" 32 | 33 | using ghost::algorithms::AntidoteSearchVariableCandidatesHeuristic; 34 | 35 | AntidoteSearchVariableCandidatesHeuristic::AntidoteSearchVariableCandidatesHeuristic() 36 | : VariableCandidatesHeuristic( "Antidote Search" ) 37 | { } 38 | 39 | std::vector AntidoteSearchVariableCandidatesHeuristic::compute_variable_candidates( const SearchUnitData& data ) const 40 | { 41 | auto error_variables = data.error_variables; 42 | 43 | for( int variable_id = 0; variable_id < data.number_variables; ++variable_id ) 44 | if( data.tabu_list[ variable_id ] > data.local_moves ) 45 | error_variables[ variable_id ] = 0.0; 46 | 47 | return error_variables; 48 | } 49 | -------------------------------------------------------------------------------- /include/algorithms/null_error_projection_algorithm.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include "error_projection_algorithm.hpp" 33 | 34 | namespace ghost 35 | { 36 | namespace algorithms 37 | { 38 | class NullErrorProjection : public ErrorProjection 39 | { 40 | public: 41 | NullErrorProjection(); 42 | 43 | void compute_variable_errors( const std::vector& variables, 44 | const std::vector>& constraints, 45 | SearchUnitData& data ) override; 46 | 47 | void update_variable_errors( const std::vector& variables, 48 | std::shared_ptr constraint, 49 | SearchUnitData& data, 50 | double delta ) override; 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /include/print.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | #include 34 | 35 | #include "variable.hpp" 36 | 37 | namespace ghost 38 | { 39 | /*! 40 | * ghost::Print is a class users can derive from to write their own way of printing candidates 41 | * and solutions, when the macro GHOST_BENCH is given to the compiler. 42 | */ 43 | class Print 44 | { 45 | public: 46 | //! Default virtual destructor. 47 | virtual ~Print() = default; 48 | 49 | /*! 50 | * The unique method to override for defining how to print candidates and solutions 51 | * on the screen. 52 | * 53 | * \param variables a const reference to the vector of variables containing values to print. 54 | * \return A std::stringstream. 55 | */ 56 | virtual std::stringstream print_candidate( const std::vector& variables ) const; 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /include/model.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #include "variable.hpp" 37 | #include "constraint.hpp" 38 | #include "objective.hpp" 39 | #include "auxiliary_data.hpp" 40 | 41 | namespace ghost 42 | { 43 | struct Model final 44 | { 45 | std::vector variables; 46 | std::vector> constraints; 47 | std::shared_ptr objective; 48 | std::shared_ptr auxiliary_data; 49 | bool permutation_problem; 50 | 51 | Model() = default; 52 | 53 | Model( std::vector&& variables, 54 | const std::vector>& constraints, 55 | const std::shared_ptr& objective, 56 | const std::shared_ptr& auxiliary_data, 57 | bool permutation_problem ); 58 | }; 59 | } 60 | -------------------------------------------------------------------------------- /tutorial/video/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.1) 2 | project (ghost_tutorial_video) 3 | 4 | set( CMAKE_VERBOSE_MAKEFILE on ) 5 | 6 | # require a C++17-capable compiler 7 | include(CheckCXXCompilerFlag) 8 | CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17) 9 | CHECK_CXX_COMPILER_FLAG("-std=c++1z" COMPILER_SUPPORTS_CXX1Z) 10 | CHECK_CXX_COMPILER_FLAG("/std:c++17" COMPILER_SUPPORTS_CXX17_WIN) 11 | if(COMPILER_SUPPORTS_CXX17) 12 | set(CMAKE_CXX_FLAGS "-std=c++17") 13 | elseif(COMPILER_SUPPORTS_CXX1Z) 14 | set(CMAKE_CXX_FLAGS "-std=c++1z") 15 | elseif(COMPILER_SUPPORTS_CXX17_WIN) 16 | set(CMAKE_CXX_FLAGS "/std:c++17") 17 | else() 18 | message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++17 support. Please use a different C++ compiler.") 19 | endif() 20 | 21 | if(WIN32) 22 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive-") 23 | INCLUDE_DIRECTORIES("C:/Program Files (x86)/ghost/include") 24 | link_directories("C:/Program Files (x86)/ghost/lib") 25 | else() 26 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") 27 | endif() 28 | 29 | if(APPLE) 30 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem\ /usr/local/include") 31 | endif() 32 | 33 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 34 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fsanitize=address,undefined,leak") 35 | set(CMAKE_EXE_FLAGS_DEBUG "-fsanitize=address,undefined,leak") 36 | endif() 37 | 38 | ## These two lines are the reason why we need CMake version 3.1.0+ 39 | set(THREADS_PREFER_PTHREAD_FLAG ON) 40 | find_package(Threads REQUIRED) 41 | 42 | # add the targets 43 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) 44 | 45 | add_executable( tutorial_knapsack src/knapsack_alldiff.cpp src/knapsack_capacity.cpp src/knapsack_model_builder.cpp src/knapsack_objective.cpp src/knapsack.cpp ) 46 | target_compile_definitions( tutorial_knapsack PUBLIC -DGHOST_BENCH ) 47 | 48 | if(APPLE) 49 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 50 | target_link_libraries(tutorial_knapsack /usr/local/lib/libghost_staticd.a Threads::Threads) 51 | else() 52 | target_link_libraries(tutorial_knapsack /usr/local/lib/libghost_static.a Threads::Threads) 53 | endif() 54 | else() 55 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 56 | target_link_libraries(tutorial_knapsack ghost Threads::Threads) 57 | else() 58 | target_link_libraries(tutorial_knapsack ghost_static Threads::Threads) 59 | endif() 60 | endif() 61 | -------------------------------------------------------------------------------- /include/algorithms/adaptive_search_error_projection_algorithm.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include "error_projection_algorithm.hpp" 33 | 34 | namespace ghost 35 | { 36 | namespace algorithms 37 | { 38 | class AdaptiveSearchErrorProjection : public ErrorProjection 39 | { 40 | public: 41 | AdaptiveSearchErrorProjection(); 42 | 43 | void compute_variable_errors( const std::vector& variables, 44 | const std::vector>& constraints, 45 | SearchUnitData& data ) override; 46 | 47 | void update_variable_errors( const std::vector& variables, 48 | std::shared_ptr constraint, 49 | SearchUnitData& data, 50 | double delta ) override; 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/algorithms/null_error_projection_algorithm.cpp: -------------------------------------------------------------------------------- 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 | #include "algorithms/null_error_projection_algorithm.hpp" 31 | 32 | using ghost::algorithms::NullErrorProjection; 33 | using ghost::Variable; 34 | using ghost::Constraint; 35 | 36 | NullErrorProjection::NullErrorProjection() 37 | : ErrorProjection( "Null Error Projection" ) 38 | {} 39 | 40 | void NullErrorProjection::compute_variable_errors( const std::vector& variables, 41 | const std::vector>& constraints, 42 | SearchUnitData& data ) 43 | {} 44 | 45 | void NullErrorProjection::update_variable_errors( const std::vector& variables, 46 | std::shared_ptr constraint, 47 | SearchUnitData& data, 48 | double delta ) 49 | {} 50 | -------------------------------------------------------------------------------- /src/auxiliary_data.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | 32 | #include "auxiliary_data.hpp" 33 | 34 | using ghost::AuxiliaryData; 35 | 36 | AuxiliaryData::AuxiliaryData() 37 | : _variables_index( std::vector{0} ) 38 | { } 39 | 40 | AuxiliaryData::AuxiliaryData( const std::vector& variables_index ) 41 | : _variables_index( variables_index ) 42 | { } 43 | 44 | AuxiliaryData::AuxiliaryData( const std::vector& variables ) 45 | : _variables_index( std::vector( variables.size() ) ) 46 | { 47 | std::transform( variables.begin(), 48 | variables.end(), 49 | _variables_index.begin(), 50 | [&](const auto& v){ return v.get_id(); } ); 51 | } 52 | 53 | void AuxiliaryData::update( int index, int new_value ) 54 | { 55 | if( _variables_position.count( index) > 0 ) 56 | required_update( _variables, _variables_position.at( index ), new_value ); 57 | } 58 | 59 | void AuxiliaryData::update() 60 | { 61 | for( int i = 0 ; i < static_cast( _variables.size() ) ; ++i ) 62 | required_update( _variables, i, _variables[i]->get_value() ); 63 | } 64 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.1) 2 | project (ghost_tests) 3 | 4 | set( CMAKE_VERBOSE_MAKEFILE on ) 5 | 6 | # require a C++17-capable compiler 7 | include(CheckCXXCompilerFlag) 8 | CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17) 9 | CHECK_CXX_COMPILER_FLAG("-std=c++1z" COMPILER_SUPPORTS_CXX1Z) 10 | CHECK_CXX_COMPILER_FLAG("/std:c++17" COMPILER_SUPPORTS_CXX17_WIN) 11 | if(COMPILER_SUPPORTS_CXX17) 12 | set(CMAKE_CXX_FLAGS "-std=c++17") 13 | elseif(COMPILER_SUPPORTS_CXX1Z) 14 | set(CMAKE_CXX_FLAGS "-std=c++1z") 15 | elseif(COMPILER_SUPPORTS_CXX17_WIN) 16 | set(CMAKE_CXX_FLAGS "/std:c++17") 17 | else() 18 | message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++17 support. Please use a different C++ compiler.") 19 | endif() 20 | 21 | if(WIN32) 22 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive-") 23 | INCLUDE_DIRECTORIES("C:/Program Files (x86)/ghost/include") 24 | INCLUDE_DIRECTORIES("C:/Program Files (x86)/googletest-distribution/include/") 25 | link_directories("C:/Program Files (x86)/googletest-distribution/lib/") 26 | link_directories("C:/Program Files (x86)/ghost/lib") 27 | else() 28 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") 29 | endif() 30 | 31 | if(APPLE) 32 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem\ /usr/local/include") 33 | endif() 34 | 35 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 36 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fsanitize=address,undefined,leak") 37 | set(CMAKE_EXE_FLAGS_DEBUG "-fsanitize=address,undefined,leak") 38 | endif() 39 | 40 | ## These two lines are the reason why we need CMake version 3.1.0+ 41 | set(THREADS_PREFER_PTHREAD_FLAG ON) 42 | find_package(Threads REQUIRED) 43 | 44 | # add the targets 45 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) 46 | 47 | ################################ 48 | # Unit Tests 49 | ################################ 50 | # Add tests cpp file 51 | add_executable( test_variable src/test_variable.cpp ) 52 | 53 | if(APPLE) 54 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 55 | target_link_libraries(test_variable /usr/local/lib/libgtest.a /usr/local/lib/libghost_staticd.a Threads::Threads) 56 | else() 57 | target_link_libraries(test_variable /usr/local/lib/libgtest.a /usr/local/lib/libghost_static.a Threads::Threads) 58 | endif() 59 | else() 60 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 61 | target_link_libraries(test_variable gtest ghostd Threads::Threads) 62 | else() 63 | target_link_libraries(test_variable gtest ghost Threads::Threads) 64 | endif() 65 | endif() 66 | 67 | enable_testing() 68 | add_test( NAME Test_Variable COMMAND test_variable WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin ) 69 | -------------------------------------------------------------------------------- /src/algorithms/random_walk_value_heuristic.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | 33 | #include "algorithms/random_walk_value_heuristic.hpp" 34 | 35 | using ghost::algorithms::RandomWalkValueHeuristic; 36 | using ghost::SearchUnitData; 37 | using ghost::Model; 38 | 39 | RandomWalkValueHeuristic::RandomWalkValueHeuristic() 40 | : ValueHeuristic( "Random Walk" ) 41 | { } 42 | 43 | int RandomWalkValueHeuristic::select_value( int variable_to_change, 44 | const SearchUnitData& data, 45 | const Model& model, 46 | const std::map>& delta_errors, 47 | double& min_conflict, 48 | randutils::mt19937_rng& rng ) const 49 | { 50 | auto pick_value_and_errors = static_cast>>( rng.pick( delta_errors ) ); 51 | min_conflict = std::accumulate( pick_value_and_errors.second.begin(), pick_value_and_errors.second.end(), 0.0 ); 52 | return pick_value_and_errors.first; 53 | } 54 | -------------------------------------------------------------------------------- /src/global_constraints/linear_equation_eq.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | #include 33 | 34 | #include "global_constraints/linear_equation_eq.hpp" 35 | 36 | using ghost::global_constraints::LinearEquationEq; 37 | 38 | LinearEquationEq::LinearEquationEq( const std::vector& variables_index, double rhs, const std::vector& coefficients ) 39 | : LinearEquation( variables_index, rhs, coefficients ) 40 | { } 41 | 42 | LinearEquationEq::LinearEquationEq( const std::vector& variables_index, double rhs ) 43 | : LinearEquation( variables_index, rhs, std::vector( variables_index.size(), 1.0 ) ) 44 | { } 45 | 46 | LinearEquationEq::LinearEquationEq( const std::vector& variables, double rhs, const std::vector& coefficients ) 47 | : LinearEquation( variables, rhs, coefficients ) 48 | { } 49 | 50 | LinearEquationEq::LinearEquationEq( const std::vector& variables, double rhs ) 51 | : LinearEquation( variables, rhs, std::vector( variables.size(), 1.0 ) ) 52 | { } 53 | 54 | double LinearEquationEq::compute_error( double sum ) const 55 | { 56 | return std::abs( sum - rhs ); 57 | } 58 | -------------------------------------------------------------------------------- /src/global_constraints/linear_equation_geq.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | #include 33 | 34 | #include "global_constraints/linear_equation_geq.hpp" 35 | 36 | using ghost::global_constraints::LinearEquationGeq; 37 | 38 | LinearEquationGeq::LinearEquationGeq( const std::vector& variables_index, double rhs, const std::vector& coefficients ) 39 | : LinearEquation( variables_index, rhs, coefficients ) 40 | { } 41 | 42 | LinearEquationGeq::LinearEquationGeq( const std::vector& variables_index, double rhs ) 43 | : LinearEquation( variables_index, rhs, std::vector( variables_index.size(), 1.0 ) ) 44 | { } 45 | 46 | LinearEquationGeq::LinearEquationGeq( const std::vector& variables, double rhs, const std::vector& coefficients ) 47 | : LinearEquation( variables, rhs, coefficients ) 48 | { } 49 | 50 | LinearEquationGeq::LinearEquationGeq( const std::vector& variables, double rhs ) 51 | : LinearEquation( variables, rhs, std::vector( variables.size(), 1.0 ) ) 52 | { } 53 | 54 | double LinearEquationGeq::compute_error( double sum ) const 55 | { 56 | return std::max( 0.0, rhs - sum ); 57 | } 58 | -------------------------------------------------------------------------------- /src/global_constraints/linear_equation_leq.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | #include 33 | 34 | #include "global_constraints/linear_equation_leq.hpp" 35 | 36 | using ghost::global_constraints::LinearEquationLeq; 37 | 38 | LinearEquationLeq::LinearEquationLeq( const std::vector& variables_index, double rhs, const std::vector& coefficients ) 39 | : LinearEquation( variables_index, rhs, coefficients ) 40 | { } 41 | 42 | LinearEquationLeq::LinearEquationLeq( const std::vector& variables_index, double rhs ) 43 | : LinearEquation( variables_index, rhs, std::vector( variables_index.size(), 1.0 ) ) 44 | { } 45 | 46 | LinearEquationLeq::LinearEquationLeq( const std::vector& variables, double rhs, const std::vector& coefficients ) 47 | : LinearEquation( variables, rhs, coefficients ) 48 | { } 49 | 50 | LinearEquationLeq::LinearEquationLeq( const std::vector& variables, double rhs ) 51 | : LinearEquation( variables, rhs, std::vector( variables.size(), 1.0 ) ) 52 | { } 53 | 54 | double LinearEquationLeq::compute_error( double sum ) const 55 | { 56 | return std::max( 0.0, sum - rhs ); 57 | } 58 | -------------------------------------------------------------------------------- /src/print.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | #include 33 | 34 | #include "print.hpp" 35 | 36 | using ghost::Print; 37 | 38 | std::stringstream Print::print_candidate( const std::vector& variables ) const 39 | { 40 | std::stringstream stream; 41 | 42 | if( !variables.empty() ) 43 | { 44 | stream << "Variables:\n"; 45 | int max_element = std::numeric_limits::min(); 46 | for( const auto& var : variables ) 47 | if( max_element < var.get_value() ) 48 | max_element = var.get_value(); 49 | 50 | int indent_values = std::ceil( std::log10( max_element ) ) + 1; 51 | int indent_indexes = std::ceil( std::log10( static_cast( variables.size() ) ) ); 52 | for( int i = 0 ; i < static_cast( variables.size() ) ; ++i ) 53 | { 54 | if( i % 10 == 0 ) 55 | { 56 | if( i != 0 ) 57 | stream << "\n"; 58 | stream << "v[" << std::setw( indent_indexes ) << i << "]:" << std::setw( indent_values ) << variables[i].get_value(); 59 | } 60 | else 61 | stream << ", v[" << std::setw( indent_indexes ) << i << "]:" << std::setw( indent_values ) << variables[i].get_value(); 62 | } 63 | stream << "\n"; 64 | } 65 | 66 | return stream; 67 | } 68 | -------------------------------------------------------------------------------- /src/global_constraints/linear_equation_g.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | #include 33 | 34 | #include "global_constraints/linear_equation_g.hpp" 35 | 36 | using ghost::global_constraints::LinearEquationG; 37 | 38 | LinearEquationG::LinearEquationG( const std::vector& variables_index, double rhs, const std::vector& coefficients ) 39 | : LinearEquation( variables_index, rhs, coefficients ) 40 | { } 41 | 42 | LinearEquationG::LinearEquationG( const std::vector& variables_index, double rhs ) 43 | : LinearEquation( variables_index, rhs, std::vector( variables_index.size(), 1.0 ) ) 44 | { } 45 | 46 | LinearEquationG::LinearEquationG( const std::vector& variables, double rhs, const std::vector& coefficients ) 47 | : LinearEquation( variables, rhs, coefficients ) 48 | { } 49 | 50 | LinearEquationG::LinearEquationG( const std::vector& variables, double rhs ) 51 | : LinearEquation( variables, rhs, std::vector( variables.size(), 1.0 ) ) 52 | { } 53 | 54 | double LinearEquationG::compute_error( double sum ) const 55 | { 56 | double equals = 0.0; 57 | if( rhs == sum ) 58 | equals = 1.0; 59 | 60 | return std::max( 0.0, rhs - sum ) + equals; 61 | } 62 | -------------------------------------------------------------------------------- /src/global_constraints/linear_equation_l.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | #include 33 | 34 | #include "global_constraints/linear_equation_l.hpp" 35 | 36 | using ghost::global_constraints::LinearEquationL; 37 | 38 | LinearEquationL::LinearEquationL( const std::vector& variables_index, double rhs, const std::vector& coefficients ) 39 | : LinearEquation( variables_index, rhs, coefficients ) 40 | { } 41 | 42 | LinearEquationL::LinearEquationL( const std::vector& variables_index, double rhs ) 43 | : LinearEquation( variables_index, rhs, std::vector( variables_index.size(), 1.0 ) ) 44 | { } 45 | 46 | LinearEquationL::LinearEquationL( const std::vector& variables, double rhs, const std::vector& coefficients ) 47 | : LinearEquation( variables, rhs, coefficients ) 48 | { } 49 | 50 | LinearEquationL::LinearEquationL( const std::vector& variables, double rhs ) 51 | : LinearEquation( variables, rhs, std::vector( variables.size(), 1.0 ) ) 52 | { } 53 | 54 | double LinearEquationL::compute_error( double sum ) const 55 | { 56 | double equals = 0.0; 57 | if( rhs == sum ) 58 | equals = 1.0; 59 | 60 | return std::max( 0.0, sum - rhs ) + equals; 61 | } 62 | -------------------------------------------------------------------------------- /src/global_constraints/linear_equation_neq.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | #include 33 | 34 | #include "global_constraints/linear_equation_neq.hpp" 35 | 36 | using ghost::global_constraints::LinearEquationNeq; 37 | 38 | LinearEquationNeq::LinearEquationNeq( const std::vector& variables_index, double rhs, const std::vector& coefficients ) 39 | : LinearEquation( variables_index, rhs, coefficients ) 40 | { } 41 | 42 | LinearEquationNeq::LinearEquationNeq( const std::vector& variables_index, double rhs ) 43 | : LinearEquation( variables_index, rhs, std::vector( variables_index.size(), 1.0 ) ) 44 | { } 45 | 46 | LinearEquationNeq::LinearEquationNeq( const std::vector& variables, double rhs, const std::vector& coefficients ) 47 | : LinearEquation( variables, rhs, coefficients ) 48 | { } 49 | 50 | LinearEquationNeq::LinearEquationNeq( const std::vector& variables, double rhs ) 51 | : LinearEquation( variables, rhs, std::vector( variables.size(), 1.0 ) ) 52 | { } 53 | 54 | double LinearEquationNeq::compute_error( double sum ) const 55 | { 56 | double equals_current = 0.0; 57 | if( rhs == sum ) 58 | equals_current = 1.0; 59 | 60 | return equals_current; 61 | } 62 | -------------------------------------------------------------------------------- /src/global_constraints/fix_value.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | 32 | #include "global_constraints/fix_value.hpp" 33 | 34 | using ghost::global_constraints::FixValue; 35 | 36 | FixValue::FixValue( const std::vector& variables_index, int value ) 37 | : Constraint( variables_index ), 38 | _value( value ) 39 | { } 40 | 41 | FixValue::FixValue( const std::vector& variables, int value ) 42 | : Constraint( variables ), 43 | _value( value ) 44 | { } 45 | 46 | double FixValue::required_error( const std::vector& variables ) const 47 | { 48 | double error = 0.; 49 | for( auto& var : variables ) 50 | error += std::abs( var->get_value() - _value ); 51 | return error; 52 | } 53 | 54 | double FixValue::optional_delta_error( const std::vector& variables, 55 | const std::vector& variable_indexes, 56 | const std::vector& candidate_values ) const 57 | { 58 | double diff = 0.; 59 | for( int index = 0 ; index < static_cast( variable_indexes.size() ) ; ++index ) 60 | diff += std::abs( candidate_values[ index ] - _value ) 61 | - std::abs( variables[ variable_indexes[ index ] ]->get_value() - _value ); 62 | 63 | return diff; 64 | } 65 | -------------------------------------------------------------------------------- /include/algorithms/culprit_search_error_projection_algorithm.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include "error_projection_algorithm.hpp" 33 | 34 | namespace ghost 35 | { 36 | namespace algorithms 37 | { 38 | class CulpritSearchErrorProjection : public ErrorProjection 39 | { 40 | std::vector> _error_variables_by_constraints; 41 | 42 | void compute_variable_errors_on_constraint( const std::vector& variables, 43 | const std::vector>& matrix_var_ctr, 44 | std::shared_ptr constraint ); 45 | 46 | public: 47 | CulpritSearchErrorProjection(); 48 | 49 | void initialize_data_structures( const SearchUnitData& data ) override; 50 | 51 | void compute_variable_errors( const std::vector& variables, 52 | const std::vector>& constraints, 53 | SearchUnitData& data ) override; 54 | 55 | void update_variable_errors( const std::vector& variables, 56 | std::shared_ptr constraint, 57 | SearchUnitData& data, 58 | double delta ) override; 59 | }; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /.github/workflows/linux.yml: -------------------------------------------------------------------------------- 1 | name: Linux 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - 'feature/*' 7 | pull_request: 8 | branches-ignore: 9 | - 'feature/*' 10 | 11 | env: 12 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 13 | BUILD_TYPE: Release 14 | CXX: g++-14 15 | EXPERIMENTAL: "" 16 | 17 | jobs: 18 | build: 19 | # The CMake configure and build commands are platform agnostic and should work equally 20 | # well on Windows or Mac. You can convert this to a matrix build if you need 21 | # cross-platform coverage. 22 | # See: https://docs.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow#configuring-a-build-matrix 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - name: Install gtest manually 27 | run: git clone https://github.com/google/googletest.git && cd googletest && mkdir build && cd build && cmake .. && make && sudo make install 28 | 29 | - uses: actions/checkout@v2 30 | 31 | - name: Create Build Environment 32 | # Some projects don't allow in-source building, so create a separate build directory 33 | # We'll use this as our working directory for all subsequent commands 34 | run: cmake -E make_directory ${{runner.workspace}}/GHOST/build 35 | 36 | - name: Configure CMake 37 | # Use a bash shell so we can use the same syntax for environment variable 38 | # access regardless of the host operating system 39 | shell: bash 40 | working-directory: ${{runner.workspace}}/GHOST/build 41 | # Note the current convention is to use the -S and -B options here to specify source 42 | # and build directories, but this is only available with CMake 3.13 and higher. 43 | # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 44 | run: cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_COMPILER=$CXX $EXPERIMENTAL .. 45 | 46 | - name: Build GHOST 47 | working-directory: ${{runner.workspace}}/GHOST/build 48 | shell: bash 49 | run: make 50 | 51 | - name: Install GHOST 52 | working-directory: ${{runner.workspace}}/GHOST/build 53 | shell: bash 54 | run: sudo make install && sudo ldconfig 55 | 56 | - name: Build Test 57 | working-directory: ${{runner.workspace}}/GHOST/tests 58 | run: mkdir build && cd build && cmake .. && make 59 | 60 | - name: Run Test 61 | working-directory: ${{runner.workspace}}/GHOST/tests/build 62 | shell: bash 63 | run: ctest 64 | 65 | - name: Build Tutorial Wiki 66 | working-directory: ${{runner.workspace}}/GHOST/tutorial/wiki 67 | run: mkdir -p build && cd build && cmake .. && make 68 | 69 | - name: Build Tutorial Video 70 | working-directory: ${{runner.workspace}}/GHOST/tutorial/video 71 | run: mkdir -p build && cd build && cmake .. && make 72 | -------------------------------------------------------------------------------- /src/algorithms/adaptive_search_variable_candidates_heuristic.cpp: -------------------------------------------------------------------------------- 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 | #include "algorithms/adaptive_search_variable_candidates_heuristic.hpp" 31 | 32 | using ghost::algorithms::AdaptiveSearchVariableCandidatesHeuristic; 33 | 34 | AdaptiveSearchVariableCandidatesHeuristic::AdaptiveSearchVariableCandidatesHeuristic() 35 | : VariableCandidatesHeuristic( "Adaptive Search" ) 36 | { } 37 | 38 | std::vector AdaptiveSearchVariableCandidatesHeuristic::compute_variable_candidates( const SearchUnitData& data ) const 39 | { 40 | std::vector worst_variables_list; 41 | double worst_variable_cost = -1; 42 | 43 | for( int variable_id = 0; variable_id < data.number_variables; ++variable_id ) 44 | if( worst_variable_cost <= data.error_variables[ variable_id ] 45 | && data.tabu_list[ variable_id ] <= data.local_moves 46 | && ( !data.matrix_var_ctr.at( variable_id ).empty() || ( data.is_optimization && data.current_sat_error == 0 ) ) ) 47 | { 48 | if( worst_variable_cost < data.error_variables[ variable_id ] ) 49 | { 50 | worst_variables_list.clear(); 51 | worst_variables_list.push_back( variable_id ); 52 | worst_variable_cost = data.error_variables[ variable_id ]; 53 | } 54 | else 55 | if( worst_variable_cost == data.error_variables[ variable_id ] ) 56 | worst_variables_list.push_back( variable_id ); 57 | } 58 | 59 | return worst_variables_list; 60 | } 61 | -------------------------------------------------------------------------------- /include/algorithms/variable_candidates_heuristic.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "../search_unit_data.hpp" 35 | // #include "../macros.hpp" 36 | 37 | namespace ghost 38 | { 39 | namespace algorithms 40 | { 41 | /* 42 | * Strategy design pattern to implement variable candidates selection heuristics. 43 | */ 44 | class VariableCandidatesHeuristic 45 | { 46 | protected: 47 | // Protected string variable for the heuristic name. Used for debug/trace purposes. 48 | std::string name; 49 | 50 | public: 51 | VariableCandidatesHeuristic( std::string&& name ) 52 | : name( std::move( name ) ) 53 | { } 54 | 55 | // Default virtual destructor. 56 | virtual ~VariableCandidatesHeuristic() = default; 57 | 58 | // Inline function returning the heuristic name. 59 | inline std::string get_name() const { return name; } 60 | 61 | /* 62 | * Function to compute variable candidates, for instance regarding their projected error. 63 | * \param data A reference to the SearchUnitData object containing data about the problem instance and the search state, such as the number of variables and constraints, the current projected error on each variable, etc. 64 | * \return A vector of double to be more generic, allowing for instance a vector of errors rather than a vector of ID. 65 | */ 66 | virtual std::vector compute_variable_candidates( const SearchUnitData& data ) const = 0; 67 | }; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/algorithms/adaptive_search_error_projection_algorithm.cpp: -------------------------------------------------------------------------------- 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 | #include "algorithms/adaptive_search_error_projection_algorithm.hpp" 31 | 32 | using ghost::algorithms::AdaptiveSearchErrorProjection; 33 | using ghost::Variable; 34 | using ghost::Constraint; 35 | 36 | AdaptiveSearchErrorProjection::AdaptiveSearchErrorProjection() 37 | : ErrorProjection( "Adaptive Search" ) 38 | { } 39 | 40 | void AdaptiveSearchErrorProjection::compute_variable_errors( const std::vector& variables, 41 | const std::vector>& constraints, 42 | SearchUnitData& data ) 43 | { 44 | std::fill( data.error_variables.begin(), data.error_variables.end(), 0. ); 45 | 46 | for( int variable_id = 0; variable_id < static_cast( variables.size() ); ++variable_id ) 47 | for( int constraint_id : data.matrix_var_ctr.at( variable_id ) ) 48 | data.error_variables[ variable_id ] += constraints[ constraint_id ]->_current_error; 49 | } 50 | 51 | void AdaptiveSearchErrorProjection::update_variable_errors( const std::vector& variables, 52 | std::shared_ptr constraint, 53 | SearchUnitData& data, 54 | double delta ) 55 | { 56 | for( const int variable_id : constraint->get_variable_ids() ) 57 | data.error_variables[ variable_id ] += delta; 58 | } 59 | -------------------------------------------------------------------------------- /include/global_constraints/all_equal.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | #include 34 | 35 | #include "../variable.hpp" 36 | #include "../constraint.hpp" 37 | 38 | namespace ghost 39 | { 40 | namespace global_constraints 41 | { 42 | /*! 43 | * Implementation of the All Equal constraint. 44 | * See http://sofdem.github.io/gccat/gccat/Call_equal.html 45 | */ 46 | class AllEqual : public Constraint 47 | { 48 | mutable std::map _count; 49 | 50 | double required_error( const std::vector& variables ) const override; 51 | 52 | double optional_delta_error( const std::vector& variables, 53 | const std::vector& variable_indexes, 54 | const std::vector& candidate_values ) const override; 55 | 56 | void conditional_update_data_structures( const std::vector& variables, 57 | int variable_index, 58 | int new_value ) override; 59 | 60 | public: 61 | /*! 62 | * Constructor with a vector of variable IDs. This vector is internally used by ghost::Constraint 63 | * to know what variables from the global variable vector it is handling. 64 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 65 | */ 66 | AllEqual( const std::vector& variables_index ); 67 | 68 | /*! 69 | * Constructor with a vector of variable. 70 | * \param variables a const reference to a vector of variables composing the constraint. 71 | */ 72 | AllEqual( const std::vector& variables ); 73 | }; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /include/global_constraints/all_different.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | #include 34 | 35 | #include "../variable.hpp" 36 | #include "../constraint.hpp" 37 | 38 | namespace ghost 39 | { 40 | namespace global_constraints 41 | { 42 | /*! 43 | * Implementation of the All Different constraint. 44 | * See http://sofdem.github.io/gccat/gccat/Calldifferent.html 45 | */ 46 | class AllDifferent : public Constraint 47 | { 48 | mutable std::map _count; 49 | 50 | double required_error( const std::vector& variables ) const override; 51 | 52 | double optional_delta_error( const std::vector& variables, 53 | const std::vector& variable_indexes, 54 | const std::vector& candidate_values ) const override; 55 | 56 | void conditional_update_data_structures( const std::vector& variables, 57 | int variable_index, 58 | int new_value ) override; 59 | 60 | double binomial_with_2( int value ) const; 61 | 62 | public: 63 | /*! 64 | * Constructor with a vector of variable IDs. This vector is internally used by ghost::Constraint 65 | * to know what variables from the global variable vector it is handling. 66 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 67 | */ 68 | AllDifferent( const std::vector& variables_index ); 69 | 70 | /*! 71 | * Constructor with a vector of variable. 72 | * \param variables a const reference to a vector of variables composing the constraint. 73 | */ 74 | AllDifferent( const std::vector& variables ); 75 | }; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /include/algorithms/variable_heuristic.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "../search_unit_data.hpp" 35 | // #include "../macros.hpp" 36 | #include "../thirdparty/randutils.hpp" 37 | 38 | namespace ghost 39 | { 40 | namespace algorithms 41 | { 42 | /* 43 | * Strategy design pattern to implement variable selection heuristics. 44 | */ 45 | class VariableHeuristic 46 | { 47 | protected: 48 | // Protected string variable for the heuristic name. Used for debug/trace purposes. 49 | std::string name; 50 | 51 | public: 52 | VariableHeuristic( std::string&& name ) 53 | : name( std::move( name ) ) 54 | { } 55 | 56 | // Default virtual destructor. 57 | virtual ~VariableHeuristic() = default; 58 | 59 | // Inline function returning the heuristic name. 60 | inline std::string get_name() const { return name; } 61 | 62 | /* 63 | * Function to select, among a vector of candidates, a variable from which the search algorithm will make a local move. 64 | * \param candidates A const reference to a double vector to be more generic, allowing for instance a vector of errors, rather than a vector of ID, although it would certainly be often the case in practice. 65 | * \param data A reference to the SearchUnitData object containing data about the problem instance and the search state, such as the number of variables and constraints, the current projected error on each variable, etc. 66 | * \param rng A reference to the pseudo-random generator, to avoid recreating such object. 67 | * \return The index of the selected variable in the candidates vector. 68 | */ 69 | virtual int select_variable( const std::vector& candidates, const SearchUnitData& data, randutils::mt19937_rng& rng ) const = 0; 70 | }; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /include/algorithms/error_projection_algorithm.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | #include 34 | 35 | #include "../search_unit_data.hpp" 36 | #include "../constraint.hpp" 37 | #include "../variable.hpp" 38 | 39 | namespace ghost 40 | { 41 | namespace algorithms 42 | { 43 | /* 44 | * Strategy design pattern to implement error projection algorithm. 45 | */ 46 | class ErrorProjection 47 | { 48 | protected: 49 | // Protected string variable for the heuristic name. Used for debug/trace purposes. 50 | std::string name; 51 | 52 | public: 53 | ErrorProjection( std::string&& name ) 54 | : name( std::move( name ) ) 55 | { } 56 | 57 | // Default virtual destructor. 58 | virtual ~ErrorProjection() = default; 59 | 60 | // Inline function returning the algorithm name. 61 | inline std::string get_name() const { return name; } 62 | 63 | // Can be useful to initialize some data structures before computing error projections. 64 | virtual void initialize_data_structures( const SearchUnitData& data ) {}; 65 | 66 | // Will reset data.error_variables and set the element of this vector to their projected cost 67 | virtual void compute_variable_errors( const std::vector& variables, 68 | const std::vector>& constraints, 69 | SearchUnitData& data ) = 0; 70 | 71 | // Incremental update of data.error_variables 72 | virtual void update_variable_errors( const std::vector& variables, 73 | std::shared_ptr constraint, 74 | SearchUnitData& data, 75 | double delta ) = 0; 76 | }; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - 'feature/*' 7 | pull_request: 8 | branches-ignore: 9 | - 'feature/*' 10 | 11 | env: 12 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 13 | BUILD_TYPE: Release 14 | CXX: cl 15 | EXPERIMENTAL: "" 16 | 17 | jobs: 18 | build: 19 | # The CMake configure and build commands are platform agnostic and should work equally 20 | # well on Windows or Mac. You can convert this to a matrix build if you need 21 | # cross-platform coverage. 22 | # See: https://docs.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow#configuring-a-build-matrix 23 | runs-on: windows-latest 24 | 25 | steps: 26 | - uses: actions/checkout@v2 27 | - uses: ilammy/msvc-dev-cmd@v1.4.1 28 | 29 | - name: Install gtest manually 30 | run: git clone https://github.com/google/googletest.git && cd googletest && mkdir build && cd build && cmake .. -DGTEST_CREATE_SHARED_LIBRARY=1 -Dgtest_force_shared_crt=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON && cmake --build . --config Release && cmake --install . --config Release 31 | 32 | - name: Create Build Environment 33 | # Some projects don't allow in-source building, so create a separate build directory 34 | # We'll use this as our working directory for all subsequent commands 35 | run: cmake -E make_directory ${{runner.workspace}}/GHOST/build 36 | 37 | - name: Configure CMake 38 | # Use a cmd shell so we can use the same syntax for environment variable 39 | # access regardless of the host operating system 40 | shell: cmd 41 | working-directory: ${{runner.workspace}}/GHOST/build 42 | # Note the current convention is to use the -S and -B options here to specify source 43 | # and build directories, but this is only available with CMake 3.13 and higher. 44 | # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 45 | run: cmake -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_COMPILER=$CXX $EXPERIMENTAL .. 46 | 47 | - name: Build GHOST 48 | working-directory: ${{runner.workspace}}/GHOST/build 49 | shell: cmd 50 | run: cmake --build . --config Release 51 | 52 | - name: Install GHOST 53 | working-directory: ${{runner.workspace}}/GHOST/build 54 | shell: cmd 55 | run: cmake --install . --config Release --prefix "C:\Program Files (x86)\ghost" 56 | 57 | - name: Build Test 58 | working-directory: ${{runner.workspace}}/GHOST/tests 59 | run: mkdir build && cd build && cmake .. -A "x64" && cmake --build . --config Release 60 | 61 | - name: Run Test 62 | working-directory: ${{runner.workspace}}/GHOST/tests/build 63 | shell: cmd 64 | run: set PATH=C:\Program Files (x86)\ghost\lib\;%PATH% && ctest -C Release 65 | 66 | - name: Build Tutorial Wiki 67 | working-directory: ${{runner.workspace}}/GHOST/tutorial/wiki 68 | run: mkdir -p build && cd build && cmake .. -A "x64" && cmake --build . --config Release 69 | 70 | - name: Build Tutorial Video 71 | working-directory: ${{runner.workspace}}/GHOST/tutorial/video 72 | run: mkdir -p build && cd build && cmake .. -A "x64" && cmake --build . --config Release 73 | -------------------------------------------------------------------------------- /src/global_constraints/linear_equation.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | #include 33 | 34 | #include "global_constraints/linear_equation.hpp" 35 | 36 | using ghost::global_constraints::LinearEquation; 37 | 38 | LinearEquation::LinearEquation( const std::vector& variables_index, double rhs, const std::vector& coefficients ) 39 | : Constraint( variables_index ), 40 | _coefficients( coefficients ), 41 | rhs( rhs ) 42 | { } 43 | 44 | LinearEquation::LinearEquation( const std::vector& variables, double rhs, const std::vector& coefficients ) 45 | : Constraint( variables ), 46 | _coefficients( coefficients ), 47 | rhs( rhs ) 48 | { } 49 | 50 | double LinearEquation::required_error( const std::vector& variables ) const 51 | { 52 | _current_sum = 0.0; 53 | for( size_t i = 0 ; i < variables.size() ; ++i ) 54 | _current_sum += ( _coefficients[i] * variables[i]->get_value() ); 55 | 56 | return compute_error( _current_sum ); 57 | } 58 | 59 | double LinearEquation::optional_delta_error( const std::vector& variables, 60 | const std::vector& variable_indexes, 61 | const std::vector& candidate_values ) const 62 | { 63 | double sum = _current_sum; 64 | 65 | for( size_t i = 0 ; i < variable_indexes.size(); ++i ) 66 | sum += ( _coefficients[ variable_indexes[i] ] * ( candidate_values[ i ] - variables[ variable_indexes[i] ]->get_value() ) ); 67 | 68 | return compute_error( sum ) - get_current_error(); 69 | } 70 | 71 | void LinearEquation::conditional_update_data_structures( const std::vector& variables, int variable_index, int new_value ) 72 | { 73 | _current_sum += _coefficients[ variable_index ] * ( new_value - variables[ variable_index ]->get_value() ); 74 | } 75 | -------------------------------------------------------------------------------- /include/global_constraints/fix_value.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "../variable.hpp" 35 | #include "../constraint.hpp" 36 | 37 | namespace ghost 38 | { 39 | namespace global_constraints 40 | { 41 | /*! 42 | * Implementation of the FixValue constraint, forcing variables in its scope taking a given value. 43 | * 44 | * This constraint must be avoided if possible. If some variables x must be fixed to a value v, it is more efficient 45 | * to directly declare these variables in the ghost::ModelBuilder with a singleton domain {v}. 46 | * However, it makes sense to use this contraint to fix the value of some variables in permutation problems. 47 | */ 48 | class FixValue : public Constraint 49 | { 50 | int _value; 51 | 52 | double required_error( const std::vector& variables ) const override; 53 | double optional_delta_error( const std::vector& variables, 54 | const std::vector& variable_indexes, 55 | const std::vector& candidate_values ) const override; 56 | 57 | public: 58 | /*! 59 | * Constructor with a vector of variable IDs. This vector is internally used by ghost::Constraint 60 | * to know what variables from the global variable vector it is handling. 61 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 62 | * \param value a value integer such that all variables in the scope must be equals to this value. 63 | */ 64 | FixValue( const std::vector& variables_index, int value ); 65 | 66 | /*! 67 | * Constructor with a vector of variable. 68 | * \param variables a const reference to a vector of variables composing the constraint. 69 | * \param value a value integer such that all variables in the scope must be equals to this value. 70 | */ 71 | FixValue( const std::vector& variables, int value ); 72 | }; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: MacOS 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - 'feature/*' 7 | pull_request: 8 | branches-ignore: 9 | - 'feature/*' 10 | 11 | env: 12 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 13 | BUILD_TYPE: Release 14 | CXX: clang++ 15 | EXPERIMENTAL: "" 16 | 17 | jobs: 18 | build: 19 | # The CMake configure and build commands are platform agnostic and should work equally 20 | # well on Windows or Mac. You can convert this to a matrix build if you need 21 | # cross-platform coverage. 22 | # See: https://docs.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow#configuring-a-build-matrix 23 | runs-on: macos-latest 24 | 25 | steps: 26 | - uses: actions/checkout@v2 27 | 28 | - name: Update clang 29 | run: | 30 | #brew update 31 | #brew upgrade 32 | #brew upgrade llvm 33 | export CXX="/usr/local/opt/llvm/bin/clang++" 34 | 35 | - name: Install gtest manually 36 | run: git clone https://github.com/google/googletest.git && cd googletest && mkdir build && cd build && cmake .. && make && sudo make install 37 | 38 | - name: Create Build Environment 39 | # Some projects don't allow in-source building, so create a separate build directory 40 | # We'll use this as our working directory for all subsequent commands 41 | run: cmake -E make_directory ${{runner.workspace}}/GHOST/build 42 | 43 | - name: Configure CMake 44 | # Use a bash shell so we can use the same syntax for environment variable 45 | # access regardless of the host operating system 46 | shell: bash 47 | working-directory: ${{runner.workspace}}/GHOST/build 48 | # Note the current convention is to use the -S and -B options here to specify source 49 | # and build directories, but this is only available with CMake 3.13 and higher. 50 | # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 51 | run: cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_COMPILER=$CXX $EXPERIMENTAL .. 52 | 53 | - name: Build GHOST 54 | working-directory: ${{runner.workspace}}/GHOST/build 55 | shell: bash 56 | run: make 57 | 58 | - name: Install GHOST 59 | working-directory: ${{runner.workspace}}/GHOST/build 60 | shell: bash 61 | run: sudo make install && sudo update_dyld_shared_cache 62 | 63 | - name: Build Test 64 | working-directory: ${{runner.workspace}}/GHOST/tests 65 | run: export CXXFLAGS=-isystem\ /usr/local/include && export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib" && cp /usr/local/lib/libgtest*.a . && mkdir build && cd build && cmake .. && make 66 | 67 | - name: Run Test 68 | working-directory: ${{runner.workspace}}/GHOST/tests/build 69 | shell: bash 70 | run: ctest 71 | 72 | - name: Build Tutorial Wiki 73 | working-directory: ${{runner.workspace}}/GHOST/tutorial/wiki 74 | run: export CXXFLAGS=-isystem\ /usr/local/include && export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib" && cp /usr/local/lib/libgtest*.a . && mkdir -p build && cd build && cmake .. && make 75 | 76 | - name: Build Tutorial Video 77 | working-directory: ${{runner.workspace}}/GHOST/tutorial/video 78 | run: export CXXFLAGS=-isystem\ /usr/local/include && export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib" && cp /usr/local/lib/libgtest*.a . && mkdir -p build && cd build && cmake .. && make 79 | -------------------------------------------------------------------------------- /src/algorithms/adaptive_search_value_heuristic.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | 33 | #include "algorithms/adaptive_search_value_heuristic.hpp" 34 | 35 | using ghost::algorithms::AdaptiveSearchValueHeuristic; 36 | using ghost::SearchUnitData; 37 | using ghost::Model; 38 | 39 | AdaptiveSearchValueHeuristic::AdaptiveSearchValueHeuristic() 40 | : ValueHeuristic( "Adaptive Search" ) 41 | { } 42 | 43 | int AdaptiveSearchValueHeuristic::select_value( int variable_to_change, 44 | const SearchUnitData& data, 45 | const Model& model, 46 | const std::map>& delta_errors, 47 | double& min_conflict, 48 | randutils::mt19937_rng& rng ) const 49 | { 50 | std::vector candidate_values; 51 | std::map cumulated_delta_errors; 52 | for( const auto& deltas : delta_errors ) 53 | cumulated_delta_errors[ deltas.first ] = std::accumulate( deltas.second.begin(), deltas.second.end(), 0.0 ); 54 | 55 | for( const auto& deltas : cumulated_delta_errors ) 56 | { 57 | if( min_conflict > deltas.second ) 58 | { 59 | candidate_values.clear(); 60 | candidate_values.push_back( deltas.first ); 61 | min_conflict = deltas.second; 62 | } 63 | else 64 | if( min_conflict == deltas.second ) 65 | candidate_values.push_back( deltas.first ); 66 | } 67 | 68 | if( candidate_values.empty() ) 69 | return variable_to_change; 70 | 71 | // if we deal with an optimization problem, find the value minimizing to objective function 72 | if( data.is_optimization ) 73 | { 74 | if( model.permutation_problem ) 75 | return static_cast( model.objective->heuristic_value_permutation( variable_to_change, candidate_values, rng ) ); 76 | else 77 | return model.objective->heuristic_value( variable_to_change, candidate_values, rng ); 78 | } 79 | else 80 | return rng.pick( candidate_values ); 81 | } 82 | -------------------------------------------------------------------------------- /include/global_constraints/linear_equation.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "../variable.hpp" 35 | #include "../constraint.hpp" 36 | 37 | namespace ghost 38 | { 39 | namespace global_constraints 40 | { 41 | /* 42 | * Abstract class for Linear Equation constraints 43 | */ 44 | class LinearEquation : public Constraint 45 | { 46 | std::vector _coefficients; 47 | mutable double _current_sum; 48 | 49 | protected: 50 | double rhs; 51 | 52 | /* 53 | * Constructor with a vector of variable IDs. This vector is internally used by ghost::Constraint 54 | * to know what variables from the global variable vector it is handling. 55 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 56 | * \param rhs the right-hand side real number of the equation. 57 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 58 | */ 59 | LinearEquation( const std::vector& variables_index, double rhs, const std::vector& coefficients ); 60 | 61 | /* 62 | * Constructor with a vector of variable. 63 | * \param variables a const reference to a vector of variables composing the constraint. 64 | * \param rhs the right-hand side real number of the equation. 65 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 66 | */ 67 | LinearEquation( const std::vector& variables, double rhs, const std::vector& coefficients ); 68 | 69 | virtual double compute_error( double sum ) const = 0; 70 | 71 | double required_error( const std::vector& variables ) const override; 72 | 73 | double optional_delta_error( const std::vector& variables, 74 | const std::vector& variable_indexes, 75 | const std::vector& candidate_values ) const override; 76 | 77 | void conditional_update_data_structures( const std::vector& variables, int variable_id, int new_value ) override; 78 | 79 | }; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /include/options.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | #include 34 | 35 | #include "print.hpp" 36 | 37 | namespace ghost 38 | { 39 | /*! 40 | * Options is a structure containing all optional arguments for Solver::solve. 41 | * 42 | * \sa Print 43 | */ 44 | struct Options 45 | { 46 | bool custom_starting_point; //!< To force starting the search on a custom variables assignment. 47 | bool resume_search; //!< Allowing stop-and-resume computation. 48 | bool parallel_runs; //!< To enable parallel runs of the solver. Using all available physical cores if number_threads is not specified. 49 | bool enable_optimization_guidance; //!< For optimization problems, consider the optimization cost as a tie-breaker for satisfaction plateau. 50 | int number_threads; //!< Number of threads the solver will use for the search. 51 | std::shared_ptr print; //!< Allowing custom solution print (by derivating a class from ghost::Print) 52 | int tabu_time_local_min; //!< Number of local moves a variable of a local minimum is marked tabu. 53 | int tabu_time_selected; //!< Number of local moves a selected variable is marked tabu. 54 | int percent_chance_force_trying_on_plateau; //!< Percentage of chance to force trying another variable rather than doing a move on a plateau. 55 | int reset_threshold; //!< Number of variables marked as tabu required to trigger a reset. 56 | int restart_threshold; //!< Trigger a restart every 'restart_threshold' reset. Set to 0 to never trigger restarts. 57 | int number_variables_to_reset; //!< Number of variables to randomly change the value at each reset. 58 | int number_start_samplings; //!< Number of variable assignments the solver randomly draw, if custom_starting_point and resume_search are false. 59 | 60 | //! Unique constructor 61 | Options(); 62 | 63 | //! Default destructor 64 | ~Options() = default; 65 | 66 | //! Unique copy constructor 67 | Options( const Options& other ); 68 | 69 | //! Unique move constructor 70 | Options( Options&& other ); 71 | 72 | /*! 73 | * Unique copy assign operator 74 | * 75 | * No move assign operator on purpose (yes, we violate the rule of 5 here). 76 | */ 77 | Options& operator=( Options other ); 78 | }; 79 | } 80 | -------------------------------------------------------------------------------- /tutorial/wiki/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.1) 2 | project (ghost_tutorial_wiki) 3 | 4 | set( CMAKE_VERBOSE_MAKEFILE on ) 5 | 6 | # require a C++17-capable compiler 7 | include(CheckCXXCompilerFlag) 8 | CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17) 9 | CHECK_CXX_COMPILER_FLAG("-std=c++1z" COMPILER_SUPPORTS_CXX1Z) 10 | CHECK_CXX_COMPILER_FLAG("/std:c++17" COMPILER_SUPPORTS_CXX17_WIN) 11 | if(COMPILER_SUPPORTS_CXX17) 12 | set(CMAKE_CXX_FLAGS "-std=c++17") 13 | elseif(COMPILER_SUPPORTS_CXX1Z) 14 | set(CMAKE_CXX_FLAGS "-std=c++1z") 15 | elseif(COMPILER_SUPPORTS_CXX17_WIN) 16 | set(CMAKE_CXX_FLAGS "/std:c++17") 17 | else() 18 | message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++17 support. Please use a different C++ compiler.") 19 | endif() 20 | 21 | if(WIN32) 22 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive-") 23 | INCLUDE_DIRECTORIES("C:/Program Files (x86)/ghost/include") 24 | link_directories("C:/Program Files (x86)/ghost/lib") 25 | else() 26 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") 27 | endif() 28 | 29 | if(APPLE) 30 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem\ /usr/local/include") 31 | endif() 32 | 33 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 34 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fsanitize=address,undefined,leak") 35 | set(CMAKE_EXE_FLAGS_DEBUG "-fsanitize=address,undefined,leak") 36 | endif() 37 | 38 | ## These two lines are the reason why we need CMake version 3.1.0+ 39 | set(THREADS_PREFER_PTHREAD_FLAG ON) 40 | find_package(Threads REQUIRED) 41 | 42 | # add the targets 43 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) 44 | 45 | add_executable( tutorial_csp src/constraint_capacity.cpp src/constraint_at_least.cpp src/model_builder_sat.cpp src/main.cpp ) 46 | add_executable( tutorial_efsp src/constraint_capacity_ef.cpp src/constraint_at_least_ef.cpp src/model_builder_sat.cpp src/main.cpp ) 47 | add_executable( tutorial_cop src/constraint_capacity.cpp src/objective_max_value.cpp src/model_builder_opti.cpp src/main.cpp ) 48 | add_executable( tutorial_efop src/constraint_capacity_ef.cpp src/objective_max_value.cpp src/model_builder_opti.cpp src/main.cpp ) 49 | 50 | target_compile_definitions( tutorial_cop PUBLIC -DOPTIMIZATION ) 51 | target_compile_definitions( tutorial_efop PUBLIC -DOPTIMIZATION ) 52 | 53 | if(APPLE) 54 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 55 | target_link_libraries(tutorial_csp /usr/local/lib/libghost_staticd.a Threads::Threads) 56 | target_link_libraries(tutorial_cop /usr/local/lib/libghost_staticd.a Threads::Threads) 57 | target_link_libraries(tutorial_efsp /usr/local/lib/libghost_staticd.a Threads::Threads) 58 | target_link_libraries(tutorial_efop /usr/local/lib/libghost_staticd.a Threads::Threads) 59 | else() 60 | target_link_libraries(tutorial_csp /usr/local/lib/libghost_static.a Threads::Threads) 61 | target_link_libraries(tutorial_cop /usr/local/lib/libghost_static.a Threads::Threads) 62 | target_link_libraries(tutorial_efsp /usr/local/lib/libghost_static.a Threads::Threads) 63 | target_link_libraries(tutorial_efop /usr/local/lib/libghost_static.a Threads::Threads) 64 | endif() 65 | else() 66 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 67 | target_link_libraries(tutorial_csp ghost Threads::Threads) 68 | target_link_libraries(tutorial_cop ghost Threads::Threads) 69 | target_link_libraries(tutorial_efsp ghost Threads::Threads) 70 | target_link_libraries(tutorial_efop ghost Threads::Threads) 71 | else() 72 | target_link_libraries(tutorial_csp ghost_static Threads::Threads) 73 | target_link_libraries(tutorial_cop ghost_static Threads::Threads) 74 | target_link_libraries(tutorial_efsp ghost_static Threads::Threads) 75 | target_link_libraries(tutorial_efop ghost_static Threads::Threads) 76 | endif() 77 | endif() 78 | -------------------------------------------------------------------------------- /src/algorithms/antidote_search_value_heuristic.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | 33 | #include "algorithms/antidote_search_value_heuristic.hpp" 34 | #include "thirdparty/randutils.hpp" 35 | 36 | using ghost::algorithms::AntidoteSearchValueHeuristic; 37 | 38 | AntidoteSearchValueHeuristic::AntidoteSearchValueHeuristic() 39 | : ValueHeuristic( "Antidote Search" ) 40 | { } 41 | 42 | int AntidoteSearchValueHeuristic::select_value( int variable_to_change, 43 | const SearchUnitData& data, 44 | const Model& model, 45 | const std::map>& delta_errors, 46 | double& min_conflict, 47 | randutils::mt19937_rng& rng ) const 48 | { 49 | std::vector cumulated_delta_errors( delta_errors.size() ); 50 | std::vector cumulated_delta_errors_for_distribution( delta_errors.size() ); 51 | std::vector cumulated_delta_errors_variable_index_correspondance( delta_errors.size() ); // longest variable name ever 52 | 53 | int index = 0; 54 | 55 | for( const auto& deltas : delta_errors ) 56 | { 57 | cumulated_delta_errors[ index ] = std::accumulate( deltas.second.begin(), deltas.second.end(), 0.0 ); 58 | cumulated_delta_errors_variable_index_correspondance[ index ] = deltas.first; 59 | ++index; 60 | } 61 | 62 | std::transform( cumulated_delta_errors.begin(), 63 | cumulated_delta_errors.end(), 64 | cumulated_delta_errors_for_distribution.begin(), 65 | []( auto delta ){ if( delta >= 0) return 0.0; else return -delta; } ); 66 | 67 | if( *std::max_element( cumulated_delta_errors_for_distribution.begin(), cumulated_delta_errors_for_distribution.end() ) == 0.0 ) 68 | index = rng.uniform( 0, static_cast( delta_errors.size() ) - 1 ); 69 | else 70 | index = rng.variate( cumulated_delta_errors_for_distribution.begin(), cumulated_delta_errors_for_distribution.end() ); 71 | 72 | min_conflict = cumulated_delta_errors[ index ]; 73 | 74 | return cumulated_delta_errors_variable_index_correspondance[ index ]; 75 | } 76 | -------------------------------------------------------------------------------- /include/algorithms/value_heuristic.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | #include 34 | 35 | #include "../search_unit_data.hpp" 36 | // #include "../macros.hpp" 37 | #include "../thirdparty/randutils.hpp" 38 | 39 | namespace ghost 40 | { 41 | namespace algorithms 42 | { 43 | /* 44 | * Strategy design pattern to implement variable selection heuristics. 45 | */ 46 | class ValueHeuristic 47 | { 48 | protected: 49 | // Protected string variable for the heuristic name. Used for debug/trace purposes. 50 | std::string name; 51 | 52 | public: 53 | ValueHeuristic( std::string&& name ) 54 | : name( std::move( name ) ) 55 | { } 56 | 57 | // Default virtual destructor. 58 | virtual ~ValueHeuristic() = default; 59 | 60 | // Inline function returning the heuristic name. 61 | inline std::string get_name() const { return name; } 62 | 63 | /* 64 | * Function to select a value to assign to the variable currently selected by the search algorithm to make a local move. 65 | * \param variable_to_change The index of the variable currently selected by the search algorithm. 66 | * \param data A reference to the SearchUnitData object containing data about the problem instance and the search state, such as the number of variables and constraints, the current projected error on each variable, etc. 67 | * \param model A reference to the problem model, to get access to the objective function for instance. 68 | * \param delta_errors A reference to a map to have the list of delta errors on each variable. 69 | * \param min_conflict A non-constant reference to get the minimal conflict value after calling this function. 70 | * \param rng A reference to the pseudo-random generator, to avoid recreating such object. 71 | * \return The selected value to be assigned to variable_to_change (or the index of a variable in case of permutation moves). 72 | */ 73 | virtual int select_value( int variable_to_change, 74 | const SearchUnitData& data, 75 | const Model& model, 76 | const std::map>& delta_errors, 77 | double& min_conflict, 78 | randutils::mt19937_rng& rng ) const = 0; 79 | }; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /include/global_constraints/linear_equation_g.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "linear_equation.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace global_constraints 39 | { 40 | /*! 41 | * Implementation of the Linear Equation constraint with greater than, i.e., the Scalar Product constraint with the atom '>'. 42 | * See http://sofdem.github.io/gccat/gccat/Cscalar_product.html 43 | */ 44 | class LinearEquationG : public LinearEquation 45 | { 46 | double compute_error( double sum ) const override; 47 | 48 | public: 49 | /*! 50 | * Constructor with a vector of variable IDs. This vector is internally used by ghost::Constraint 51 | * to know what variables from the global variable vector it is handling. 52 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 53 | * \param rhs the right-hand side real number of the equation. 54 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 55 | */ 56 | LinearEquationG( const std::vector& variables_index, double rhs, const std::vector& coefficients ); 57 | 58 | /*! 59 | * Constructor with a vector of variable IDs. This constructor calls LinearEquationG( const std::vector& index, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 60 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 61 | * \param rhs the right-hand side real number of the equation. 62 | */ 63 | LinearEquationG( const std::vector& variables_index, double rhs ); 64 | 65 | /*! 66 | * Constructor with a vector of variable. 67 | * \param variables a const reference to a vector of variables composing the constraint. 68 | * \param rhs the right-hand side real number of the equation. 69 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 70 | */ 71 | LinearEquationG( const std::vector& variables, double rhs, const std::vector& coefficients ); 72 | 73 | /*! 74 | * Constructor with a vector of variable. This constructor calls LinearEquationG( const std::vector& variables, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 75 | * \param variables a const reference to a vector of variables composing the constraint. 76 | * \param rhs the right-hand side real number of the equation. 77 | */ 78 | LinearEquationG( const std::vector& variables, double rhs ); 79 | }; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /include/global_constraints/linear_equation_l.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "linear_equation.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace global_constraints 39 | { 40 | /*! 41 | * Implementation of the Linear Equation constraint with less than, i.e., the Scalar Product constraint with the atom '<'. 42 | * See http://sofdem.github.io/gccat/gccat/Cscalar_product.html 43 | */ 44 | class LinearEquationL : public LinearEquation 45 | { 46 | double compute_error( double sum ) const override; 47 | 48 | public: 49 | /*! 50 | * Constructor with a vector of variable IDs. This vector is internally used by ghost::Constraint 51 | * to know what variables from the global variable vector it is handling. 52 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 53 | * \param rhs the right-hand side real number of the equation. 54 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 55 | */ 56 | LinearEquationL( const std::vector& variables_index, double rhs, const std::vector& coefficients ); 57 | 58 | /*! 59 | * Constructor with a vector of variable IDs. This constructor calls LinearEquationL( const std::vector& index, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 60 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 61 | * \param rhs the right-hand side real number of the equation. 62 | */ 63 | LinearEquationL( const std::vector& variables_index, double rhs ); 64 | 65 | /*! 66 | * Constructor with a vector of variable. 67 | * \param variables a const reference to a vector of variables composing the constraint. 68 | * \param rhs the right-hand side real number of the equation. 69 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 70 | */ 71 | LinearEquationL( const std::vector& variables, double rhs, const std::vector& coefficients ); 72 | 73 | /*! 74 | * Constructor with a vector of variable. This constructor calls LinearEquationL( const std::vector& variables, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 75 | * \param variables a const reference to a vector of variables composing the constraint. 76 | * \param rhs the right-hand side real number of the equation. 77 | */ 78 | LinearEquationL( const std::vector& variables, double rhs ); 79 | }; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /include/global_constraints/linear_equation_eq.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "linear_equation.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace global_constraints 39 | { 40 | /*! 41 | * Implementation of the Linear Equation constraint with equality, i.e., the Scalar Product constraint with the equality atom '='. 42 | * See http://sofdem.github.io/gccat/gccat/Cscalar_product.html 43 | */ 44 | class LinearEquationEq : public LinearEquation 45 | { 46 | double compute_error( double sum ) const override; 47 | 48 | public: 49 | /*! 50 | * Constructor with a vector of variable IDs. This vector is internally used by ghost::Constraint 51 | * to know what variables from the global variable vector it is handling. 52 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 53 | * \param rhs the right-hand side real number of the equation. 54 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 55 | */ 56 | LinearEquationEq( const std::vector& variables_index, double rhs, const std::vector& coefficients ); 57 | 58 | /*! 59 | * Constructor with a vector of variable IDs. This constructor calls LinearEquationEq( const std::vector& index, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 60 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 61 | * \param rhs the right-hand side real number of the equation. 62 | */ 63 | LinearEquationEq( const std::vector& variables_index, double rhs ); 64 | 65 | /*! 66 | * Constructor with a vector of variable. 67 | * \param variables a const reference to a vector of variables composing the constraint. 68 | * \param rhs the right-hand side real number of the equation. 69 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 70 | */ 71 | LinearEquationEq( const std::vector& variables, double rhs, const std::vector& coefficients ); 72 | 73 | /*! 74 | * Constructor with a vector of variable. This constructor calls LinearEquationEq( const std::vector& variables, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 75 | * \param variables a const reference to a vector of variables composing the constraint. 76 | * \param rhs the right-hand side real number of the equation. 77 | */ 78 | LinearEquationEq( const std::vector& variables, double rhs ); 79 | }; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /include/global_constraints/linear_equation_neq.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "linear_equation.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace global_constraints 39 | { 40 | /*! 41 | * Implementation of the Linear Equation constraint with different, i.e., the Scalar Product constraint with the atom '≠'. 42 | * See http://sofdem.github.io/gccat/gccat/Cscalar_product.html 43 | */ 44 | class LinearEquationNeq : public LinearEquation 45 | { 46 | double compute_error( double sum ) const override; 47 | 48 | public: 49 | /*! 50 | * Constructor with a vector of variable IDs. This vector is internally used by ghost::Constraint 51 | * to know what variables from the global variable vector it is handling. 52 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 53 | * \param rhs the right-hand side real number of the equation. 54 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 55 | */ 56 | LinearEquationNeq( const std::vector& variables_index, double rhs, const std::vector& coefficients ); 57 | 58 | /*! 59 | * Constructor with a vector of variable IDs. This constructor calls LinearEquationNeq( const std::vector& index, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 60 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 61 | * \param rhs the right-hand side real number of the equation. 62 | */ 63 | LinearEquationNeq( const std::vector& variables_index, double rhs ); 64 | 65 | /*! 66 | * Constructor with a vector of variable. 67 | * \param variables a const reference to a vector of variables composing the constraint. 68 | * \param rhs the right-hand side real number of the equation. 69 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 70 | */ 71 | LinearEquationNeq( const std::vector& variables, double rhs, const std::vector& coefficients ); 72 | 73 | /*! 74 | * Constructor with a vector of variable. This constructor calls LinearEquationNeq( const std::vector& variables, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 75 | * \param variables a const reference to a vector of variables composing the constraint. 76 | * \param rhs the right-hand side real number of the equation. 77 | */ 78 | LinearEquationNeq( const std::vector& variables, double rhs ); 79 | }; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /include/global_constraints/linear_equation_leq.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "linear_equation.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace global_constraints 39 | { 40 | /*! 41 | * Implementation of the Linear Equation constraint with less than or equals to, i.e., the Scalar Product constraint with the atom '≤'. 42 | * See http://sofdem.github.io/gccat/gccat/Cscalar_product.html 43 | */ 44 | class LinearEquationLeq : public LinearEquation 45 | { 46 | double compute_error( double sum ) const override; 47 | 48 | public: 49 | /*! 50 | * Constructor with a vector of variable IDs. This vector is internally used by ghost::Constraint 51 | * to know what variables from the global variable vector it is handling. 52 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 53 | * \param rhs the right-hand side real number of the equation. 54 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 55 | */ 56 | LinearEquationLeq( const std::vector& variables_index, double rhs, const std::vector& coefficients ); 57 | 58 | /*! 59 | * Constructor with a vector of variable IDs. This constructor calls LinearEquationLeq( const std::vector& index, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 60 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 61 | * \param rhs the right-hand side real number of the equation. 62 | */ 63 | LinearEquationLeq( const std::vector& variables_index, double rhs ); 64 | 65 | /*! 66 | * Constructor with a vector of variable. 67 | * \param variables a const reference to a vector of variables composing the constraint. 68 | * \param rhs the right-hand side real number of the equation. 69 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 70 | */ 71 | LinearEquationLeq( const std::vector& variables, double rhs, const std::vector& coefficients ); 72 | 73 | /*! 74 | * Constructor with a vector of variable. This constructor calls LinearEquationLeq( const std::vector& variables, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 75 | * \param variables a const reference to a vector of variables composing the constraint. 76 | * \param rhs the right-hand side real number of the equation. 77 | */ 78 | LinearEquationLeq( const std::vector& variables, double rhs ); 79 | }; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /include/global_constraints/linear_equation_geq.hpp: -------------------------------------------------------------------------------- 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 | #pragma once 31 | 32 | #include 33 | 34 | #include "linear_equation.hpp" 35 | 36 | namespace ghost 37 | { 38 | namespace global_constraints 39 | { 40 | /*! 41 | * Implementation of the Linear Equation constraint with greater than or equals to, i.e., the Scalar Product constraint with the atom '≥'. 42 | * See http://sofdem.github.io/gccat/gccat/Cscalar_product.html 43 | */ 44 | class LinearEquationGeq : public LinearEquation 45 | { 46 | double compute_error( double sum ) const override; 47 | 48 | public: 49 | /*! 50 | * Constructor with a vector of variable IDs. This vector is internally used by ghost::Constraint 51 | * to know what variables from the global variable vector it is handling. 52 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 53 | * \param rhs the right-hand side real number of the equation. 54 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 55 | */ 56 | LinearEquationGeq( const std::vector& variables_index, double rhs, const std::vector& coefficients ); 57 | 58 | /*! 59 | * Constructor with a vector of variable IDs. This constructor calls LinearEquationGeq( const std::vector& index, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 60 | * \param variables_index a const reference to a vector of IDs of variables composing the constraint. 61 | * \param rhs the right-hand side real number of the equation. 62 | */ 63 | LinearEquationGeq( const std::vector& variables_index, double rhs ); 64 | 65 | /*! 66 | * Constructor with a vector of variable. 67 | * \param variables a const reference to a vector of variables composing the constraint. 68 | * \param rhs the right-hand side real number of the equation. 69 | * \param coefficients the vector of real numbers coefficients for each variable of the equation. 70 | */ 71 | LinearEquationGeq( const std::vector& variables, double rhs, const std::vector& coefficients ); 72 | 73 | /*! 74 | * Constructor with a vector of variable. This constructor calls LinearEquationGeq( const std::vector& variables, double rhs, const std::vector& coefficients), with all coefficients set to 1.0. 75 | * \param variables a const reference to a vector of variables composing the constraint. 76 | * \param rhs the right-hand side real number of the equation. 77 | */ 78 | LinearEquationGeq( const std::vector& variables, double rhs ); 79 | }; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/global_constraints/all_equal.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "global_constraints/all_equal.hpp" 36 | 37 | using ghost::global_constraints::AllEqual; 38 | 39 | AllEqual::AllEqual( const std::vector& variables_index ) 40 | : Constraint( variables_index ) 41 | { } 42 | 43 | AllEqual::AllEqual( const std::vector& variables ) 44 | : Constraint( variables ) 45 | { } 46 | 47 | double AllEqual::required_error( const std::vector& variables ) const 48 | { 49 | _count.clear(); 50 | 51 | for( auto v : variables ) 52 | if( _count.find( v->get_value() ) == _count.end() ) 53 | _count[ v->get_value() ] = 1; 54 | else 55 | _count[ v->get_value() ] = _count[ v->get_value() ] + 1; 56 | 57 | auto max = std::max_element( _count.begin(), _count.end(), [](const auto& c1, const auto& c2){ return c1.second < c2.second; } ); 58 | 59 | return static_cast( variables.size() ) - max->second; 60 | } 61 | 62 | double AllEqual::optional_delta_error( const std::vector& variables, const std::vector& variable_indexes, const std::vector& candidate_values ) const 63 | { 64 | // Warning: we may have several values with the same maximal count. How to handle that in a smart way? 65 | 66 | auto copy_count( _count ); 67 | auto max = std::max_element( _count.begin(), _count.end(), [](const auto& c1, const auto& c2){ return c1.second < c2.second; } ); 68 | 69 | //int number_substraction = std::count( variable_indexes.begin(), variable_indexes.end(), [&](const auto& i){ return variables[ i ]->get_value() == max->first; } ); 70 | //int number_addition = std::count( candidate_values.begin(), candidate_values.end(), [&](const int v){ return v == max->first; } ); 71 | 72 | for( int i = 0 ; i < static_cast( variable_indexes.size() ) ; ++i ) 73 | { 74 | copy_count[ variables[ variable_indexes[ i ] ]->get_value() ] = copy_count[ variables[ variable_indexes[ i ] ]->get_value() ] - 1; 75 | if( copy_count.count( candidate_values[ i ] ) == 0 ) 76 | copy_count[ candidate_values[ i ] ] = 1; 77 | else 78 | copy_count[ candidate_values[ i ] ] = copy_count[ candidate_values[ i ] ] + 1; 79 | } 80 | 81 | auto max_bis = std::max_element( copy_count.begin(), copy_count.end(), [](const auto& c1, const auto& c2){ return c1.second < c2.second; } ); 82 | 83 | return static_cast( max->second - max_bis->second ); 84 | } 85 | 86 | void AllEqual::conditional_update_data_structures( const std::vector& variables, int variable_index, int new_value ) 87 | { 88 | _count[ variables[ variable_index ]->get_value() ] = _count[ variables[ variable_index ]->get_value() ] - 1; 89 | 90 | if( _count.count( new_value ) == 0 ) 91 | _count[ new_value ] = 1; 92 | else 93 | _count[ new_value ] = _count[ new_value ] + 1; 94 | } 95 | -------------------------------------------------------------------------------- /ChangeLog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file, since GHOST 2.0.0. 4 | 5 | ## [3.2.0] - 2025-06-04 6 | - Changed `Options.percent_chance_escape_plateau` with `Options.percent_chance_force_trying_on_plateau`, as well as some printed traces. 7 | - Add `Options.enable_optimization_guidance` to enable (default) or disable the usage of the objective function as a tie-breaker for satisfaction plateau. 8 | 9 | ## [3.1.0] - 2024-03-11 10 | - Add Random Walk and Hill Climbing as search algorithms, for landscape analysis. 11 | - Minor changes in the global solver algorithm, such as removing the probability to force tabu-marking a variable. 12 | 13 | ## [3.0.2] - 2023-09-26 14 | - Fix a mistake with maximization objectives in the complete solver, and a bug that happened with the compiler Clang. 15 | 16 | ## [3.0.1] - 2023-09-21 17 | - Hotfix adding a method to call the complete solver with default options. 18 | 19 | ## [3.0.0] - 2023-09-20 20 | - Add a complete solver within the framework, implementing the Arc Consistency 3 algorithm and aiming to find all solutions of a problem instance. 21 | - Changed the interface `Solver::solve` -> `Solver::fast_search`, to be coherent with the new `Solver::complete_search` 22 | 23 | ## [2.8.2] - 2023-07-21 24 | - Fix a mistake in the final cost of an objective function to maximize, where the value v needed to be reset to the opposite value -v. 25 | 26 | ## [2.8.1] - 2023-06-22 27 | - Change Cmake and build.sh to compile the library for different Android architectures. 28 | 29 | ## [2.8.0] - 2023-05-31 30 | - Now allow modeling pure optimization problems. 31 | 32 | ## [2.7.0] - 2023-05-30 33 | - Slight memory management improvement, by pre-allocating memory during the search. 34 | 35 | ## [2.6.0] - 2023-01-24 36 | - Add the AllEqual global constraint. 37 | 38 | ## [2.5.2] - 2022-09-21 39 | - Add virtual destructors in base classes. This fixes a problem on OSX. 40 | 41 | ## [2.5.1] - 2022-07-11 42 | - Fix minor forgettings (Doxygen file, README, ...). 43 | 44 | ## [2.5.0] - 2022-07-11 45 | - Add all possible linear equation global constraints. 46 | 47 | ## [2.4.0] - 2022-07-08 48 | - Error projection is now implemented following the Strategy pattern. 49 | 50 | ## [2.3.1] - 2022-06-29 51 | - Fix an error in the AllDifferent global constraint. 52 | - Add a constructor taking an argument std::vector for each global constraint. 53 | 54 | ## [2.3.0] - 2022-06-23 55 | - Add first global constraints: AllDifferent, FixValue and LinearEquation. 56 | - Search unit inner data have been moved into an object. 57 | - Variable and value selection heuristics are now implemented following the Strategy pattern. 58 | - Code optimization (avoiding copies of randutils::mt19937_rng objects) 59 | - Change the file tree 60 | 61 | ## [2.2.1] - 2021-12-13 62 | - Fix mistakes within the search unit when one starts with a custom sector of variable values. 63 | - Fix a mistake in Options documentation. 64 | 65 | ## [2.2.0] - 2021-11-10 66 | - The default number of threads is now the number of physical CPU cores (half the number of virtual cores for CPUs with hyper-threading). 67 | - Add in `Options` a parameter to set the percentage of chance to escape a plateau rather than exploring it. 68 | - Rename `Options::percent_to_reset` to `Options::number_variables_to_reset`. 69 | 70 | ## [2.1.2] - 2021-11-02 71 | - Enable the include and lib files installation on Windows with Visual Studio. 72 | 73 | ## [2.1.1] - 2021-10-18 74 | - Fix a bug in the solver when some variables are assigned to any constraints. 75 | - Fix a mistake in Objective in case some vectors are empty. 76 | 77 | ## [2.1.0] - 2021-10-04 78 | This is a minor version change due to some interface modifications. 79 | 80 | - Permutation problem declaration is now done in the `ModelBuilder` constructor. 81 | - Remove `Objective::expert_postprocess_satisfaction` and change the name and the interface of `Objective::expert_postprocess` (previously `Objective::expert_postprocess_optimization`) 82 | 83 | ## [2.0.1] - 2021-09-30 84 | - Fix a bad implementation of the copy-and-swap idiom in ghost::Options 85 | - Fix some typos in the Solver screen outputs when the macro GHOST_BENCH is declared 86 | - Remove unnecessary whitespaces 87 | 88 | ## [2.0.0] - 2021-09-29 89 | 90 | Major refactoring of version 1.0.1 91 | - deep interface modification 92 | - performance improvements 93 | - new features (parallel search, ...) 94 | -------------------------------------------------------------------------------- /include/search_unit_data.hpp: -------------------------------------------------------------------------------- 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 34 | #include 35 | 36 | #include "model.hpp" 37 | 38 | namespace ghost 39 | { 40 | /* 41 | * SearchUnitData is the object containing inner data for search units. 42 | */ 43 | struct SearchUnitData 44 | { 45 | // General data about the curent model 46 | int number_variables; 47 | int number_constraints; 48 | bool is_optimization; 49 | 50 | // Matrix to know which constraints contain a given variable 51 | // matrix_var_ctr[ variable_id ] = { constraint_id_1, ..., constraint_id_k } 52 | std::vector > matrix_var_ctr; 53 | 54 | // To know how many iterations each variable is still marked as tabu 55 | // tabu_list[2] = 3 --> variable with id=2 is marked tabu for the next 3 iterations of the search process 56 | // tabu_list[6] = 0 --> variable with id=6 is not marked as tabu (therefore, it is selectable during the search process) 57 | std::vector tabu_list; 58 | 59 | // Variables about errors of the variables, and global satisfaction/optimization errors 60 | std::vector error_variables; 61 | double best_sat_error; 62 | double best_opt_cost; 63 | double current_sat_error; 64 | double current_opt_cost; 65 | 66 | // Statistics about the current run 67 | int restarts; 68 | int resets; 69 | int local_moves; 70 | int search_iterations; 71 | int local_minimum; 72 | int plateau_moves; 73 | int plateau_force_trying_another_variable; 74 | 75 | SearchUnitData( const Model& model ) 76 | : number_variables ( static_cast( model.variables.size() ) ), 77 | number_constraints ( static_cast( model.constraints.size() ) ), 78 | is_optimization ( model.objective->is_optimization() ), 79 | matrix_var_ctr ( number_variables ), 80 | tabu_list ( std::vector( number_variables, 0 ) ), 81 | error_variables ( std::vector( number_variables, 0.0 ) ), 82 | best_sat_error ( std::numeric_limits::max() ), 83 | best_opt_cost ( std::numeric_limits::max() ), 84 | current_sat_error ( std::numeric_limits::max() ), 85 | current_opt_cost ( std::numeric_limits::max() ), 86 | restarts ( 0 ), 87 | resets ( 0 ), 88 | local_moves ( 0 ), 89 | search_iterations ( 0 ), 90 | local_minimum ( 0 ), 91 | plateau_moves ( 0 ), 92 | plateau_force_trying_another_variable ( 0 ) 93 | { } 94 | 95 | void initialize_matrix( const Model& model ) 96 | { 97 | // Save the id of each constraint where the current variable appears in. 98 | for( int variable_id = 0; variable_id < number_variables; ++variable_id ) 99 | for( int constraint_id = 0; constraint_id < number_constraints; ++constraint_id ) 100 | if( model.constraints[ constraint_id ]->has_variable( variable_id ) ) 101 | matrix_var_ctr[ variable_id ].push_back( constraint_id ); 102 | } 103 | }; 104 | } 105 | -------------------------------------------------------------------------------- /src/global_constraints/all_different.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | #include 33 | 34 | #include "global_constraints/all_different.hpp" 35 | 36 | using ghost::global_constraints::AllDifferent; 37 | 38 | double AllDifferent::binomial_with_2( int value ) const 39 | { 40 | if( value <= 1 ) 41 | return 0; 42 | 43 | if( value % 2 == 0 ) 44 | return static_cast( value - 1 ) * ( value / 2 ); 45 | else 46 | return static_cast( value ) * ( ( value - 1 ) / 2 ); 47 | } 48 | 49 | 50 | AllDifferent::AllDifferent( const std::vector& variables_index ) 51 | : Constraint( variables_index ) 52 | { } 53 | 54 | AllDifferent::AllDifferent( const std::vector& variables ) 55 | : Constraint( variables ) 56 | { } 57 | 58 | // SOFT_ALLDIFF error function (Petit et al. 2001) 59 | double AllDifferent::required_error( const std::vector& variables ) const 60 | { 61 | double counter = 0; 62 | _count.clear(); 63 | 64 | for( auto v : variables ) 65 | if( _count.find( v->get_value() ) == _count.end() ) 66 | _count[ v->get_value() ] = 1; 67 | else 68 | _count[ v->get_value() ] = _count[ v->get_value() ] + 1; 69 | 70 | for( const auto& [key, value] : _count ) 71 | if( value > 1 ) 72 | counter += binomial_with_2( value ); 73 | 74 | return counter; 75 | } 76 | 77 | double AllDifferent::optional_delta_error( const std::vector& variables, const std::vector& variable_indexes, const std::vector& candidate_values ) const 78 | { 79 | double diff = 0.0; 80 | auto copy_count( _count ); 81 | 82 | for( int i = 0 ; i < static_cast( variable_indexes.size() ) ; ++i ) 83 | { 84 | copy_count[ variables[ variable_indexes[ i ] ]->get_value() ] = copy_count[ variables[ variable_indexes[ i ] ]->get_value() ] - 1; 85 | if( copy_count.count( candidate_values[ i ] ) == 0 ) 86 | copy_count[ candidate_values[ i ] ] = 1; 87 | else 88 | copy_count[ candidate_values[ i ] ] = copy_count[ candidate_values[ i ] ] + 1; 89 | } 90 | 91 | for( int i = 0 ; i < static_cast( variable_indexes.size() ) ; ++i ) 92 | { 93 | if( _count[ variables[ variable_indexes[ i ] ]->get_value() ] != copy_count[ variables[ variable_indexes[ i ] ]->get_value() ] ) 94 | diff += ( binomial_with_2( copy_count[ variables[ variable_indexes[ i ] ]->get_value() ] ) - binomial_with_2( _count[ variables[ variable_indexes[ i ] ]->get_value() ] ) ); 95 | if( _count[ candidate_values[ i ] ] != copy_count[ candidate_values[ i ] ] ) 96 | diff += ( binomial_with_2( copy_count[ candidate_values[ i ] ] ) - binomial_with_2( _count[ candidate_values[ i ] ] ) ); 97 | } 98 | 99 | return diff; 100 | } 101 | 102 | void AllDifferent::conditional_update_data_structures( const std::vector& variables, int variable_index, int new_value ) 103 | { 104 | _count[ variables[ variable_index ]->get_value() ] = _count[ variables[ variable_index ]->get_value() ] - 1; 105 | 106 | if( _count.count( new_value ) == 0 ) 107 | _count[ new_value ] = 1; 108 | else 109 | _count[ new_value ] = _count[ new_value ] + 1; 110 | } 111 | -------------------------------------------------------------------------------- /src/objective.cpp: -------------------------------------------------------------------------------- 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 | #include "objective.hpp" 31 | 32 | using ghost::Objective; 33 | 34 | Objective::Objective( const std::vector& variables_index, bool is_maximization, const std::string& name ) 35 | : _variables_index( variables_index ), 36 | _is_optimization( true ), 37 | _is_maximization( is_maximization ), 38 | _name( name ) 39 | { } 40 | 41 | Objective::Objective( const std::vector& variables, bool is_maximization, const std::string& name ) 42 | : _variables_index( std::vector( variables.size() ) ), 43 | _is_optimization( true ), 44 | _is_maximization( is_maximization ), 45 | _name( name ) 46 | { 47 | std::transform( variables.begin(), 48 | variables.end(), 49 | _variables_index.begin(), 50 | [&](const auto& v){ return v.get_id(); } ); 51 | } 52 | 53 | double Objective::cost() const 54 | { 55 | double value = required_cost( _variables ); 56 | 57 | if( std::isnan( value ) ) 58 | throw nanException( _variables ); 59 | 60 | if( _is_maximization ) 61 | value = -value; 62 | 63 | return value; 64 | } 65 | 66 | void Objective::conditional_update_data_structures( const std::vector& variables, int index, int new_value ) 67 | { } 68 | 69 | int Objective::expert_heuristic_value( const std::vector& variables, 70 | int variable_index, 71 | const std::vector& possible_values, 72 | randutils::mt19937_rng& rng ) const 73 | { 74 | double min_cost = std::numeric_limits::max(); 75 | double simulated_cost; 76 | 77 | auto var = variables[ variable_index ]; 78 | int backup = var->get_value(); 79 | std::vector best_values; 80 | 81 | for( auto v : possible_values ) 82 | { 83 | var->set_value( v ); 84 | simulated_cost = required_cost( variables ); 85 | 86 | if( _is_maximization ) 87 | simulated_cost = -simulated_cost; 88 | 89 | if( min_cost > simulated_cost ) 90 | { 91 | min_cost = simulated_cost; 92 | best_values.clear(); 93 | best_values.push_back( v ); 94 | } 95 | else 96 | if( min_cost == simulated_cost ) 97 | best_values.push_back( v ); 98 | } 99 | 100 | var->set_value( backup ); 101 | 102 | if( !best_values.empty() ) 103 | return rng.pick( best_values ); 104 | else 105 | if( !possible_values.empty() ) 106 | return rng.pick( possible_values ); 107 | else 108 | return backup; 109 | } 110 | 111 | int Objective::expert_heuristic_value_permutation( const std::vector& variables, 112 | int variable_index, 113 | const std::vector& bad_variables, 114 | randutils::mt19937_rng& rng ) const 115 | { 116 | return rng.pick( bad_variables ); 117 | } 118 | 119 | double Objective::expert_postprocess( const std::vector& variables, 120 | double best_cost ) const 121 | { 122 | return best_cost; 123 | } 124 | -------------------------------------------------------------------------------- /src/options.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | 32 | #include "options.hpp" 33 | 34 | using ghost::Options; 35 | 36 | Options::Options() 37 | : custom_starting_point( false ), 38 | resume_search( false ), 39 | parallel_runs( false ), 40 | enable_optimization_guidance( true ), 41 | number_threads( std::max( 2, static_cast( std::thread::hardware_concurrency() ) / 2 ) ), // std::thread::hardware_concurrency() returns 0 if it is not able to detect the number of threads 42 | print( std::make_shared() ), 43 | tabu_time_local_min( -1 ), 44 | tabu_time_selected( -1 ), 45 | percent_chance_force_trying_on_plateau( -1 ), 46 | reset_threshold( -1 ), 47 | restart_threshold( -1 ), 48 | number_variables_to_reset( -1 ), 49 | number_start_samplings( -1 ) 50 | { } 51 | 52 | Options::Options( const Options& other ) 53 | : custom_starting_point( other.custom_starting_point ), 54 | resume_search( other.resume_search ), 55 | parallel_runs( other.parallel_runs ), 56 | enable_optimization_guidance( other.enable_optimization_guidance ), 57 | number_threads( other.number_threads ), 58 | print( other.print ), 59 | tabu_time_local_min( other.tabu_time_local_min ), 60 | tabu_time_selected( other.tabu_time_selected ), 61 | percent_chance_force_trying_on_plateau( other.percent_chance_force_trying_on_plateau ), 62 | reset_threshold( other.reset_threshold ), 63 | restart_threshold( other.restart_threshold ), 64 | number_variables_to_reset( other.number_variables_to_reset ), 65 | number_start_samplings( other.number_start_samplings ) 66 | { } 67 | 68 | Options::Options( Options&& other ) 69 | : custom_starting_point( other.custom_starting_point ), 70 | resume_search( other.resume_search ), 71 | parallel_runs( other.parallel_runs ), 72 | enable_optimization_guidance( other.enable_optimization_guidance ), 73 | number_threads( other.number_threads ), 74 | print( std::move( other.print ) ), 75 | tabu_time_local_min( other.tabu_time_local_min ), 76 | tabu_time_selected( other.tabu_time_selected ), 77 | percent_chance_force_trying_on_plateau( other.percent_chance_force_trying_on_plateau ), 78 | reset_threshold( other.reset_threshold ), 79 | restart_threshold( other.restart_threshold ), 80 | number_variables_to_reset( other.number_variables_to_reset ), 81 | number_start_samplings( other.number_start_samplings ) 82 | { } 83 | 84 | Options& Options::operator=( Options other ) 85 | { 86 | if( this != &other ) 87 | { 88 | custom_starting_point = other.custom_starting_point; 89 | resume_search = other.resume_search; 90 | parallel_runs = other.parallel_runs; 91 | enable_optimization_guidance = other.enable_optimization_guidance; 92 | number_threads = other.number_threads; 93 | std::swap( print, other.print ); 94 | tabu_time_local_min = other.tabu_time_local_min; 95 | tabu_time_selected = other.tabu_time_selected; 96 | percent_chance_force_trying_on_plateau = other.percent_chance_force_trying_on_plateau; 97 | reset_threshold = other.reset_threshold; 98 | restart_threshold = other.restart_threshold; 99 | number_variables_to_reset = other.number_variables_to_reset; 100 | number_start_samplings = other.number_start_samplings; 101 | } 102 | 103 | return *this; 104 | } 105 | -------------------------------------------------------------------------------- /src/model_builder.cpp: -------------------------------------------------------------------------------- 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 | #include "model_builder.hpp" 31 | 32 | using ghost::ModelBuilder; 33 | using ghost::Model; 34 | 35 | ModelBuilder::ModelBuilder( bool permutation_problem ) 36 | : permutation_problem( permutation_problem ) 37 | { } 38 | 39 | Model ModelBuilder::build_model() 40 | { 41 | variables.clear(); 42 | constraints.clear(); 43 | 44 | declare_variables(); 45 | // Set the id of each variable object to be their index in the _variables vector 46 | for( int variable_id = 0 ; variable_id < static_cast( variables.size() ) ; ++variable_id ) 47 | { 48 | variables[ variable_id ]._id = variable_id; 49 | if( variables[ variable_id ]._name.empty() ) 50 | variables[ variable_id ]._name = "v" + std::to_string( variable_id ); 51 | } 52 | 53 | // Auxiliary data may be needed by the constraints and the objective function, 54 | // so it must be defined before them. 55 | declare_auxiliary_data(); 56 | declare_constraints(); 57 | declare_objective(); 58 | 59 | if( constraints.empty() ) 60 | constraints.emplace_back( std::make_shared( variables ) ); 61 | 62 | // Internal data structure initialization 63 | // Set the id of each constraint object to be their index in the _constraints vector 64 | for( int constraint_id = 0 ; constraint_id < static_cast( constraints.size() ) ; ++constraint_id ) 65 | { 66 | constraints[ constraint_id ]->_id = constraint_id; 67 | // Set also constraints' variables and their internal data structures 68 | for( int index = 0 ; index < static_cast( constraints[ constraint_id ]->_variables_index.size() ) ; ++index ) 69 | { 70 | constraints[ constraint_id ]->_variables.push_back( &variables[ constraints[ constraint_id ]->_variables_index[ index ] ] ); 71 | constraints[ constraint_id ]->_variables_position[ constraints[ constraint_id ]->_variables_index[ index ] ] = index; 72 | } 73 | } 74 | 75 | // Set auxiliary data's variables and its internal data structures 76 | for( int index = 0 ; index < static_cast( auxiliary_data->_variables_index.size() ) ; ++index ) 77 | { 78 | auxiliary_data->_variables.push_back( &variables[ auxiliary_data->_variables_index[ index ] ] ); 79 | auxiliary_data->_variables_position[ auxiliary_data->_variables_index[ index ] ] = index; 80 | } 81 | 82 | // Set objective function's variables and its internal data structures 83 | for( int index = 0 ; index < static_cast( objective->_variables_index.size() ) ; ++index ) 84 | { 85 | objective->_variables.push_back( &variables[ objective->_variables_index[ index ] ] ); 86 | objective->_variables_position[ objective->_variables_index[ index ] ] = index; 87 | } 88 | 89 | return Model( std::move( variables ), constraints, objective, auxiliary_data, permutation_problem ); 90 | } 91 | 92 | void ModelBuilder::create_n_variables( int number, const std::vector& domain, int index ) 93 | { 94 | for( int i = 0 ; i < number ; ++i ) 95 | variables.emplace_back( domain, index ); 96 | } 97 | 98 | void ModelBuilder::create_n_variables( int number, int starting_value, std::size_t size, int index ) 99 | { 100 | for( int i = 0 ; i < number ; ++i ) 101 | variables.emplace_back( starting_value, size, index ); 102 | } 103 | 104 | void ModelBuilder::declare_constraints() 105 | { } 106 | 107 | void ModelBuilder::declare_objective() 108 | { 109 | objective = std::make_shared(); 110 | } 111 | 112 | void ModelBuilder::declare_auxiliary_data() 113 | { 114 | auxiliary_data = std::make_shared(); 115 | } 116 | -------------------------------------------------------------------------------- /src/variable.cpp: -------------------------------------------------------------------------------- 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 | #include 31 | #include 32 | 33 | #include "variable.hpp" 34 | 35 | using ghost::Variable; 36 | 37 | Variable::Variable( const std::vector& domain, int index, const std::string& name ) 38 | : _domain( domain ), 39 | _id( 0 ), 40 | _name( name ), 41 | _current_value( domain.at( index ) ), 42 | _min_value( *( std::min_element( _domain.begin(), _domain.end() ) ) ), 43 | _max_value( *( std::max_element( _domain.begin(), _domain.end() ) ) ) 44 | { } 45 | 46 | Variable::Variable( int starting_value, std::size_t size, int index, const std::string& name ) 47 | : _domain( std::vector( size ) ), 48 | _id( 0 ), 49 | _name( name ), 50 | _min_value( starting_value ), 51 | _max_value( starting_value + static_cast( size ) - 1 ) 52 | { 53 | std::iota( _domain.begin(), _domain.end(), starting_value ); 54 | _current_value = _domain.at( index ); 55 | } 56 | 57 | Variable::Variable( const std::vector& domain, 58 | const std::string& name ) 59 | : Variable( domain, 0, name ) 60 | { } 61 | 62 | Variable::Variable( int starting_value, 63 | std::size_t size, 64 | const std::string& name ) 65 | : Variable( starting_value, size, 0, name ) 66 | { } 67 | 68 | std::vector Variable::get_partial_domain( int range ) const 69 | { 70 | if( range >= static_cast( _domain.size() ) ) 71 | return _domain; 72 | else 73 | if( range <= 0 ) 74 | return std::vector{}; 75 | else 76 | { 77 | std::vector partial_domain( range ); 78 | 79 | // [---xxxIxxx-] 80 | // | 81 | // ^ 82 | // index 83 | int index = std::distance( _domain.cbegin(), std::find( _domain.cbegin(), _domain.cend(), _current_value ) ); 84 | int start_position = index - static_cast( range / 2 ); 85 | 86 | if( start_position >= 0 ) 87 | { 88 | // [---xxxIxxx-] 89 | // | 90 | // ^ 91 | // start_position 92 | if( index + ( range - static_cast( range / 2 ) ) <= static_cast( _domain.size() ) ) 93 | { 94 | std::copy( _domain.begin() + start_position, 95 | _domain.begin() + start_position + range, 96 | partial_domain.begin() ); 97 | } 98 | // [xx----xxxIx] 99 | // | 100 | // ^ 101 | // end_position 102 | else 103 | { 104 | int end_position = index + ( range - static_cast( range / 2 ) ) - static_cast( _domain.size() ); 105 | std::copy( _domain.begin(), 106 | _domain.begin() + end_position, 107 | partial_domain.begin() ); 108 | 109 | std::copy( _domain.begin() + start_position, 110 | _domain.end(), 111 | partial_domain.begin() + end_position ); 112 | } 113 | } 114 | // [xIxxx----xx] 115 | // | | 116 | // | ^ 117 | // | start_position 118 | // ^ 119 | // end_position 120 | else 121 | { 122 | int end_position = index + ( range - static_cast( range / 2 ) ); 123 | // Remember: start_position is negative here 124 | start_position += static_cast( _domain.size() ); 125 | std::copy( _domain.begin(), 126 | _domain.begin() + end_position, 127 | partial_domain.begin() ); 128 | 129 | std::copy( _domain.begin() + start_position, 130 | _domain.end(), 131 | partial_domain.begin() + end_position ); 132 | } 133 | 134 | return partial_domain; 135 | } 136 | } 137 | --------------------------------------------------------------------------------